微信/支付宝支付服务搭建,一次性搞定!

微信支付

在这里插入图片描述

  1. 付款码支付
    付款码支付是指用户展示微信钱包内的“付款码”给商户系统扫描后直接完成支付,适用于线下场所面对面收银的场景,例如商超、便利店、餐饮、医院、学校、电影院和旅游景区等具有明确经营地址的实体场所
  2. JSAPI支付
    JSAPI支付是指商户通过调用微信支付提供的JSAPI接口,在支付场景中调起微信支付模块完成收款。

应用场景有:

线下场所:调用接口生成二维码,用户扫描二维码后在微信浏览器中打开页面后完成支付

公众号场景:用户在微信公众账号内进入商家公众号,打开某个主页面,完成支付

PC网站场景:在网站中展示二维码,用户扫描二维码后在微信浏览器中打开页面后完成支付

  1. 小程序支付
    小程序支付是指商户通过调用微信支付小程序支付接口,在微信小程序平台内实现支付功能;用户打开商家助手小程序下单,输入支付密码并完成支付后,返回商家小程序。
  2. Native支付
    Native支付是指商户系统按微信支付协议生成支付二维码,用户再用微信“扫一扫”完成支付的模式。该模式适用于PC网站、实体店单品或订单、媒体广告支付等场景。
  3. APP支付
    APP支付是指商户通过在移动端应用APP中集成开放SDK调起微信支付模块来完成支付。适用于在移动端APP中集成微信支付功能的场景。
  4. 刷脸支付
    刷脸支付是指用户在刷脸设备前通过摄像头刷脸、识别身份后进行的一种支付方式,安全便捷。适用于线下实体场所的收银场景,如商超、餐饮、便利店、医院、学校等。

支付流程

三个关键步骤是需要后台人员去实现的
在这里插入图片描述

核心依赖

<dependency><groupId>com.github.wechatpay-apiv3</groupId><artifactId>wechatpay-apache-httpclient</artifactId><version>0.4.9</version>
</dependency>

主要是用来向微信服务器发送http请求的客户端
在这里插入图片描述

API证书

拿营业执照申请API证书
在这里插入图片描述

下单请求

根据接口文档,通过httpClient发送请求
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

请求体:

{"mchid": "1900006XXX","out_trade_no": "native12177525012014070332333","appid": "wxdace645e0bc2cXXX","description": "Image形象店-深圳腾大-QQ公仔","notify_url": "https://weixin.qq.com/","amount": {"total": 1,"currency": "CNY"}
}

响应体

{"code_url": "weixin://wxpay/bizpayurl?pr=p4lpSuKzz"
}

请求体参数可以封装成对应的对象

