微信支付
个人无法开通微信支付
申请开通微信支付参数
邮件(申请微信支付开通)中的账户参数与接口API参数对应关系见表:
账户参数说明
|邮件中参数 |API参数名 |详细说明|
| — | — |
| APPID | appid | appid是微信小程序后台APP的唯一标识,在小程序后台申请小程序账号后,微信会自动分配对应的appid,用于标识该应用。可在小程序–>设置–>开发设置中查看。|
| 微信支付商户号 | mch_id |商户申请微信支付后,由微信支付分配的商户收款账号。|
| API密钥 | key | 交易过程生成签名的密钥,仅保留在商户系统和微信支付后台,不会在网络中传播。商户妥善保管该Key,切勿在网络中传输,不能在其他客户端中存储,保证key不会被泄漏。商户可根据邮件提示登录微信商户平台进行设置。也可按一下路径设置:微信商户平台(pay.weixin.qq.com)–>账户设置–>API安全–>密钥设置 |
| Appsecret | secret | AppSecret是APPID对应的接口密码,用于获取接口调用凭证时使用。|
规范
商户接入微信支付,调用API必须遵循以下规则:
| method | desp |
|---|---|
| 传输方式 | 为保证交易安全性,采用HTTPS传输 |
| 提交方式 | 采用POST方法提交 |
| 数据格式 | 提交和返回数据都为XML格式,根节点名为xml |
| 字符编码 | 统一采用UTF-8字符编码 |
| 签名算法 | MD5,后续会兼容SHA1、SHA256、HMAC等。 |
| 签名要求 | 请求和接收数据均需要校验签名,详细方法请参考安全规范-签名算法 |
| 证书要求 | 调用申请退款、撤销订单接口需要商户证书 |
| 判断逻辑 | 先判断协议字段返回,再判断业务返回,最后判断交易状态 |
参数规定
安全规范
签名算法
签名生成的通用步骤如下:
第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
特别注意以下重要规则:
1 | ◆ 参数名ASCII码从小到大排序(字典序); |
第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。
1 | ◆ key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置 |
即:
1 | stringA="param1=value1¶m2=value2..."; |
Example
假设传送的参数如下:
1 | appid: wxd930ea5d5a258f4f |
第一步:对参数按照key=value的格式,并按照参数名ASCII字典序排序如下:
1 | stringA="appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA"; |
第二步:拼接API密钥:
1 | stringSignTemp=stringA+"&key=192006250b4c09247ec02edce69f6a2d" //注:key为商户平台设置的密钥key |
最终得到最终发送的数据:
1 | <xml> |
生成随机数算法
微信支付API接口协议中包含字段nonce_str,主要保证签名不可预测。我们推荐生成随机数算法如下:调用随机数函数生成,将得到的值转换为字符串。
API证书
(1)获取API证书(SSL… 校验身份什么是api证书?如何升级?)
微信支付接口中,涉及资金回滚的接口会使用到API证书,包括退款、撤销接口。商家在申请微信支付成功后,收到的相应邮件后,可以按照指引下载API证书,也可以按照以下路径下载:微信商户平台(pay.weixin.qq.com)–>账户中心–>账户设置–>API安全 。证书文件说明如下:
(2)使用API证书
1 | ◆ apiclient_cert.p12是商户证书文件,除PHP外的开发均使用此证书文件。 |
(3)API证书安全
- 证书文件不能放在web服务器虚拟目录,应放在有访问权限控制的目录中,防止被他人下载;
- 建议将证书文件名改为复杂且不容易猜测的文件名;
- 商户服务器要做好病毒和木马防护工作,不被非法侵入者窃取证书文件。
商户回调API安全
在普通的网络环境下,HTTP请求存在DNS劫持、运营商插入广告、数据被窃取,正常数据被修改等安全风险。商户回调接口使用HTTPS协议可以保证数据传输的安全性。所以微信支付建议商户提供给微信支付的各种回调采用HTTPS协议。请参考:HTTPS搭建指南。
业务流程
业务流程时序图
小程序支付的交互图如下:
商户系统和微信支付系统主要交互:
1、小程序内调用登录接口,获取到用户的openid,api参见公共api【小程序登录API】
2、商户server调用支付统一下单,api参见公共api【统一下单API】
3、商户server调用再次签名,api参见公共api【再次签名】
4、商户server接收支付通知,api参见公共api【支付结果通知API】
5、商户server查询支付结果,api参见公共api【查询订单API】
开发步骤
如果开发者已做过JSAPI或JSSDK调起微信支付,接入小程序支付非常相似,以下是三种接入方式的对比:
| 对比栏目| JSAPI | JSSDK| 小程序|
|— | —|
|统一下单| 都需要先获取到Openid,调用相同的API|||
|调起数据签名 |五个字段参与签名(区分大小写):appId,nonceStr,package,signType,timeStamp |||
|调起支付页面协议 | HTTP或HTTPS |HTTP或HTTPS| HTTPS|
|支付目录 |有 |有 |无|
|授权域名 |有 |有 |无|
|回调函数 |有 |success回调 |complete、fail、success回调函数|
程序访问商户服务都是通过HTTPS,开发部署的时候需要安装HTTPS服务器
openid: code2session() 获取(登录api–getSession)
1 | { |
调起数据签名
详解小程序调起支付API-小程序调起支付数据签名字段列表
appid,nonceStr(随机数),package(…),signType(MD5/HMAC-SHA256),timeStamp
小程序调起支付API
小程序调起支付数据签名字段列表
|字段名 |变量名 |必填 |类型 |示例值 |描述|
|—|—|
|小程序ID |appId |是 |String |wxd678efh567hg6787 |微信分配的小程序ID|
|时间戳 |timeStamp |是 |String |1490840662 |时间戳从1970年1月1日00:00:00至今的秒数,即当前的时间|
|随机串 |nonceStr |是 |String |5K8264ILTKCH16CQ2502SI8ZNMTM67VS |随机字符串,不长于32位。推荐随机数生成算法|
|数据包 |package |是 |String| prepay_id=wx2017033010242291fcfe0db70013231072 |统一下单接口返回的prepay_id 参数值,提交格式如:prepay_id=wx2017033010242291fcfe0db70013231072|
|签名方式 |signType |是 |String |MD5 |签名类型,默认为MD5,支持HMAC-SHA256和MD5。注意此处需与统一下单的签名类型一致 |
举例如下:
1 | paySign = MD5(appId=wxd678efh567hg6787&nonceStr=5K8264ILTKCH16CQ2502SI8ZNMTM67VS |
发起支付
调用wx.requestPayment(OBJECT)发起微信支付Object参数说明:
| 参数 | 类型 | 必填 | 说明|
|—|—|
| timeStamp | String | 是 | 时间戳从1970年1月1日00:00:00至今的秒数,即当前的时间 |
| nonceStr | String | 是 | 随机字符串,长度为32个字符以下。 |
| package | String |是 | 统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=* |
| signType | String | 是 | 签名类型,默认为MD5,支持HMAC-SHA256和MD5。注意此处需与统一下单的签名类型一致 |
| paySign | String | 是 | 签名,ok 上一步结果 |
| success | Function | 否 | 接口调用成功的回调函数 |
| fail | Function | 否 | 接口调用失败的回调函数 |
| complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
回调结果:
| 回调类型 | errMsg | 说明 |
|—-|—-|
| success | requestPayment:ok | 调用支付成功 |
| fail | requestPayment:fail cancel | 用户取消支付 |
| fail | requestPayment:fail (detail message) | 调用支付失败,其中 detail message 为后台返回的详细失败原因 |
示例代码:
1 | wx.requestPayment( |
最佳实践
HTTPS服务器配置
一、SSL证书申请
确认需要申请证书的域名
生成私钥和csr文件
在linux机器上执行以下命令生成私钥1
openssl genrsa -out server.key 2048
在linux机器上执行以下命令生成csr文件
1
openssl req -new -key server.key -out certreq.csr
以下黑色标识文字仅供参考,请根据商户自己实际情况进行填写
1
2
3
4
5
6
7
8Country Name: CN //您所在国家的ISO标准代号,中国为CN
State or Province Name:guandong //您单位所在地省/自治区/直辖市
Locality Name:shenzhen //您单位所在地的市/县/区
Organization Name: Tencent Technology (Shenzhen) Company Limited //您单位/机构/企业合法的名称
Organizational Unit Name: R&D //部门名称
Common Name: www.example.com //通用名,例如:www.itrus.com.cn。此项必须与您访问提供SSL服务的服务器时所应用的域名完全匹配。
Email Address: //您的邮件地址,不必输入,直接回车跳过
"extra"attributes //以下信息不必输入,回车跳过直到命令执行完毕。执行上面的命令后,在当前目录下即可生成私钥文件server.key和certreq.csr csr文件
将生成的csr文件提交给第三方证书颁发机构申请对应域名的服务器证书,同时将私钥文件保存好,以免丢失。
证书申请后,证书颁发机构会提供服务器证书内容和两张中级CA证书,请按证书颁发机器说明生成服务器证书,此处假设服务器证书文件名称为server.pem
将生成的私钥文件server.key和服务器证书server.pem拷贝至服务器指定的目录即可进行HTTPS服务器配置
二、HTTPS服务器配置
- Nginx配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15server {
listen 443; #指定ssl监听端口
server_name www.example.com;
ssl on; #开启ssl支持
ssl_certificate /etc/nginx/server.pem; #指定服务器证书路径
ssl_certificate_key /etc/nginx/server.key; #指定私钥证书路径
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #指定SSL服务器端支持的协议版本
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; #指定加密算法
ssl_prefer_server_ciphers on; #在使用SSLv3和TLS协议时指定服务器的加密算法要优先于客户端的加密算法
#以下内容请按域名需要进行配置,此处仅供参考
location / {
return 444;
}
} - 其它web服务器配置
请参考文档:《服务器证书配置指南》
三、相关事项
证书颁发机构
推荐天威诚信,具体请见:链接常见问题
证书受信任的问题
部分国内签发的SSL证书,在Android上不受信任,推荐GeoTrust;如果页面有动静分离,静态资源使用独立域名的话,也需要为该域名申请证书;
android低版本不支持SNI扩展,受此限制,一台服务器只能部署一个数字证书;