字节跳动小程序接入支付功能(Flask)

Java版:http://blog.yixun.store/article/app_wechatpay_alipay

首先先了解字节跳动小程序以及微信H5支付他们发起支付时所需要的参数

微信

H5支付


官网文档链接:https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_4

流程图:

1、用户在商户侧完成下单,使用微信支付进行支付

2、由商户后台向微信支付发起下单请求(调用统一下单接口)注:交易类型trade_type=MWEB

3、统一下单接口返回支付相关参数给商户后台,如支付跳转url(参数名“mweb_url”),商户通过mweb_url调起微信支付中间页

4、中间页进行H5权限的校验,安全性检查(此处常见错误请见下文)

5、如支付成功,商户后台会接收到微信侧的异步通知

6、用户在微信支付收银台完成支付或取消支付,返回商户页面(默认为返回支付发起页面)

7、商户在展示页面,引导用户主动发起支付结果的查询

8,9、商户后台判断是否接到收微信侧的支付结果通知,如没有,后台调用我们的订单查询接口确认订单状态

10、展示最终的订单支付结果给用户

统一下单接口


https://api.mch.weixin.qq.com/pay/unifiedorder

参数


<xml>
<appid>wx2421b1c4370ec43b</appid>
<attach>支付测试</attach>
<body>H5支付测试</body>
<mch_id>10000100</mch_id>
<nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str>
<notify_url>http://wxpay.wxutil.com/pub_v2/pay/notify.v2.php</notify_url>
<openid>oUpF8uMuAJO_M2pxb1Q9zNjWeS6o</openid>
<out_trade_no>1415659990</out_trade_no>
<spbill_create_ip>14.23.150.211</spbill_create_ip>
<total_fee>1</total_fee>                                  #  金额必须为整数,这里单位为分
<trade_type>MWEB</trade_type>
<scene_info>{"h5_info": {"type":"IOS","app_name": "王者荣耀","package_name": "com.tencent.tmgp.sgame"}}</scene_info>
<sign>0CB01533B8C1EF103065174F50BCA001</sign>
</xml>

签名

将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。

特别注意以下重要规则:

  1. ◆ 参数名ASCII码从小到大排序(字典序);
  2. ◆ 如果参数的值为空不参与签名;
  3. ◆ 参数名区分大小写;
  4. ◆ 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
  5. ◆ 微信接口可能增加字段,验证签名时必须支持增加的扩展字段

第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。

key设置路径:微信商户平台(https://pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置

### 微信支付接口签名校验工具(https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=20_1

# 使用MD5生成
m1 = hashlib.md5()
m1.update(stringA)    # stringA为拼接的字符串
key = m1.hexdigest().upper() # 拿到加密字符串,将他转化为大写

只要你生成的和用官方测试工具生成的签名一致,那签名这块就没问题了

 

然后再封装成xml请求微信统一支付接口

request = urllib2.Request(url="https://api.mch.weixin.qq.com/pay/unifiedorder",
                          headers={'Content-Type': 'application/xml', 'charset': 'UTF-8'},
                          data=xml)
f = opener.open(request)
data = f.read()
data = xml2dict.xml2dict(data)

请求成功后会返回以下参数

<xml>
   <return_code><![CDATA[SUCCESS]]></return_code>
   <return_msg><![CDATA[OK]]></return_msg>
   <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
   <mch_id><![CDATA[10000100]]></mch_id>
   <nonce_str><![CDATA[IITRi8Iabbblz1Jc]]></nonce_str>
   <sign><![CDATA[7921E432F65EB8ED0CE9755F0E86D72F]]></sign>
   <result_code><![CDATA[SUCCESS]]></result_code>
   <prepay_id><![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id>
   <trade_type><![CDATA[MWEB]]></trade_type>
   <mweb_url><![CDATA[https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx2016121516420242444321ca0631331346&package=1405458241]]></mweb_url>
</xml>

字节跳动

当你做完所有操作后,就得开始封装返回给字节跳动的数据,所以我们对于字节跳动的文档多多少少也还是要熟悉一点。
当我们返回出去后,前端就会调用字节跳动的tt.pay接口,所以我们返回的参数还需要根据这个接口来规定

官方链接:https://microapp.bytedance.com/dev/cn/mini-app/develop/open-capacity/payment/pay

签名方案只验证 服务端签名前的支付数据 和 tt.pay 发送到字节跳动后端的支付数据 的一致性(因而,具体字段有哪些,以及字段的值是否正确并不由签名验证) ----只要验证对签名就好了

生成签名规则

 

Key 筛选(我之前就是错在这一步,搞了很久,有些参数是不要参加签名的)


去掉请求参数中的字节类型字段(如文件、字节流)、sign 与 risk_info 字段、value 为空的字段(某些接口请求参数中特殊标明不参与签名的字段也需要去掉)。

 

K-V 排序和拼接


把筛选后的 k-v 集合按照 key 的 ASCII 码升序排序,

k-v 按照 key=value 的格式链接,并且按照 key 排序使用 & 连接成一个字符串,生成待签名字符串

 

MD5 加签


MD5(待签名字符串 + app_secret); // 待签名字符串 + app_secret 是字符串直接拼接,待签名字符串在前,中间没有连接符

sign = hashlib.md5(string)

然后将所有的数据返回给前端

data = {
            'app_id': str(dy_utils.app_id),  # 头条支付分配给商户 app_id
            'merchant_id': str(dy_utils.partner_id),  # 商户号
            'timestamp': str(create_time),  # 请求时间戳
            'out_order_no': str(order_num),  # 订单号
            'total_amount': str(money),  # 金额
            'trade_type': 'H5',   # 交易类型
            'subject': '测试订单',  # 商户订单名称
            'body': '测试订单',  # 商户订单详情
            'uid': str(uid),   # 用户id
            'trade_time': str(create_time),  # 下单时间戳
            'notify_url': return_url,
            'risk_info': client_ip,
            'wx_url': mweb_url,    # 微信支付跳转链接
            'sign': sign,  # 签名
        }

有些固定值让前端添加

 

# 验证签名


可以先用官方给的数据来进行签名,如果签名对了,就将官方的数据换成自己的数据

{
  app_id: '800000000001',
  merchant_id: '1900000001',
  timestamp: 1570694312,
  sign_type: 'MD5',
  out_order_no: '201900000000000001',
  total_amount: 1,
  product_code: 'pay',
  payment_type: 'direct',
  trade_type: 'H5',
  version: '2.0',
  currency: 'CNY',
  subject: '测试订单',
  body: '测试订单',
  uid: '0000000000000001',
  trade_time: 1570585744,
  valid_time: 300,
  notify_url: '',
  risk_info: '{"ip":"120.230.0.0"}',
  wx_type: 'MWEB',
  wx_url: 'https://wx.tenpay.com/xxx',
  alipay_url: 'app_id=2019000000000006&biz_content=xxxx'
}

则待签名字符串 unsigned_str 为:

alipay_url=app_id=2019000000000006&biz_content=xxxx&app_id=800000000001&body=测试订单&currency=CNY&merchant_id=1900000001&out_order_no=201900000000000001&payment_type=direct&product_code=pay&sign_type=MD5&subject=测试订单&timestamp=1570694312&total_amount=1&trade_time=1570585744&trade_type=H5&uid=0000000000000001&valid_time=300&version=2.0&wx_type=MWEB&wx_url=https://wx.tenpay.com/xxx

若你的 app_secret 是 'a',那么带入上述 unsigned_str,最终 MD5(unsigned_str + app_secret) 后签名字符串 signed_str 应为:

0f1e3358a9898d7c4c6c23740251808a

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值