/**
* 订单请求体
* */
@Data
@Builder
public class NativePayParams {/*** 应用id* */private String appid;/*** 商户id* */private String mchid;/*** 商品描述* */private String description;/*** 订单号* */private String out_trade_no;/*** 回调通知地址* */private String notify_url;/*** 订单金额* */private Amount amount;}
/**
* 金额对象
* */
@Data
@Builder
public class Amount {/*** 总金额* */private Integer total;/*** 货币单位* */private String currency;}
public class PayService {private CloseableHttpClient httpClient;/*** 必备的校验参数:需要拿营业执照向腾讯申请* *//*** 商户API私钥* */private String privateKey="";private String mchId="";/*** 证书序列号* */private String mchSerialNo="";/*** API v3密钥* */private String apiV3Key="";public static void main(String[] args) {try {PayService payService = new PayService();payService.setup();payService.CreateOrder();payService.after();} catch (Exception e) {throw new RuntimeException(e);}}/*** 初始化* */public void setup() throws IOException {// 加载商户私钥(privateKey:私钥字符串)PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));// 加载平台证书(mchId:商户号,mchSerialNo:商户证书序列号,apiV3Key:V3密钥)AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)),apiV3Key.getBytes("utf-8"));// 初始化httpClienthttpClient = WechatPayHttpClientBuilder.create().withMerchant(mchId, mchSerialNo, merchantPrivateKey).withValidator(new WechatPay2Validator(verifier)).build();}/*** 创建并发送订单* */public void CreateOrder() throws Exception{HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/native");// 封装请求体String reqdata = "json字符串";StringEntity entity = new StringEntity(reqdata,"utf-8");entity.setContentType("application/json");httpPost.setEntity(entity);httpPost.setHeader("Accept", "application/json");//发送http请求CloseableHttpResponse response = httpClient.execute(httpPost);try {int statusCode = response.getStatusLine().getStatusCode();if (statusCode == 200) { //处理成功System.out.println("success,return body = " + EntityUtils.toString(response.getEntity()));} else if (statusCode == 204) { //处理成功,无返回BodySystem.out.println("success");} else {System.out.println("failed,resp code = " + statusCode+ ",return body = " + EntityUtils.toString(response.getEntity()));throw new IOException("request failed");}} finally {response.close();}}/*** 关闭连接* */public void after() throws IOException {httpClient.close();}}

支付结果

微信官方会异步通知商户支付结果,商户也可以自行查询支付结果

异步通知

在发送下单请求时,需要指定notify_url,这是一个接口地址,微信会访问这个接口,并通过http传递支付结果
写一个接口来接收通知就行了
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
接口要接收的请求体

{"id": "EV-2018022511223320873","create_time": "2015-05-20T13:29:35+08:00","resource_type": "encrypt-resource","event_type": "TRANSACTION.SUCCESS","summary": "支付成功","resource": {"original_type": "transaction","algorithm": "AEAD_AES_256_GCM","ciphertext": "","associated_data": "","nonce": ""}
}
/**
* 回调通知
* */
@Data
public class NotifyDTO {/*** 通知的唯一ID* */private String id;/*** 通知创建的时间* */private String create_time;/*** 通知的类型* */private String event_type;/*** 通知的资源数据类型* */private String resource_type;/*** 回调摘要* */private String summary;/*** 通知资源数据* */private ResourceDTO resourceDTO;
}
/**
* 资源
* */
@Data
public class ResourceDTO {/*** 对开启结果数据进行加密的加密算法* */private String algorithm;/*** Base64编码后的开启/停用结果数据密文* */private String ciphertext;/*** 附加数据* */private String associated_data;/*** 原始回调类型,为transaction* */private String original_type;/*** 加密使用的随机串* */private String nonce;
}

接口返回结果

/**
* 接收失败时,需要返回一个对象给微信
* */
@Data
public class ErrorDTO {/*** 错误码,SUCCESS为清算机构接收成功,其他错误码为失败* */private String code;/*** 返回信息,如非空,为错误原因* */private String message;}

在这里插入图片描述

接口设计

/*** 与微信的交互*/
@RestController
@RequestMapping("/pay")
public class PayController {@ResourceNativePayService nativePayService;@PostMapping("/notify")public ErrorDTO getNotify(@RequestBody NotifyDTO notifyDTO) {nativePayService.payNotify(notifyDTO);return new ErrorDTO();}}

在这里插入图片描述

解密Resource

解密微信发来的Resource部分,可以拿到订单对应的编号,从而根据该编号完成支付流程
在这里插入图片描述
AES-256-GCM是一种对称密钥加密,也就是说,加密解密,只考虑apiV3Key密钥即可

/**
* 处理支付业务
* */
@Service
public class NativeServiceImpl implements NativePayService{/*** 对称密钥* */private static final String apiV3Key="";/*** 订单号* */public static String tradeNo;@Overridepublic ErrorDTO payNotify(NotifyDTO notifyDTO) {try {AesUtil aesUtil = new AesUtil(apiV3Key.getBytes());ResourceDTO resourceDTO = notifyDTO.getResourceDTO();String json = aesUtil.decryptToString(resourceDTO.getAssociated_data().getBytes(),resourceDTO.getNonce().getBytes(),resourceDTO.getCiphertext());Map map = JSONUtil.parseObj(json);tradeNo = map.get("out_trade_no").toString();} catch (GeneralSecurityException e) {throw new RuntimeException(e);}return null;}
}

主动查询订单

后台需要不断轮询,向微信查询订单支付的结果,直到获得成功的结果
使用定时任务即可
在这里插入图片描述
请求体
在这里插入图片描述
响应体

{"appid" : "wxd678efh567hg6787","mchid" : "1230000109","out_trade_no" : "1217752501201407033233368018","transaction_id" : "1217752501201407033233368018","trade_type" : "MICROPAY","trade_state" : "SUCCESS","trade_state_desc" : "支付失败,请重新下单支付","bank_type" : "CMC","attach" : "自定义数据","success_time" : "2018-06-08T10:34:56+08:00","payer" : {"openid" : "oUpF8uMuAJO_M2pxb1Q9zNjWeS6o\t"},"amount" : {"total" : 100,"payer_total" : 100,"currency" : "CNY","payer_currency" : "CNY"},"scene_info" : {"device_id" : "013467007045764"},"promotion_detail" : [{"coupon_id" : "109519","name" : "单品惠-6","scope" : "GLOBAL","type" : "CASH","amount" : 100,"stock_id" : "931386","wechatpay_contribute" : 0,"merchant_contribute" : 0,"other_contribute" : 0,"currency" : "CNY","goods_detail" : [{"goods_id" : "M1006","quantity" : 1,"unit_price" : 100,"discount_amount" : 1,"goods_remark" : "商品备注信息"}]}]
}

支付宝

在这里插入图片描述

沙箱环境

访问支付宝接口需要的验证信息在这里获取
如果是生产环境则需要拿营业执照向官方申请密钥和证书
在这里插入图片描述

加密原理

非对称加密:

