如何使用签名/验签工具
更新时间:2024.08.22# 概述
在微信支付APIV3的所有接口交互中,都需要对【接口请求】或【回调通知】进行SHA256 with RSA算法签名计算,保证支付安全;并且也强烈建议对【响应】和【回调】进行验签(部分接口不需要响应验签),保证响应数据来自微信支付且未经第三方篡改。对于常见的APIv3接口签名错误的问题,提供【签名验签工具】,模拟微信支付进行签名验签。
提示
- 本工具无法识别并提示错误参数,计算结果需自行核对,不会主动纠正,可能产生无效的请求签名。
- 若相应的必填参数未填写时,本工具不会进行提醒。
- 该工具目前只支持Windows操作系统,其他类型的操作系统暂不支持。
下面介绍工具详细操作指引,协助你进行签名计算和签名验证。
# 1. 如何下载签名验签工具
下载地址:下载签名验签工具 (opens new window)
1.1 打开时个别用户可能会提示:找不到MSVCR120.dll文件,需要额外下载一下该文件,放置安装目录即可。
1.2 功能界面
# 2. 如何使用签名验签工具
微信支付在签名计算和签名验证中使用基于非对称密钥的SHA256-RSA的数字签名算法,利用公钥和私钥的配对关系实现加密和解密。私钥用于加密数据,公钥用于解密数据。由于私钥的私密性,只有私钥的拥有者才能生成有效的签名,确保了信息的完整性和来源的可靠性。
下面列举了微信支付常见场景的签名/验签参数以及使用的证书:
签名场景 | 微信支付APIv3接口 | 调起收银台 | 微信支付应答/回调 |
---|---|---|---|
计算签名证书 | 商户API证书私钥(商户API证书获取方法及功能介绍 (opens new window)) apiclient_key.pem | 商户API证书私钥(商户API证书获取方法及功能介绍 (opens new window)) apiclient_key.pem | 微信支付平台证书私钥(商户无法持有/感知) |
签名串格式 | HTTP请求方法\n URL\n 请求时间戳\n 请求随机串\n 请求报文主体\n | 应用ID\n 时间戳\n 随机字符串\n 扩展字符串\n | 应答时间戳\n 应答随机串\n 应答报文主体\n |
签名验证证书 | 商户API证书公钥 apiclient_cert.pem | 商户API证书公钥 apiclient_cert.pem | 微信支付平台证书公钥(通过下载平台证书 (opens new window)接口获得) |
验证方式 | 商户可以使用其自身的商户API证书私钥(apiclient_key.pem)对待签名串进行SHA256 with RSA签名,并对签名结果进行Base64编码,从而获得签名值signature。 微信支付侧会使用商户API证书公钥(apiclient_cert.pem)对商户上送的签名值进行解密验签,以确保请求的数据的完整性和真实性。 | 商户可以使用其自身的商户API证书私钥(apiclient_key.pem)对待签名串进行SHA256 with RSA签名,并对签名结果进行Base64编码,从而获得签名值signature。 微信支付侧会使用商户API证书公钥(apiclient_cert.pem)对商户上送的签名值进行解密验签,以确保请求的数据的完整性和真实性。 | 微信支付用微信支付平台证书私钥对【响应签名串】进行SHA256 with RSA签名,并对签名结果进行Base64编码得到签名值。 商户收到回调消息后,使用微信支付平台证书公钥对回调/响应消息中包含的【响应签名串】进行解密验签。 |
# 3. 签名验证示例
# 3.1 微信支付APIv3接口
# 3.1.1 验签参数填写
参数 | 说明 | 示例 |
---|---|---|
选择文件 | 请求微信支付API时使用商户API证书私钥(apiclient_key.pem)进行签名,现使用工具模拟验签流程,所以验签文件需选择商户API证书公钥(apiclient_cert.pem)进行签名验证。 | apiclient_cert.pem |
明文/验签串 | 所有APIv3请求的明文格式相同。 由5个部分组成,每一行尾部都需要填充换行符 \n,工具中不能出现 \n 的字符文本,需使用回车键换行。 | POST /v3/pay/transactions/jsapi 1724060744 614275b63d789bd3a7a472c63d809552 {"time_expire":"2022-11-11T23:59:59+08:00","amount":{"total":1},"mchid":"1900006891","out_trade_no":"Tencentwechatpay0000457","settle_info":{"profit_sharing":false},"appid":"wx0036c37711cdfb99","description":"Image形象店-深圳腾大-QQ公仔","attach":"附加数据","notify_url":"https://www.weixin.qq.com/wxpay/pay.php","payer":{"openid":"ooejCjpfavMf1-KzCpQrKl_rzYZk"},"support_fapiao":false} |
签名 | 使用明文计算得到的签名值 | Ggewaqj5IovOiDUDzhGvOzSUDTv1nHwa1oX4AKyUCrQTXG3+p4VrmfWA8cRt3WiR+iOB/kSrWCbF+K2WhvhhWJSmrtaGy+5Sig3OSw+e+H38go6fc33ijr7p+l3xihMKSkU4r3YgluixXt/GVhxMCiFF5THj/VMyZuT4o3BE46eZMM52MovEcNRpI6CF5TseuXa87P+u56Lk8yvqOB2+Qy3Nf0aiezbAktr/wXP4mMh0ceB1g5Yv2Hk5wzERM2dZwogzyncOMef0BeebTwadR/OxPlbr7HyI816SJdefQUIszdFXEOo3xgR8UnzyXXX6NU/mnreGVLnC9U3Or8Sc6g== |
# 3.1.2 GET请求验证示例(通过商户单号查询订单状态)
1GET https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/{out_trade_no}?mchid={mchid}
请求内容 | 值 |
---|---|
HTTP方法 | GET |
参与签名的URL | /v3/pay/transactions/out-trade-no/Tencentwechatpay0000457?mchid=1900006891 |
签名信息-请求时间戳 (参与签名计算时使用的时间戳) | 1723789635 |
签名信息-请求随机串 (参与签名计算时使用的随机串) | 614275b63d789bd3a7a472c63d809552 |
明文/验签串 | GET /v3/pay/transactions/out-trade-no/Tencentwechatpay0000457?mchid=1900006891 1723793954 614275b63d789bd3a7a472c63d809552 |
签名 | mm/2CMGxo5qDKNk1i7Szn0IiwAUPlfrpeCE1udNzEvUmohKYO8e40+3hNUTZVXwXUO4qOik/gqrPmXmppF37xa9aIe/oPzPLHaIpSCnDL1VBjl60ztc66kVkFQc/1LvYFwDzpsbnxq1B/DeMTTB6oXekfEDuZATI/erJ+B63BY+Cm6hKMDoPyaHn5hoFSTyfuLacxei+a0sPbFGGklDzr/vxh0Pta3Gp4vCvtnt7cmT+72h5Z7cijiYfw7JHzWt9VcK8Z1r9f6hMuYx6y2BIaEIcczZxq9fLxwRXZRYC2pRwUdrhADFHAUExm5oglZLgZ5QFc1dWijBGzVWzA40O7w== |
签名验证示例:
# 3.1.3 非GET请求验证示例(以JSAPI下单接口为例)
请求微信支付APIv3接口时,签名参数示例:
1POST https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi
请求内容 | 值 |
---|---|
HTTP方法 | POST |
参与签名的URL | /v3/pay/transactions/jsapi |
签名信息-请求时间戳 (参与签名计算时使用的时间戳) | 1724062075 |
签名信息-请求随机串 (参与签名计算时使用的随机串) | 614275b63d789bd3a7a472c63d809552 |
请求Body | {"time_expire":"2022-11-11T23:59:59+08:00","amount":{"total":1},"mchid":"1900006891","out_trade_no":"Tencentwechatpay0000457","settle_info":{"profit_sharing":false},"appid":"wx0036c37711cdfb99","description":"Image形象店-深圳腾大-QQ公仔","attach":"附加数据","notify_url":"https://www.weixin.qq.com/wxpay/pay.php","payer":{"openid":"ooejCjpfavMf1-KzCpQrKl_rzYZk"},"support_fapiao":false} |
明文/验签串 | POST v3/pay/transactions/jsapi 1724062075 614275b63d789bd3a7a472c63d809552 {"time_expire":"2022-11-11T23:59:59+08:00","amount":{"total":1},"mchid":"1900006891","out_trade_no":"Tencentwechatpay0000457","settle_info":{"profit_sharing":false},"appid":"wx0036c37711cdfb99","description":"Image形象店-深圳腾大-QQ公仔","attach":"附加数据","notify_url":"https://www.weixin.qq.com/wxpay/pay.php","payer":{"openid":"ooejCjpfavMf1-KzCpQrKl_rzYZk"},"support_fapiao":false} |
签名 | Ggewaqj5IovOiDUDzhGvOzSUDTv1nHwa1oX4AKyUCrQTXG3+p4VrmfWA8cRt3WiR+iOB/kSrWCbF+K2WhvhhWJSmrtaGy+5Sig3OSw+e+H38go6fc33ijr7p+l3xihMKSkU4r3YgluixXt/GVhxMCiFF5THj/VMyZuT4o3BE46eZMM52MovEcNRpI6CF5TseuXa87P+u56Lk8yvqOB2+Qy3Nf0aiezbAktr/wXP4mMh0ceB1g5Yv2Hk5wzERM2dZwogzyncOMef0BeebTwadR/OxPlbr7HyI816SJdefQUIszdFXEOo3xgR8UnzyXXX6NU/mnreGVLnC9U3Or8Sc6g== |
签名验证示例:
注意
APIv3接口请求 签名验证不通过 注意事项
- 严格按照验签参数填写规则中进行参数填写,注意验签文件选择,明文格式内容填写,尾部需回车换行。否则签名验证结果无效。
- 请注意明文中用于签名的时间戳和随机串内容是否和Authorization中的时间戳和随机串内容一致。
- 请注意明文中用于签名的签名值内容是否和Authorization中的signature内容一致。
- 检查签名的Body和实际代码请求时使用的Body是否完全一致。当请求方法为POST或PUT时,请使用真实发送的JSON报文。
- 请注意区分GET和POST请求中明文内容:
a. 请求方式不同(GET和POST均是大写)
b. URL设置:GET请求注意带上完整的路径参数和查询参数。
c. Body(签名串明文第5项内容不同):
请求方法为GET时,报文主体body是空的。所以展示出来GET请求随机串后面需要2个回车,签名串规则如下
如何生成请求签名 - 若参数填写没问题,工具中签名验证通过,但接口仍然报签名错误,则因为实际接口请求时使用的【证书】、【签名信息】和【Body】与工具中参与签名的参数信息不一致导致,需注意核对。
# 3.2 调起收银台
# 3.2.1 验签参数填写
参数 | 说明 | 示例 |
---|---|---|
选择文件 | 请求微信支付API时使用商户API证书私钥(apiclient_key.pem)进行签名,现使用工具模拟验签流程,所以验签文件需选择商户API证书公钥(apiclient_cert.pem)进行签名验证。 | apiclient_cert.pem |
明文/验签串 | 由4个部分组成,每一行尾部都需要填充换行符 \n,工具中不能出现 \n 的字符文本,需使用回车键换行。 | wxdce7996323956160 1723691310813 ff6ow9e1smvq3hg5qotr5m9q896i6nb7 wx15110833050799e86af8a2989edddf0001 |
签名 | 计算得到的签名值 | X+rmlGdyzHDBzd469iMPwajsxUPyTZf2BrROmdorJzVOcw/sDeUAkMc0iGMlOh4++//DtATW+qemIQ7MNWQxdD+MGOlWOgrSJ/zBBUTrzS/qSSaUeJ49Ah9c2+QEpfWfPpejWmLDqr83saGCkbHUxi0IVvLdZ12PkKgYh3ewn3TO1gq1GSMZTZbHSQ+5zbaBMaGnmE0ciwWUWkD6qGAYgrrni9j5MYNSODS2Dx3/p0Hq8QHhG5/J7rgKloL8xWwagkmeU9mvzovcyEHMggY+H7eS+KtH7KhyCUwKvziTkyyjwDMIsjanQXg7kGS5WAwhVEvJCfX1RADl4kpbmaSnJg== |
使用App支付、JSAPI支付和小程序支付时,下单成功后,需要对相关调起参数计算签名,再通过JS SDK调起收银台。
调起收银台和请求APIv3接口时使用的签名算法一致,主要的不同是需构造出不同的签名明文。
# 3.2.2 调起收银台验证示例(App支付)
参数 | 示例 |
---|---|
应用ID | wxdce7996323956160 |
签名信息-请求时间戳 (参与签名计算时使用的时间戳) | 1723691310813 |
签名信息-请求随机串 (参与签名计算时使用的随机串) | ff6ow9e1smvq3hg5qotr5m9q896i6nb7 |
预支付交易会话ID | wx15110833050799e86af8a2989edddf0001 |
明文/验签串 | wxdce7996323956160 1723691310813 ff6ow9e1smvq3hg5qotr5m9q896i6nb7 wx15110833050799e86af8a2989edddf0001 |
签名 | X+rmlGdyzHDBzd469iMPwajsxUPyTZf2BrROmdorJzVOcw/sDeUAkMc0iGMlOh4++//DtATW+qemIQ7MNWQxdD+MGOlWOgrSJ/zBBUTrzS/qSSaUeJ49Ah9c2+QEpfWfPpejWmLDqr83saGCkbHUxi0IVvLdZ12PkKgYh3ewn3TO1gq1GSMZTZbHSQ+5zbaBMaGnmE0ciwWUWkD6qGAYgrrni9j5MYNSODS2Dx3/p0Hq8QHhG5/J7rgKloL8xWwagkmeU9mvzovcyEHMggY+H7eS+KtH7KhyCUwKvziTkyyjwDMIsjanQXg7kGS5WAwhVEvJCfX1RADl4kpbmaSnJg== |
签名验证示例:
注意
调起收银台 签名验证不通过 注意事项
- 严格按照验签参数填写规则中进行参数填写,注意验签文件选择、明文格式内容填写、行尾需回车换行。否则签名验证结果无效。
- 请注意明文中用于签名的时间戳和随机串内容是否与传递给前端的时间戳和随机串内容一致。
- 应用ID需要下单参数中appid和实际调起的应用一致。App调起则是App的应用ID;JSAPI公众号调起,传递调起的公众号的应用ID。
- 如果是JSAPI支付,明文中需要传递【订单详情拓展字符串】,格式要加“prepay_id=”前缀,如
prepay_id=wx201410272009395522657a690389285100
- 若工具验签通过,但调起仍然报签名支付验证失败排查:参数和证书正确,工具校验结果一定是正确的;请注意打印对比,前后端签名和发起支付请求的实际数据参数名称和参数内容是否完全一致。
# 3.3 微信支付应答/回调
由于用于消息加密的微信支付平台证书私钥仅为微信支付侧所持有,商户无法独立创建消息以进行回调验证测试。因此,商户仅能通过实际的线上应答/回调请求来获取相应参数以完成测试。
# 3.3.1 验签参数填写
参数 | 说明 | 示例 |
---|---|---|
选择文件 | 响应/回调请求头Headers会包含使用的验签证书序列号Wechatpay-Serial,根据该证书序列号选择对应的证书 | 微信平台证书(公钥) 1、通过下载平台证书 (opens new window)接口获得 ciphertext ,使用APIv3 (opens new window)密钥,可以从ciphertext解密出平台证书的明文。证书明文需自行保存为PEM文件格式;2、首次下载证书,可以使用微信支付提供的证书下载工具 (opens new window),该工具会自动下载解密证书到指定位置(PEM文件格式) |
明文/验签串 | 由3个部分组成,每一行尾部都需要填充换行符 \n,工具中不能出现 \n 的字符文本,需使用回车键换行。 | 1724231603 D4PJYH8323444WUNiUs5O1jorgGif5ykEs {"id":"da2b8a7f-dad3-5f69-b5eb-2446b94543","create_time":"2024-08-16T15:00:03+08:00","resource_type":"encrypt-resource","event_type":"TRANSACTION.SUCCESS","summary":"支付成功","resource":{"original_type":"transaction","algorithm":"AEAD_AES_256_GCM","ciphertext":"Zkwzt1znCk78U2/xRl2ZVHlwaxcTg02MWN/36VW3cTFGJJWCDucckbqEPFCt5HIAwuhz1+oVbI1NJDqqmdfJAKSeZvDWivzgkLehZSI211qZhPruF8+/Oo8fuEmTigQo6BL1XUDUKSyegcYphyU+hFayU6gXAa7hatmbOr36dALy5Ijb+o6f+VDJ33A77lGgFP5xD1IhaqLkaYnDseBxot5bn3fwtASpNN176VKnKDb4co5E73kJzgtF3qPZTv40Nud0qakFHjs8h7NI7/hKKZVRL8wd3NHXLFfWGlq11GBjpH4Pm7OtZMifdHEa2pxZDiiYnAdO49cx1EMToN+0cdKv4dxWLxsy4wJhja44zaIfaViGSxbOojo1017C1eNQvfLraEqRnASvkilb/MQUPhLNM93PI1I20M6rrsKMNsF0U3IKYHvay+r9V+twrzXuHbgBWWVUtxVwvpIEzuPkJ756zRK5mf/XOLyotW4E42DBVgJZ+11OyTY8aSANWUl2G4zJoVlQJgHgNy0JNF2w0/7kU02o6fkDp81lOP7QU/4PeyzIqchDoqqhxKGOfMrun+V6/avn+tcZ2qIK+2etIZ4NwTun6G/Q2Cn8hRUwcXU28eWJvMrFeg==","associated_data":"transaction","nonce":"Oiyu5riw0HOJ"}} |
签名 | 响应/回调 请求头中的签名值Wechatpay-Signature | ZTp6+tGGBDoh+6dnG9fFQFStlBqgtqozfACJ2bwHKB6yRn0qIaIgWUcT72Ylhyjzh9c3nvTG2xbeSyY4TclAVbSz4z2aLnR6h0VBXhDxIqcuR+m1lVed9WcE0Yebb496gh7vctrRtJXTb+wZ6pdtqJ+Z/XqZn/rz7o16IQIxdHrBnIotkEzJ56stwPsrcuOf/dQOY3enkv3cfMSLRfMkto70xfzIYu+Hr7M5FIbSiMviIgPp+gvF4O0BsEXxSYTIuTQ4GISYlLplirv4tNVCqcZEB5Mb/vK0xWtO0oIEAPwA8Y5qqVAj6FPdPPaCxGqbdR6Qmvf55N+KRWisfA6RLQ== |
# 3.3.2 微信通知回调验证示例(支付通知)
以某次支付成功后支付回调通知HTTP 报文为例:
请求头
1Content-Length: 9232Wechatpay-Nonce: D4PJYH8323444WUNiUs5O1jorgGif5ykEs3Wechatpay-Signature: ZTp6+tGGBDoh+6dnG9fFQFStlBqgtqozfACJ2bwHKB6yRn0qIaIgWUcT72Ylhyjzh9c3nvTG2xbeSyY4TclAVbSz4z2aLnR6h0VBXhDxIqcuR+m1lVed9WcE0Yebb496gh7vctrRtJXTb+wZ6pdtqJ+Z/XqZn/rz7o16IQIxdHrBnIotkEzJ56stwPsrcuOf/dQOY3enkv3cfMSLRfMkto70xfzIYu+Hr7M5FIbSiMviIgPp+gvF4O0BsEXxSYTIuTQ4GISYlLplirv4tNVCqcZEB5Mb/vK0xWtO0oIEAPwA8Y5qqVAj6FPdPPaCxGqbdR6Qmvf55N+KRWisfA6RLQ==+p4VrmfWA8cRt3WiR+iOB/kSrWCbF+K2WhvhhWJSmrtaGy+5Sig3OSw+e+H38go6fc33ijr7p+l3xihMKSkU4r3YgluixXt/GVhxMCiFF5THj/VMyZuT4o3BE46eZpp7RMovEcNRpI6CF5TseuXa87P+u56Lk8yvqOB2+Qy3Nf0aiezbAktr/wXP4mMh0ceB1g5Yv2Hk5wzERM2dZwogzyncOMef0BeebTwadR/OxPlbr7HyI816SJdefQUIszdFXEOo3xgR8UnzyXXX6NU/mnreGVLnC9U3Or8Sc6g=4Wechatpay-Timestamp: 17242316035Wechatpay-Serial: 5157F09EFDC960DE15EBE81A47057A7232F1B8E16Wechatpay-Signature-Type: WECHATPAY2-SHA256-RSA20487Connection: keep-alive8Content-Type: application/json9User-Agent: Mozilla/4.0
请求体
1{"id":"da2b8a7f-dad3-5f69-b5eb-2446b94543","create_time":"2024-08-16T15:00:03+08:00","resource_type":"encrypt-resource","event_type":"TRANSACTION.SUCCESS","summary":"支付成功","resource":{"original_type":"transaction","algorithm":"AEAD_AES_256_GCM","ciphertext":"Zkwzt1znCk78U2/xRl2ZVHlwaxcTg02MWN/36VW3cTFGJJWCDucckbqEPFCt5HIAwuhz1+oVbI1NJDqqmdfJAKSeZvDWivzgkLehZSI211qZhPruF8+/Oo8fuEmTigQo6BL1XUDUKSyegcYphyU+hFayU6gXAa7hatmbOr36dALy5Ijb+o6f+VDJ33A77lGgFP5xD1IhaqLkaYnDseBxot5bn3fwtASpNN176VKnKDb4co5E73kJzgtF3qPZTv40Nud0qakFHjs8h7NI7/hKKZVRL8wd3NHXLFfWGlq11GBjpH4Pm7OtZMifdHEa2pxZDiiYnAdO49cx1EMToN+0cdKv4dxWLxsy4wJhja44zaIfaViGSxbOojo1017C1eNQvfLraEqRnASvkilb/MQUPhLNM93PI1I20M6rrsKMNsF0U3IKYHvay+r9V+twrzXuHbgBWWVUtxVwvpIEzuPkJ756zRK5mf/XOLyotW4E42DBVgJZ+11OyTY8aSANWUl2G4zJoVlQJgHgNy0JNF2w0/7kU02o6fkDp81lOP7QU/4PeyzIqchDoqqhxKGOfMrun+V6/avn+tcZ2qIK+2etIZ4NwTun6G/Q2Cn8hRUwcXU28eWJvMrFeg==","associated_data":"transaction","nonce":"Oiyu5riw0HOJ"}}
验签参数
参数 | 说明 | 示例 |
---|---|---|
应答/回调时间戳 | 签名信息-请求时间戳 应答/回调 请求头Headers获取 Wechatpay-Timestamp | 1724231603 |
应答/回调随机字符串 | 签名信息-随机字符串 应答/回调 请求头Headers中获取 Wechatpay-Nonce | D4PJYH8323444WUNiUs5O1jorgGif5ykEs |
应答/回调报文主体 | 请使用原始报文主体执行验签。如果您使用了某个框架,要确保它不会篡改报文主体。对报文主体的任何篡改都会导致验证失败。 | {"id":"da2b8a7f-dad3-5f69-b5eb-2446b94543","create_time":"2024-08-16T15:00:03+08:00","resource_type":"encrypt-resource","event_type":"TRANSACTION.SUCCESS","summary":"支付成功","resource":{"original_type":"transaction","algorithm":"AEAD_AES_256_GCM","ciphertext":"Zkwzt1znCk78U2/xRl2ZVHlwaxcTg02MWN/36VW3cTFGJJWCDucckbqEPFCt5HIAwuhz1+oVbI1NJDqqmdfJAKSeZvDWivzgkLehZSI211qZhPruF8+/Oo8fuEmTigQo6BL1XUDUKSyegcYphyU+hFayU6gXAa7hatmbOr36dALy5Ijb+o6f+VDJ33A77lGgFP5xD1IhaqLkaYnDseBxot5bn3fwtASpNN176VKnKDb4co5E73kJzgtF3qPZTv40Nud0qakFHjs8h7NI7/hKKZVRL8wd3NHXLFfWGlq11GBjpH4Pm7OtZMifdHEa2pxZDiiYnAdO49cx1EMToN+0cdKv4dxWLxsy4wJhja44zaIfaViGSxbOojo1017C1eNQvfLraEqRnASvkilb/MQUPhLNM93PI1I20M6rrsKMNsF0U3IKYHvay+r9V+twrzXuHbgBWWVUtxVwvpIEzuPkJ756zRK5mf/XOLyotW4E42DBVgJZ+11OyTY8aSANWUl2G4zJoVlQJgHgNy0JNF2w0/7kU02o6fkDp81lOP7QU/4PeyzIqchDoqqhxKGOfMrun+V6/avn+tcZ2qIK+2etIZ4NwTun6G/Q2Cn8hRUwcXU28eWJvMrFeg==","associated_data":"transaction","nonce":"Oiyu5riw0HOJ"}} |
明文/验签串 | 由3个部分组成,每一行尾部都需要填充换行符 \n,工具中不能出现 \n 的字符文本,需使用回车键换行。 | 1724231603 D4PJYH8323444WUNiUs5O1jorgGif5ykEs {"id":"da2b8a7f-dad3-5f69-b5eb-2446b94543","create_time":"2024-08-16T15:00:03+08:00","resource_type":"encrypt-resource","event_type":"TRANSACTION.SUCCESS","summary":"支付成功","resource":{"original_type":"transaction","algorithm":"AEAD_AES_256_GCM","ciphertext":"Zkwzt1znCk78U2/xRl2ZVHlwaxcTg02MWN/36VW3cTFGJJWCDucckbqEPFCt5HIAwuhz1+oVbI1NJDqqmdfJAKSeZvDWivzgkLehZSI211qZhPruF8+/Oo8fuEmTigQo6BL1XUDUKSyegcYphyU+hFayU6gXAa7hatmbOr36dALy5Ijb+o6f+VDJ33A77lGgFP5xD1IhaqLkaYnDseBxot5bn3fwtASpNN176VKnKDb4co5E73kJzgtF3qPZTv40Nud0qakFHjs8h7NI7/hKKZVRL8wd3NHXLFfWGlq11GBjpH4Pm7OtZMifdHEa2pxZDiiYnAdO49cx1EMToN+0cdKv4dxWLxsy4wJhja44zaIfaViGSxbOojo1017C1eNQvfLraEqRnASvkilb/MQUPhLNM93PI1I20M6rrsKMNsF0U3IKYHvay+r9V+twrzXuHbgBWWVUtxVwvpIEzuPkJ756zRK5mf/XOLyotW4E42DBVgJZ+11OyTY8aSANWUl2G4zJoVlQJgHgNy0JNF2w0/7kU02o6fkDp81lOP7QU/4PeyzIqchDoqqhxKGOfMrun+V6/avn+tcZ2qIK+2etIZ4NwTun6G/Q2Cn8hRUwcXU28eWJvMrFeg==","associated_data":"transaction","nonce":"Oiyu5riw0HOJ"}} |
签名 | 应答/回调 请求头Headers中获取Wechatpay-Signature | ZTp6+tGGBDoh+6dnG9fFQFStlBqgtqozfACJ2bwHKB6yRn0qIaIgWUcT72Ylhyjzh9c3nvTG2xbeSyY4TclAVbSz4z2aLnR6h0VBXhDxIqcuR+m1lVed9WcE0Yebb496gh7vctrRtJXTb+wZ6pdtqJ+Z/XqZn/rz7o16IQIxdHrBnIotkEzJ56stwPsrcuOf/dQOY3enkv3cfMSLRfMkto70xfzIYu+Hr7M5FIbSiMviIgPp+gvF4O0BsEXxSYTIuTQ4GISYlLplirv4tNVCqcZEB5Mb/vK0xWtO0oIEAPwA8Y5qqVAj6FPdPPaCxGqbdR6Qmvf55N+KRWisfA6RLQ==+p4VrmfWA8cRt3WiR+iOB/kSrWCbF+K2WhvhhWJSmrtaGy+5Sig3OSw+e+H38go6fc33ijr7p+l3xihMKSkU4r3YgluixXt/GVhxMCiFF5THj/VMyZuT4o3BE46eZpp7RMovEcNRpI6CF5TseuXa87P+u56Lk8yvqOB2+Qy3Nf0aiezbAktr/wXP4mMh0ceB1g5Yv2Hk5wzERM2dZwogzyncOMef0BeebTwadR/OxPlbr7HyI816SJdefQUIszdFXEOo3xgR8UnzyXXX6NU/mnreGVLnC9U3Or8Sc6g= |
签名验证示例:
注意
微信支付通知/回调 签名验证不通过 排查思路
- 严格按照验签参数填写规则中进行参数填写,注意验签文件选择,明文格式内容填写,行尾需回车换行。否则签名验证结果无效。
- 请注意,验证应答和通知回调的签名应使用微信支付平台证书,而非商户 API 证书。使用商户 API 证书将验证失败。
- 在验证签名前,您应先检查 HTTP 头 Wechatpay-Serial 的内容是否跟商户当前所持有的微信支付平台证书的序列号一致。若不一致,请重新获取证书。否则,签名的私钥和证书不匹配,将验证失败。
- 为了确保商户系统的安全,微信支付会在极少数应答或通知回调中生成错误签名,以探测商户系统是否正确地验证了签名。 商户系统不应对探测流量进行特殊处理,而应将其视为正常的应答或通知回调,并对其签名进行验证。 在排查问题时,您可以通过查看签名值中的 WECHATPAY/SIGNTEST/ 前缀快速判断是否为探测流量。所有用于探测目的的签名值都会包含此前缀。
- 若参数正确、工具验签通过,但响应和回调依然验签失败:请检查代码中实际验签使用的参数(body是否有转义、乱码)、微信平台证书是否与签名工具中一致。
# 4 生成签名示例
除了验签,我们还可以通过签名/验签工具,直接生成对应明文的签名值。因为SHA256和RSA的算法都是固定的,所以使用同样的私钥对同样的明文(签名串)计算后得到的签名值是相同的。
- 验证证书匹配关系。
我们可以用私钥签名后生成签名值,公钥验签,根据结果判断使用的签名证书apiclient_key.pem(私钥)和验签证书apiclient_cert.pem(公钥)是否匹配,验证代码计算签名的过程是否正确。 - 校验请求签名的正确性。
工具生成后的签名值,可以用于直接去请求接口,调试校验自己代码请求时使用的各参数和工具中计算签名时使用的各参数是否一致。
# 4.1 验证证书匹配关系
对于有多套有效商户API证书的商户,请求接口时签名私钥文件apiclient_key.pem和证书序列号容易传错,但是无法确定自己使用的是否为同一套公私钥,可以使用该工具进行验证。
也可使用 证书查看工具 (opens new window) 查看商户API证书公钥apiclient_cert.pem的证书序列号进行辅助确认。
# 4.2 校验请求签名的正确性
您可以在工具上填入指定的参数,生成请求签名,以及校验请求签名的正确性。生成签名示例参考 请求参数里带Body参数(包体参数),如何计算签名
- 按接口规则构建明文/验签串,通过签名/验签工具用apiclient_key.pem私钥证书生成签名signature
- 再根据Authorization的组成规则,结合验签串的内容和生成的signature,构建一个Authorization字符串,可以直接使用Authorization去请求接口。
注意
- 工具生成的签名值一定是对应apiclient_key.pem和明文参数生成的正确签名值。如果代码仍然报错,需要自己检查签名过程中使用的参数是否和工具中保持一致,如signature和Body是否一致,如参数大小写等。
- 空格、格式、转义、解析、或者环境等原因改变都会导致最终请求时微信支付侧的验签失败。