Java版微信支付
一、微信支付接入与介绍
1、微信支付产品介绍
付款码支付
用户展示微信钱包内的“付款码”给商家,商家扫描后直接完成支付,适用于线下面对面收银的场景。
JSAPI支付
- 线下场所:商户展示一个支付二维码,用户使用微信扫描二维码后,输入需要支付的金额,完成支 付。
- 公众号场景:用户在微信内进入商家公众号,打开某个页面,选择某个产品,完成支付。
- PC网站场景:在网站中展示二维码,用户使用微信扫描二维码,输入需要支付的金额,完成支付。
特点:用户在客户端输入支付金额
小程序支付
在微信小程序平台内实现支付的功能。
Native支付
Native支付是指商户展示支付二维码,用户再用微信“扫一扫”完成支付的模式。这种方式适用于PC网站。
特点:商家预先指定支付金额
APP支付
商户通过在移动端独立的APP应用程序中集成微信支付模块,完成支付。
刷脸支付
用户在刷脸设备前通过摄像头刷脸、识别身份后进行的一种支付方式。
2、接入指引
1、获取商户号
微信商户平台:https://pay.weixin.qq.com/ 场景:Native支付
步骤:提交资料 => 签署协议 => 获取商户号
2、获取APPID
微信公众平台:https://mp.weixin.qq.com/
步骤:注册服务号 => 服务号认证 => 获取APPID => 绑定商户号
3、获取API秘钥
APIv2版本的接口需要此秘钥
步骤:登录商户平台 => 选择 账户中心 => 安全中心 => API安全=>设置API密钥
4、获取APIv3秘钥
APIv3版本的接口需要此秘钥
步骤:登录商户平台 => 选择 账户中心 => 安全中心 =>API安全 => 设置APIv3密钥
5、申请商户API证书
商户API证书是指由商户申请的,包含商户的商户号、公司名称、公钥信息的证书。
APIv3版本的所有接口都需要;APIv2版本的高级接口需要(如:退款、企业红包、企业付款等)
步骤:登录商户平台 =>选择 账户中心 => 安全中心 => API安全 => 申请API证书
商户证书在商户后台申请:https://pay.weixin.qq.com/index.php/core/cert/api_cert#/
6、获取微信平台证书
微信支付平台证书是指由微信支付 负责申请的,包含微信支付平台标识、公钥信息的证书。商户可以使用平台证书中的公钥进行验签。
可以预先下载,也可以通过编程的方式获取。后面的课程中,我们会通过编程的方式来获取
平台证书的获取:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay3_0.shtml
注意:以上所有API秘钥和证书需妥善保管防止泄露
二、支付安全基础(证书/秘钥/签名)
1、安全基础
**明文:**加密前的消息叫“明文”(plain text)
**密文:**加密后的文本叫“密文”(cipher text)
**密钥:**只有掌握特殊“钥匙”的人,才能对加密的文本进行解密,这里的“钥匙”就叫做“密钥”(key)
“密钥”就是一个字符串,度量单位是“位”(bit),比如,密钥长度是 128,就是 16 字节的二进制串
**加密:**实现机密性最常用的手段是“加密”(encrypt)
按照密钥的使用方式,加密可以分为两大类:对称加密和非对称加密。
**解密:**使用密钥还原明文的过程叫“解密”(decrypt)
**加密算法:**加密解密的操作过程就是“加密算法”
所有的加密算法都是公开的,而算法使用的“密钥”则必须保密
2、对称加密和非对称加密
对称加密
- 特点:只使用一个密钥,密钥必须保密,常用的有AES算法
- 优点:运算速度快
- 缺点:秘钥需要信息交换的双方共享,一旦被窃取,消息会被破解,无法做到安全的密钥交换
非对称加密
- 特点:使用两个密钥:公钥和私钥,公钥可以任意分发而私钥保密,常用的有RSA
- 优点:黑客获取公钥无法破解密文,解决了密钥交换的问题
- 缺点:运算速度非常慢
混合加密
实际场景中把对称加密和非对称加密结合起来使用
身份认证
- 公钥加密,私钥解密的作用是加密信息
- 私钥加密,公钥解密的作用是身份认证
3、摘要算法
摘要算法就是我们常说的散列函数、哈希函数(Hash Function),它能够把任意长度的数据“压缩”成固定长度、而且独一无二的“摘要”字符串,就好像是给这段数据生成了一个数字“指纹”。
摘要算法的作用是保证信息的完整性
特性:
- 不可逆:只有算法,没有秘钥,只能加密,不能解密难题友好性:想要破解,只能暴力枚举
- 发散性:只要对原文进行一点点改动,摘要就会发生剧烈变化抗碰撞性:原文不同,计算后的摘要也要不同
常见摘要算法:
MD5、SHA1、SHA2(SHA224、SHA256、SHA384)
4、数字签名与证书
4.1 数字签名
数字签名是使用私钥对摘要加密生成签名,需要由公钥将签名解密后进行验证,实现身份认证和不可否认。但是黑客可以伪造公钥与客户进行通信
4.2 数字证书
数字证书解决“公钥的信任”问题,可以防止黑客伪造公钥。个人不能直接分发公钥,公钥的分发必须使用数字证书,数字证书由CA(证书颁发机构)颁发
4.3 https协议中的数字证书
三、基础支付API V3
1、支付配置准备
1.1 引入支付参数
注:这里使用了尚硅谷的资料
新建 wxpay.properties
文件并放置在resources文件夹下
1 | # 微信支付相关参数 |
新建 WxPayConfig.java
获取配置文件信息
1 |
|
最后为了让IDEA可以识别配置文件,将配置文件的图标展示成SpringBoot的图标,同时配置文件的内容可以高亮显示,让配置文件和Java代码之间的对应参数可以自动定位,方便开发,这里需要配置Annotation Processor
maven依赖,同时进入File -> Project Structure -> Modules -> 选择小叶子- > 选择+号- >选中配置文件
,即可配置成功
1 | <!-- 生成自定义配置的元数据信息 --> |
1.2 加载商户私钥
https://github.com/wechatpay-apiv3/wechatpay-apache-httpclient
引入微信SDK详情查看官网,搜索如何加载商户私钥,实现了请求签名的生成和应答签名的验证
1 | <dependency> |
1.3 获取签名验证器和HttpClient
流程如图所示,其余可查看Github官网,1.1中已经具体写明
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0Po2JQaN-1649921278437)(https://pay.weixin.qq.com/wiki/doc/apiv3/assets/img/common/ico-guide/chapter1_5_1.png “”)]
1.4 API字典和相关工具
https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_7_3.shtml
微信Native支付的API列表
同时微信支付 APIv3 使用 JSON 作为消息体的数据交换格式,因此需要引入json转换依赖
1 | <!--json处理--> |
最后将Native支付接口写成枚举类,方便调用,以及HttpUtil工具类
1 | //举例 |
1 | public class HttpUtils { |
1.5 设置全局返回类
1 | // 全局返回 |
2、签名和验签解析
2.1 签名
https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_0.shtml
2.2 验签
https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_1.shtml
3、Native支付
3.1 Native支付流程
https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_4.shtml
3.2 Native下单Api
https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_1.shtml
https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_7_2.shtml
商户端发起支付请求,微信端创建支付订单并生成支付二维码链接,微信端将支付二维码返回给商户 端,商户端显示支付二维码,用户使用微信客户端扫码后发起支付
1 | /** |
使用微信SDK自带的验签和签名函数,进行订单创建,同时为了减轻服务器压力,需要缓存二维码,同时定时检查二维吗url是否已经过期,并同步到数据库
3.3 支付通知API
https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_5.shtml
微信支付通过支付通知接口将用户支付成功消息通知给商户
- 内网穿透
这里使用了ngrok作为内网穿透工具,原因是微信支付回调函数需要通知地址,而我们的程序一般都部署在内网;同时针对微信的回调函数,需要考虑失败、超时等情况,否则微信会持续发送回调通知,直到成功返回 - 验签工具
参考SDK源码中的 WechatPay2Validator 创建通知验签工具类 WechatPay2ValidatorForRequest - 解密工具
验签成功的签名串经过对称加密,需要进行api-v3-key
秘钥进行解密,证书和回调解密的AesGcm解密参考AesUtil.java
- 处理订单
获取微信支付回调函数后,需要更新订单状态以及插入支付记录,同时使用可重入锁来处理并发、重复请求,保证订单记录的唯一性与可靠性
4、微信支付查单API
https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_2.shtml
查单接口是为了确定用户已经完成支付但却未回调到系统的情况,需要增加定时任务,定时查找超时订单与处理超时订单等
1 | 4j |
5、微信支付退款API
退款回调和通知回调类似
6、微信支付账单下载
https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_4_8.shtml
前端Vue下载函数
1 | //下载账单 |
7、基础支付APIv2
四、支付宝支付介绍与环境准备
1、接入介绍
支付宝开发者开发平台:https://open.alipay.com/
1.1 常规接入流程
例如网页&移动应用:https://opendocs.alipay.com/open/200
- 创建应⽤:选择应⽤类型、填写应⽤基本信息、添加应⽤功能、配置应⽤环境(获取⽀付宝公钥、应⽤公钥、应⽤私钥、⽀付宝⽹关地址,配置接⼝内容加密⽅式)、查看 APPID
- 绑定应⽤:将开发者账号中的APPID和商家账号PID进⾏绑定
- 配置秘钥:即创建应⽤中的“配置应⽤环境”步骤
- 上线应⽤:将应⽤提交审核
- 签约功能:在商家中⼼上传营业执照、已备案⽹站信息等,提交审核进⾏签约
1.2 使用沙箱
- 沙箱环境配置:https://opendocs.alipay.com/common/02kkv7
- 沙箱版支付宝下载与登录:https://open.alipay.com/platform/appDaily.htm?tab=tool
2、支付参数引入
2.1 引入配置文件
创建alipay.properties
文件,里面存放支付宝相关参数,这里使用了尚硅谷的真实支付宝参数,沙箱版自行替换参数
1 | # 支付宝支付相关参数 |
2.2 创建配置文件
在config包创建AlipayClientConfig,这里使用Environment 获取参数,和上面微信支付获取参数方法不同
1 |
|
3、引入服务端SDK
3.1 引入依赖
参考⽂档:开放平台 => ⽂档 => 开发⼯具 => 服务端SDK => Java => 通⽤版 => Maven项⽬依赖https://search.maven.org/artifact/com.alipay.sdk/alipay-sdk-java
1 | <dependency> |
3.2 创建客户端连接对象
参考⽂档:开放平台 => ⽂档 => 开发⼯具 => 技术接⼊指南 => 数据签名
https://opendocs.alipay.com/common/02kf5q
参考⽂档中 公钥方式 完善 AlipayClientConfig
类,添加 alipayClient()
⽅法 初始化 AlipayClient
对象
1 |
|
五、支付宝支付功能开发
1、统一收单下单与支付
1.1 支付调用流程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mWwD20cH-1653225486947)(https://secure2.wostatic.cn/static/uxiuZngjTEt6V1s3cK7vcG/image.png)]
1.2 接口说明
- 公共请求参数:所有接⼝都需要的参数
- 请求参数:当前接⼝需要的参数
- 公共响应参数:所有接⼝的响应中都包含的数据
- 响应参数:当前接⼝的响应中包含的数据
1.3 发起支付请求
后端核心
1 |
|
前端核心
1 | //确认支付 |
前端API方法
1 | import request from '@/utils/request' |
2、支付结果通知
2.1 环境配置
在 AliPayServiceImpl
的 tradeCreate
⽅法中设置异步通知地址。同时启动ngrok内网穿透,上面微信支付已经说明,注意要修改成自己的配置
2.2 开发异步通知接口
AliPayController
1 | "支付通知") ( |
AliPayService
1 | /** |
3、统一收单交易关闭
1 | /** |
注意:针对⼆维码⽀付,只有经过扫码的订单才在⽀付宝端有交易记录。针对⽀付宝账号⽀付,只有经过登录的订单才在⽀付宝端有交易记录。
4、统一收单交易查询
4.1 查单接口调用
商户后台未收到异步⽀付结果通知时,商户应该主动调⽤《统⼀收单线下交易查询接⼝》,同步订单状态。
1 | /** |
4.2 定时查单
创建定时任务
1 | 4j |
4.3 处理查询到的订单
1 | /** |
5、统一交易退款
1 | /** |
6、收单退款冲退完成通知
退款存在退到银⾏卡场景下时,收单会根据银⾏回执消息发送退款完成信息。开发流程类似⽀付结果通知。
7、对账
查询对账单下载地址接⼝
1 | /** |
参考文章