  • 通信双方分别创建公钥和私钥,
  • 并且保证公钥所加密的信息,只有配对的私钥可以解密,
  • 接下来,双方公开交换公钥,通信时,使用对方的公钥进行加密,
  • 如此,就能确保对方能够通过自己的私钥解密
    显然,这种做法并不安全,第三方可以直接拦截一方发送的公钥,将其调包成自己的公钥,这样一来,另一方使用该公钥加密的所有信息,都能被第三方轻易解密

二维码信息载体

一维码只有宽度表示信息,二维码长度和宽度都能储存信息
二维码生成过程:

  • 数据经过编码之后得到一个二进制串
  • 数据串将和纠错码交织在一起
  • 依据相应版本二维码的规范,利用不同尺寸的方块填充得到二维码

对接支付宝

依赖:

<!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-easysdk -->
<dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-easysdk</artifactId><version>2.2.3</version>
</dependency>

配置文件

server:port: 15100
pay:alipay:protocol: httpsgatewayHost: openapi-sandbox.dl.alipaydev.comsignType: RSA2appId: #应用IdmerchantPrivateKey: #应用私钥alipayPublicKey: #支付宝公钥notifyUrl:  #支付宝发送通知地址

这里的notifyUrl指的是公网的url,如果想要本机接收,需要先进行内网穿透
内网穿透:
教程参考:内网穿透教程
工具:cpolar
命令:
cpolar authtoken <令牌> #将authtoken保存到本机,
cpolar http <要暴露的端口号> #在这个端口上开一个通道连接到cpolar

@RestController
@RequestMapping("/alipay")
@Slf4j
public class AliPayController {@ResourceConfig config;@ResourceAliPayConfig aliPayConfig;@GetMapping("/code")public String pay() throws Exception {try {//1.添加配置项Factory.setOptions(config);//2.调用接口发送请求AlipayTradePrecreateResponse response = Factory.Payment.FaceToFace().preCreate(aliPayConfig.getSubject(),"123456","10");//3.解析响应结果String httpBody = response.getHttpBody();JSONObject jsonObject = JSONUtil.parseObj(httpBody);//3.2获取订单号String qrCode = jsonObject.getJSONObject("alipay_trade_precreate_response").get("qr_code").toString();log.info("返回二维码:{}", qrCode);QrCodeUtil.generate(qrCode,500,500,new File("D:/test2.jpg"));return qrCode;} catch (Exception e) {log.error("发生错误:{}", e.getClass().getName() + e.getMessage());e.printStackTrace();return "获取二维码失败,请稍后再试";}}@PostMapping("/notify")public String notify(HttpServletRequest request) {String outTradeNo = request.getParameter("out_trade_no");log.info("订单{}支付成功", outTradeNo);return "success";}@GetMapping("/query")public String queryOrder() {try {Factory.setOptions(config);AlipayTradeQueryResponse response = Factory.Payment.Common().query("123456");log.info("支付结果:{}", response);return response.getHttpBody();} catch (Exception e) {throw new RuntimeException(e);}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/832771.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024年第七届可再生能源与环境工程国际会议(REEE 2024)即将召开!

2024年第七届可再生能源与环境工程国际会议&#xff08;REEE 2024&#xff09;将于2024 年8月28-30日在法国南特举行。共绘绿色未来&#xff0c;全球同频共振&#xff01;REEE 2024将汇聚全球可再生能源与环境工程领域的专家学者和业界精英&#xff0c;共同探讨行业发展的前沿技…

华南理工大胆突破,全国首个软物质科学与工程本科专业诞生!

不久前&#xff0c;教育部公布了2023年普通高等学校本科专业备案和审批结果&#xff0c;一个新名词吸引了我——软物质科学与工程。这是今年新增的24种新专业之一&#xff0c;而华南理工大学成为国内首个申请设置该专业的高校。这让我产生了强烈的好奇心&#xff1a;软物质是什…

【OpenVINO™】在 C# 中使用OpenVINO™ 部署 YOLO-World 模型实现实时开放词汇对象检测

YOLO-World是一个融合了实时目标检测与增强现实&#xff08;AR&#xff09;技术的创新平台&#xff0c;旨在将现实世界与数字世界无缝对接。该平台以YOLO&#xff08;You Only Look Once&#xff09;算法为核心&#xff0c;实现了对视频中物体的快速准确识别&#xff0c;并通过…

助贷客户管理系统:助力助贷公司轻松实现30%增长目标!

为了解决传统助贷公司在业务过程中遇到的痛点&#xff0c;盛鑫优创科技特别设计了一款定制化的解决方案——"鑫鹿助贷客户管理系统"&#xff0c;以满足助贷行业的独特需求&#xff1a; 传统助贷公司的老板们在做业务的的过程中都有这些痛点&#xff1a; 1、没有一个…

探索5个独特AI工具:它们是否值得独立存在?

在这个“地下AI”系列的最新一集中&#xff0c;我们深入挖掘了一些鲜为人知的AI工具。这些工具并非出自OpenAI、微软或谷歌等科技巨头之手&#xff0c;而是独立创造者和小型团队的智慧结晶。我们的目标是发现利用最新AI技术的独特工具。但这次有个新玩法&#xff1a;我们玩一个…

ABAP 数据写入Excel 并保存 千分位

参考老白 https://www.cnblogs.com/liaojunbo/archive/2011/09/06/2168552.html 但是缺zcl_excel 。需要从 dotabap要引入abap2xlsx 英文版进入后 尝试了一下 1&#xff09;列的宽度自适应么有找到在哪里&#xff1f; 列宽设置 lo_worksheet->set_column_width( ip_co…

生信技能45 - 基于docker容器运行生信软件

1. 获取docker镜像 以运行xhmm CNV分析软件为例。 # 搜索仓库镜像 sudo docker search xhmm# 拉取镜像 sudo docker pull ksarathbabu/xhmm_v1.0# 启动镜像,非后台 sudo docker run -it ksarathbabu/xhmm_v1.0 /bin/bash # -i: 交互式操作。 # -t: 终端。 # ksarathbabu/xhmm…

软件测试经理工作日常随记【2】-接口自动化

软件测试主管工作日常随记【2】-接口自动化 1.接口自动化 jmeter-反电诈项目 这个我做过的一个非常有意义的项目&#xff0c;和腾讯合作的&#xff0c;主要为用户拦截并提示所有可能涉及到的诈骗类型&#xff0c;并以裂变的形式扩展用户&#xff0c;这个项目前期后端先完成&…

VMware虚拟网卡网络适配器出现黄色感叹号

问题发生&#xff1a;VMware在使用Ubuntu的过程中突然卡死&#xff0c;强制关闭开启后就发生了网络无法连接 找到电脑的设备管理发现VMware的适配器出现黄色感叹号 解决方法&#xff1a; 下载软件ccleaner 扫描问题&#xff0c;懒得去找就修复了所有的问题 最后发现适配器…

连锁收银系统批量调整商品价格教程

1、进入系统后台&#xff0c;系统后台登录网址&#xff1a; 2、点击商品>商品调价 3、将按模板整理好的商品价格数据导入即可。 Tips&#xff1a;每次导入的商品数量不要超过6000 条。

python 12实验

1.导入数据。 2.清洗数据&#xff0c;将缺失值或“NAN”替换为“无”&#xff0c;并将文本数据转换为数值型数据。 3.使用聚类算法&#xff08;如KMeans&#xff09;对数据进行聚类&#xff0c;并计算样本到簇中心的平均距离以确定最佳的簇数量。 4.对数据进行PCA降维&#xff…

Python进阶之-jinja2详解

✨前言&#xff1a; &#x1f31f;什么是jinja2&#xff1f; Jinja2 是一个强大的 Python 模版引擎&#xff0c;主要用于生成HTML或其他文本文件。这个库非常适合开发动态网站和Web应用的视图层&#xff0c;因为它支持逻辑操作如循环和条件判断&#xff0c;还可以继承和重用模…

linux——主从同步

1. 保证主节点开始二进制日志&#xff0c;从节点配置中继日志 2. 从节点的开启一个 I/O 线程读取主节点二进制日志的内容 3. 从节点读取主节点的二进制日志之后&#xff0c;会将去读的内容写入从节点的中继日志 4. 从节点开启 SQL 线程&#xff0c;读取中继日志的内容&a…

图搜索算法 - 广度优先搜索法(BFS)

相关文章&#xff1a; 图搜索算法 - 深度优先搜索法&#xff08;DFS&#xff09; 广度优先搜索法&#xff08;BFS&#xff09; 2.从一个顶点出发&#xff0c;把它所有关联的顶点依次访问&#xff0c;然后到下一个顶点&#xff08;刚才访问的关联顶点&#xff09;。然后以这个顶…

Advanced RAG 06:生成结果的相关性低? 快用 Query Rewriting 优化技术

编者按&#xff1a;在现实生活中&#xff0c;普通用户很难编写合适的提示词&#xff08;prompt&#xff09;来指示 LLM 完成期望任务。用户提出的 queries 往往存在词汇不准确、缺乏语义信息等问题&#xff0c;导致 LLM 难以理解并生成相关的模型响应。因此&#xff0c;如何优化…

前端 | iframe框架标签应用(二)| 外部页面导入

文章目录 &#x1f4da;实现效果&#x1f4da;模块实现解析&#x1f407;html&#x1f407;css&#x1f407;javascript &#x1f4da;实现效果 点击右上角喇叭&#xff0c;弹出iframe页面框&#xff0c;链接bilibili白噪音视频页面&#xff1b;点击关闭按钮&#xff0c;关闭弹…

sqlmodel实现唯一性校验3,检查多列同时重复

之前的方案虽然能够解决重复性问题&#xff0c;但是没有覆盖到多列同时重复的情况。 比如&#xff0c;我们可以认为用户名是可以重复的。但是用户名和年龄不能同时重复&#xff0c;那么这种情况该怎么解决呢&#xff1f; 之前的代码如下&#xff1a; from sqlalchemy import…

数据集标签数量不均衡如何设计loss均衡数量

数据集标签数量不均衡如何设计loss均衡数量 1. 思路出发点&#xff1a; 对于哪些数量分布比值较少的标签提供更多的loss注意力比重&#xff0c;如何提高训练注意力比重&#xff0c;也就是说&#xff0c;让模型的梯度更多的倾向于有利于数据标签分布较少的数据训练&#xff0c…

【快捷部署】023_HBase(2.3.6)

&#x1f4e3;【快捷部署系列】023期信息 编号选型版本操作系统部署形式部署模式复检时间023HBase2.3.6Ubuntu 20.04tar包单机2024-05-07 注意&#xff1a;本脚本非全自动化脚本&#xff0c;有2次人工干预&#xff0c;第一次是确认内网IP&#xff0c;如正确直接回车即可&#…

了解TMS运输管理系统,实现物流高效运转

TMS运输管理系统&#xff08;Transportation Management System&#xff09;是一种集成物流和信息技术的解决方案&#xff0c;通过优化运输流程、实时跟踪货物信息和自动化管理操作&#xff0c;提高物流效率&#xff0c;降低运营成本&#xff0c;实现高效运输。 TMS运输管理系…