微信支付类型、相关术语及流程
- 微信支付账户参数与接口API参数对应关系表:
参数 | API参数名 | 详细说明 |
APPID | appid | appid是微信公众账号或开放平台APP的唯一标识,在公众平台申请公众账号或者在开放平台申请APP账号后,微信会自动分配对应的appid,用于标识该应用。可在微信公众平台-->开发-->基本配置里面查看,商户的微信支付审核通过邮件中也会包含该字段值。 |
微信支付商户号 | mch_id | 商户申请微信支付后,由微信支付分配的商户收款账号。 |
API密钥 | key | 交易过程生成签名的密钥,仅保留在商户系统和微信支付后台,不会在网络中传播。商户妥善保管该Key,切勿在网络中传输,不能在其他客户端中存储,保证key不会被泄漏。商户可根据邮件提示登录微信商户平台进行设置。也可按以下路径设置:微信商户平台(pay.weixin.qq.com)-->账户中心-->账户设置-->API安全-->密钥设置 |
Appsecret | secret | AppSecret是APPID对应的接口密码,用于获取接口调用凭证access_token时使用。在微信支付中,先通过OAuth2.0接口获取用户openid,此openid用于微信内网页支付模式下单接口使用。可登录公众平台-->微信支付,获取AppSecret(需成为开发者且帐号没有异常状态)。 |
- 协议规则:
传输方式 | 为保证交易安全性,采用HTTPS传输 |
提交方式 | 采用POST方法提交 |
数据格式 | 提交和返回数据都为XML格式,根节点名为xml |
字符编码 | 统一采用UTF-8字符编码 |
签名算法 | MD5/HMAC-SHA256 |
签名要求 | 请求和接收数据均需要校验签名,详细方法请参考安全规范-签名算法 |
证书要求 | 调用申请退款、撤销订单、红包接口等需要商户api证书,各api接口文档均有说明。 |
判断逻辑 | 先判断协议字段返回,再判断业务返回,最后判断交易状态 |
特别提示:
必须严格按照API的说明进行一单一支付,一单一红包,一单一付款,在未得到支付系统明确的回复之前不要换单,防止重复支付或者重复付款
- 参数规定:
1、交易金额
交易金额默认为人民币交易,接口中参数支付金额单位为【分】,参数值不能带小数。对账单中的交易金额单位为【元】。
外币交易的支付金额精确到币种的最小单位,参数值不能带小数点。
2、交易类型trade_type
JSAPI--JSAPI支付(或小程序支付)、NATIVE--Native支付、APP--app支付,MWEB--H5支付,不同trade_type决定
了调起支付的方式,请根据支付产品正确上传
MICROPAY--付款码支付,付款码支付有单独的支付接口,所以接口不需要上传,该字段在对账单中会出现
3、货币类型
境内商户号仅支持人民币
CNY:人民币
4、时间
标准北京时间,时区为东八区;如果商户的系统时间为非标准北京时间。参数值必须根据商户系统所在时区先换算成标
准北京时间, 例如商户所在地为0时区的伦敦,当地时间为2014年11月11日0时0分0秒,换算成北京时间为2014年11月
11日8时0分0秒。
5、时间戳
标准北京时间,时区为东八区,自1970年1月1日 0点0分0秒以来的秒数。注意:部分系统取到的值为毫秒级,需要转
换成秒(10位数字)。
6、商户订单号
商户支付的订单号由商户自定义生成,仅支持使用字母、数字、中划线-、下划线_、竖线|、星号*这些英文半角字符的
组合,请勿使用汉字或全角等特殊字符。微信支付要求商户订单号保持唯一性(建议根据当前系统时间加随机序列来生
成订单号)。重新发起一笔支付要使用原订单号,避免重复支付;已支付过或已调用关单、撤销(请见后文的API列表)
的订单号不能重新发起支付。
- 安全规范
1、签名算法
签名生成的通用步骤如下:
第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
特别注意以下重要规则:
- ◆ 参数名ASCII码从小到大排序(字典序);
- ◆ 如果参数的值为空不参与签名;
- ◆ 参数名区分大小写;
- ◆ 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
- ◆ 微信接口可能增加字段,验证签名时必须支持增加的扩展字段
第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换
为大写,得到sign值signValue。
◆ key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置
举例:
假设传送的参数如下:
appid: wxd930ea5d5a258f4f
mch_id: 10000100
device_info: 1000
body: test
nonce_str: ibuaiVcKdpRxkhJA
第一步:对参数按照key=value的格式,并按照参数名ASCII字典序排序如下,PHP中ksort()字典序排序:
stringA="appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA";
第二步:拼接API密钥:
stringSignTemp=stringA+"&key=192006250b4c09247ec02edce69f6a2d" //注:key为商户平台设置的密钥key
sign=MD5(stringSignTemp).toUpperCase()="9A0A8659F005D6984697E2CA0A9CF3B7" //注:MD5签名方式
sign=hash_hmac("sha256",stringSignTemp,key).toUpperCase()="6A9AE1657590FD6257D693A078E1C3E4BB6BA4DC3
0B23E0EE2496E54170DACD6" //注:HMAC-SHA256签名方式,部分语言的hmac方法生成结果二进制结果,需要调对应函数
转化为十六进制字符串。
最终得到最终发送的数据:
wxd930ea5d5a258f4f 10000100 1000 test ibuaiVcKdpRxkhJA 9A0A8659F005D6984697E2CA0A9CF3B7
2、生成随机数算法
微信支付API接口协议中包含字段nonce_str,主要保证签名不可预测。我们推荐生成随机数算法如下:调用随机数函数生成,将得到的值转换为字符串。
- 付款码支付:
语法格式:
- JSAPI支付(公众号支付):
语法格式:
DELETE FROM table_name [WHERE Clause] ##如果不指定where条件,表中所有记录都会被清掉
- 小程序支付:
语法格式:
##省略where条件将会更新所有记录
UPDATE table_name SET field1=new-value1, field2=new-value2 [WHERE Clause]
--------------------------------------------------------------------------------------
UPDATE test SET test_title='C++', test_author='Jacky' WHERE id=1;
如果使用UPDATE语句更新多行,并且在更新这些行中一行或多行出现一个错误则整个UPDATE操作都会被取消
- APP支付:
语法格式:
##省略where条件将会更新所有记录
SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset;
offset指定第一个返回记录行的偏移量,rows指定返回记录行的最大数目。
初始记录行的偏移量是 0(而不是 1): 为了与 PostgreSQL 兼容,MySQL 也支持句法: LIMIT # OFFSET #。
--------------------------------------------------------------------------------------
1、指定一个记录范围
SELECT * FROM test LIMIT 1,2;##检索两条记录,从第2条开始,检索2行,记录行2-3
2、只提供一个参数
SELECT * FROM test LIMIT 0,1;
等价于:
SELECT * FROM test LIMIT 1;##offset默认为0
3、检索从某一个偏移量到记录集的结束所有的记录行,第二个参数为 -1:
mysql> SELECT * FROM test LIMIT 5,-1; // 检索记录行 6-last