调用第三方平台(支付宝)支付总结
趁着刚把支付宝功能完工,这里我来总结一下。
# 一。老版:mapi 网关产品密钥 demo
# payment 支付表
名称 | 类型 | 描述 |
---|---|---|
user_id | integer | 用户 ID |
payment_no | string | 支付单号(支付的时候生成一个唯一的支付单号) |
transaction_no | string | 流水号(支付宝返回的唯一流水号) |
status | string | 支付状态('sucess’成功,'fail’失败,default:'initial’未支付) |
total_money | decimal | 支付总金额 |
payment_at | datetime | 付款时间 |
raw_response | text | 支付宝返回的原始数据结果集 |
# 订单表增加以下字段
名称 | 类型 | 描述 |
---|---|---|
payment_id | integer | 对应的支付记录 id |
status | string | 订单状态(是否是付款成功,default:'initial’未支付) |
# 官方文档强制要求提交到支付宝的请求参数
1 | pay_options = { |
## 二: 新版:开放平台密钥
老版的时候写的 demo 是进行 md5 进行加密,比较简单,在新版中,需要采用 RSA 密钥。
支付宝需求和原理:
- 1. 需求:移动端 app 需要在原先支持微信支付的基础上外增加支付宝支付。
- 支付宝支付原理:
1. 移动端 sdk 携带支付宝请求参数去请求支付宝,支付宝接受参数后,用配置的公钥和我们请求的私钥进行比对
2. 比对成功之后,给我们响应参数。我们在获取支付宝响应参数之后,通过走回调方法来把支付宝响应的信息进行验签比对,比对成功之后来更新我们的数据库。
备注:
移动端支付我们采用的是异步,通过 notify_url 来回调。pc 端一般是同步,直接获取到响应参数。
RSA 密钥验签流程:
支付宝会要求我们自己生成 RSA 的公钥和私钥,然后开发平台支付宝也会生成的一对这样的密钥,我们自己生成的和支付宝生成的需要交换彼此的公钥,我们利用自己生成的密钥对数据进行加密,然后拿到支付平台生成的公钥,再对彼此的私钥进行验证。
实现步骤:
- 下载本地私钥,本地生成工具生成私钥
- 把自己的生成的商户公钥在支付宝配置项中进行配置
- 构造支付宝需要的请求参数
- 对请求数据进行签名
- 对支付宝返回的通知参数进行验签处理,更改数据库操作
给前端返回 (加密后):
1 | app_id=2020012345678&method=alipay.trade.page.pay&charset=utf-8&version=1.0×tamp=2017-12-06+16%3A54%3A14¬ify_url=http%3A%2F%2Fmallbear.com%2Fapi%2Fmobile%2Ftrades%2F4952%2Falipay_return&sign_type=RSA&biz_content=%7B%22out_trade_no%22%3D%3E%2220171206115444TNCWK%22%2C+%22subject%22%3D%3E%2220171206115444TNCWK%22%2C+%22timeout_express%22%3D%3E%2224h%22%2C+%22total_amount%22%3D%3E227.0%2C+%22product_code%22%3D%3E%22QUICK_MSECURITY_PAY%22%7D&sign=wSLRgh%2BRcHUYA4FIeOm73TRvvqsK%2F6TApMNjgJ3uqqo%2BMK%2BLIjIpqulSE5kIJ7%2BWLScGh9M9N8NmK3dD4BAlWnfaSai2H1Rgsb8eSD%2By1g5BRhnRIt6MlNkKwucEUnlKO1kR5rsZAEAVoowxOqT1HFUvrJLsr%2BeOJp6dnEeyfo8%3D |
实际操作中需要注意的点总结:
1.
在构建支付宝请求参数的时候,需要先把 biz_content 转换成 json 格式,然后把请求参数进行加密提交,把支付宝返回的参数中的签名和(本地的公钥 + 支付宝返回的参数)生成的签名进行校验比对
2.
验签的时候,用的是支付宝提供的公钥,每 64 个字符要换行
3.
获取请求参数的时候去掉无用的参数
1 | params.except(*request.path_parameters.keys) |