tencent cloud

APIv3证书签名
最后更新时间:2025-08-20 17:56:08
APIv3证书签名
最后更新时间: 2025-08-20 17:56:08

概述

在 superapp 支付 API 的所有请求应答场景、接口回调场景、调起支付场景,开发者都需要进行签名验签。

什么时候需要签名?如何签名?

请求 superapp 支付接口

商户调用 superapp 支付接口的时候需要用到商户 API 证书构造请求签名,且根据请求参数类型的不同,签名方式有所差异,请参考以下的操作指引说明。

如何构造请求签名

获取商户 API 证书
构造请求签名需要使用商户 API 证书
此处我们已经拿到了商户 API 证书,并且将对应的商户 API 私钥 apiclient_key.pem,保存在了本地。
商户号:202003191046
证书序列号:526807E51G82219FOC2D5D3E6AB8ED1S8SDS8787AS
API 证书私钥:您需要将以下文件保存为 pem 格式,为了避免大家和自己的真实的公私钥混淆,此处将其保存为了 apiclient_test_key.pem。
注意:
以下只是一个示例密钥,实际上并不可用。
-----BEGIN PRIVATE KEY-----\\nMIIEuwIBADALBgkqhkiG9w0BAQEEggSnMIIEowIBAAKCAQEA1WFrv7DQ2FeBB2ZR\\n/bh+W/38+Rgcs/yxTdd0/9r5DWYvB6Lhc0pqaNnrmZUc+Uih6CELe1K3AAvg0+6A\\njfcLV/aqNx4xdwqfLt2P1F7TsyGJZWMe5OoPmwzel8zRpGcqY/WdmevEEFqmIc/r\\nWVa1fOCM9eIzP9QQbgT7tKXa/ixi5B5y8B0pShYJuyE2M8GimvbDbnaatMQJlwFP\\nO9fxU7cRZBdkDcUB8dMxl2ZfTHZjEC6ypR4Ux5vnPIB9hH7qHFbc6W9ueEfVRTk3\\neeoVnbmZJHliWBqtv89Tm0uMk+fD2ZayRA+TuwFajt0NTcbnM6kM0cuuyEyd7bnE\\nWFKuAwIDAQABAoIBACS+8CVEt9Jpz0iM8FW3Ldt9s9DZvCeqvoXfMsDU3srV7Adu\\nn1CRYh3IWXBLY3/yaB9ngWitZ+JUKVWV3wGTp5pwWgO/6VjMtXkGorw50E8q2VRi\\na3GUdTeIUdTmarvbIEuygn99QHhog++StL7f1cU5jkzRtW2qgWHQ7d/AKCRZA+R1\\nnUwNaQHdz2Fn5a5cQsULgNCf0Rfn4MxgsvGl3ZVcJVUiumEDfV2TDcLz2wEaWvTo\\nOhD6bN+Ug0LuucmuwC9FzR7DUNxWxmQpAdPMbAfku47K9ARqHfUjNXtBUktGdo6x\\nfmdm/fNTodSzziu4Sn87iQU0R7VU8TT2Wx1l/jECgYEA3/3yqEWSwjCY/hs+rq9O\\nrhF4vVyd8az7X+KCKiYZl51oRiRSso8dWvuVixpx3ZW8vp81K2eq9h6BmuePMVZK\\nH8PV8LbNbuLUn/cTREo7JcT0jUFSfwyMiu6De23fyCSb3fM4EFdjuywTn0d+RIr5\\nlnurFc8mRWTTX0E+kht7K50CgYEA899JYDMqs7GU+Gg8vNEHL3ux4VIGWaV0LPFj\\nn4UNn0aT3t0M+OgWm9K1tCSi5PPkmkAt8wCOtKPmSiq1CQeWa8HX+JHkMiEYO6Ki\\nHecXmZlUr/yXMhCTkkxwNsFAFxP1KYOm91+ka6w+l7/qcjan+WZsYT2XpSTx0LV5\\nPma8Hh8CgYABUNuZE3eOPnzXmU9f9VWv/hhIfH/NCKgdYxZCqyChXGJdbx8xP1f7\\nzdiODaS3mYaXVBYa4CwH8BvwzgVwU8Jxt1PNazV/vkNjgS8SyqDYUvTg045pgqhc\\ntJP/KKEU6uojfqdIqUrDsbmXyPK78lkPAkD6CtJ9u97mA1sbvp+VnQKBgFp41qba\\ntJfPZJ23RfkibtD9yaL2pCZzzCK0NqpCWShirY77YMmiiGishf5brRbVKFTVRHan\\nGUoIl/Gh4GGGMBav5ihwL0Etp+jPz+baCZZRHOrhAVJwdd7LfsHBdb5aCBSro7CY\\nCc5sKxhu+VH/1tceWUzF5dE9YHx2JpGw2U8vAoGBAL2Wp4S2dA+zKfhX7QOCLl3q\\nXYujhL1dgZBaDonWtOrn7llLSqaryD/TH8C6QRVrsXpLdwuSLx7tzQnG81ptO49Q\\nuCVFbGF5RwCf8Wq8OlYuJ/MS9GsE+Ux2EYVX3DD5zV6gtN11c7NsTEan9fRpgZjt\\n2kuvKl1oec/Rh8fbmqid\\n-----END PRIVATE KEY-----
构造签名串
我们希望商户的技术开发人员按照当前文档约定的规则构造签名串。superapp 支付会使用同样的方式构造签名串。如果商户构造签名串的方式错误,将导致签名验证不通过。下面先说明签名串的具体格式。
签名串一共有5个部分,每一行为一个参数。结尾以\\n(换行符,ASCII 编码值为0x0A)结束,包括最后一行。如果参数本身以\\n结束,也需要附加一个\\n。
HTTP请求方法\\n
URL\\n
请求时间戳\\n
请求随机串\\n
请求报文主体\\n
1. 请求参数里带 Path 参数
以查询订单接口为例
第一步,获取 HTTP 请求的方法
GET
第二步,获取请求的绝对 URL
查询订单接口的 URL 为/v3/pay/transactions/out-trade-no/{out_trade_no},path里面带了参数 out_trade_no,这里需要填上实际的商户订单号,例如1217752501201407033233368018
/v3/pay/transactions/out-trade-no/1217752501201407033233368018
第三步,获取发起请求时的系统当前时间戳
即格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数,作为请求时间戳。superapp 支付会拒绝处理很久之前发起的请求,请商户保持自身系统的时间准确。
date +%s
1554208460
第四步,生成一个请求随机串
E6F165123B4E32D8D0D6
第五步,获取请求中的请求报文主体(request body)
对于该接口来说,请求报文主体是一个空串,只需要附加一个 \\n 即可
第六步,按照前述规则构造的请求签名串
POST\\n
/v3/pay/transactions/jsapi\\n
1554208460\\n
E6F165123B4E32D8D0D6\\n
{"appid":"wxd678efh567hg6787","mchid":"1230000109","description":"Image","out_trade_no":"1217752501201407033233368018","notify_url":"https://www.weixin.qq.com/wxpay/pay.php","amount":{"total":100,"currency":"USD"},"payer":{"openid":"oUpF8uMuAJO_M2pxb1Q9zNjWeS6o"}}\\n
2. 请求参数里带 Body 参数
以下单接口为例
第一步,获取 HTTP 请求的方法
POST
第二步,获取请求的绝对 URL,请注意需要去除域名部分
/v3/pay/transactions/jsapi
第三步,获取发起请求时的系统当前时间戳
即格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数,作为请求时间戳。superapp 支付会拒绝处理很久之前发起的请求,请商户保持自身系统的时间准确。
date +%s
1554208460
第四步,生成一个请求随机串
E6F165123B4E32D8D0D6
第五步,获取请求中的请求报文主体(request body)
您可以将所有参数放在一行,对应的发起签名请求的时候 body 参数也应该放在一行。
您也可以将参数以多行计算签名,对应发起请求的时候 body 参数也要是多行。即您计算签名时 body 是怎么样的,您发起请求时 body 就应该是怎么样的。
这里以将所有参数放到一行做演示
{"appid":"wxd678efh567hg6787","mchid":"1230000109","description":"describe","out_trade_no":"1217752501201407033233368018","notify_url":"https://${domain}/wxpay/pay.php","amount":{"total":100,"currency":"USD"},"payer":{"openid":"oUpF8uMuAJO_M2pxb1Q9zNjWeS6o"}}
第六步,按照前述规则构造的请求签名串
POST\\n
/v3/pay/transactions/jsapi\\n
1554208460\\n
E6F165123B4E32D8D0D6\\n
{"appid":"wxd678efh567hg6787","mchid":"1230000109","description":"describe","out_trade_no":"1217752501201407033233368018","notify_url":"https://${domain}/wxpay/pay.php","amount":{"total":100,"currency":"USD"},"payer":{"openid":"oUpF8uMuAJO_M2pxb1Q9zNjWeS6o"}}
当请求报文主体是一个空串时,只需要附加一个\\n即可。
3. 请求参数里带 Query 参数
以商户订单号查询订单
第一步,获取 HTTP 请求的方法
GET
第二步,获取请求的绝对 URL,请注意需要去除域名部分
拼接您的 Query(查询参数),假设您的 query 参数如下
limit=52offset=103authorized_data={"business_type":"FAVOR_STOCK", "stock_id":"2433405"}4partner={"type":"APPID","appid":"wx4e1916a585d1f4e9","merchant_id":"2480029552"}
(1)先对 authorized_data 参数和 partne 参数做个 URL encodeURL
limit=52offset=103authorized_data%3D%7B%22business_type%22%3A%22FAVOR_STOCK%22%2C%20%22stock_id%22%3A%222433405%22%7D4partner%3D%7B%22type%22%3A%22APPID%22%2C%22appid%22%3A%22wx4e1916a585d1f4e9%22%2C%22merchant_id%22%3A%222480029552%22%7D
(2)拼接您的请求 URL,查询参数需要在末尾加'?'和对应的查询字符串,多个字符串之间用&符号链接(请注意以下 URL 是在一行,因为排版原因可能看起来像换行,实际数据在一行)
/v3/pay/transactions/out-trade-no/112233445566?limit=5&offset=10&authorized_data%3D%7B%22business_type%22%3A%22FAVOR_STOCK%22%2C%20%22stock_id%22%3A%222433405%22%7D&partner%3D%7B%22type%22%3A%22APPID%22%2C%22appid%22%3A%22wx4e1916a585d1f4e9%22%2C%22merchant_id%22%3A%222480029552%22%7D
第三步,获取发起请求时的系统当前时间戳
即格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数,作为请求时间戳。superapp 支付会拒绝处理很久之前发起的请求,请商户保持自身系统的时间准确。
date +%s
1554208460
第四步,生成一个请求随机串
E6F165123B4E32D8D0D6
第五步,获取请求中的请求报文主体(request body)
请求报文主体是一个空串,只需要附加一个\\n即可。
第六步,按照前述规则构造的请求签名串
当请求报文主体是一个空串时,只需要附加一个\\n即可。

GET\\n /v3/marketing/partnerships?limit=5&offset=10&authorized_data%3D%7B%22business_type%22%3A%22FAVOR_STOCK%22%2C%20%22stock_id%22%3A%222433405%22%7D&partner%3D%7B%22type%22%3A%22APPID%22%2C%22appid%22%3A%22wx4e1916a585d1f4e9%22%2C%22merchant_id%22%3A%222480029552%22%7D\\n 31554208460\\n E6F165123B4E32D8D0D6\\n \\n
计算签名值
绝大多数编程语言提供的签名函数支持对签名数据进行签名。强烈建议商户调用该类函数,使用商户私钥对待签名串进行 SHA256 with RSA 签名,并对签名结果进行 Base64 编码得到签名值。
请注意处理单双引号转义问题,第二行的外层是单引号,则里面的参数不需要转义,如果第二行最外层使用了双引号,则 body 参数的双引号都需要转义。
1. 设置 HTTP 头
请求通过 HTTP Authorization 头来传递签名。Authorization 由认证类型和签名信息两个部分组成。
下面我们使用命令行演示如何生成签名。
Authorization: 认证类型 签名信息
具体组成为:
2. 认证类型,目前为 WECHATPAY2-SHA256-RSA2048
3. 签名信息,参数参考开发必要参数说明
发起请求的商户(包括直连商户、服务商或渠道商)的商户号 mchid。
商户 API 证书序列号【serial_no】,用于声明所使用的证书。
请求随机串 nonce_str,和您上面构造签名串的随机串要保持一致。
时间戳 timestamp,和您上面构造签名串的时间戳要保持一致。
签名值 signature,上面算出来的签名值。
注意:
以上五项签名信息,无顺序要求。
Authorization 头的示例如下:(注意,示例因为排版可能存在换行,实际数据应在一行)
Authorization: WECHATPAY2-SHA256-RSA2048 mchid="1900007291",nonce_str="593BEC0C930BF1AFEB40B4A08C8FB242",signature="gEuexJ547PHFV77TQ6eiE4tphVYfWfUe1Wc2dBmVnoMYU2rl/M4zhw+b3vBhuMw6AC7pteNkryLA7UWU2h+umo0OdSuuLm1++O3NckQPCSfm6dypsjn4GYm84KMqXWFrhFmyxEwIdEJDr3w1UYfxOcu55OQupfLkrt/ZzuOspnliJFrPzGQFUk7lGqMMtpz3EfbDUNxnVsHblORg3hVmuYNmbGWnS2ovU30Y2Q+iKFDxzkaXBk8LTy6HzvxizRo6Q+J4SVM7O0hKXfgo1QdI68kpzNULb3EVBXlhTyPUzhkHzzLxECL1qHl3HH2hEv8++C+4wBlsagF3j/O6PABojA==",timestamp="1554208460",serial_no="408B07E79B8269FEC3D5D3E6AB8ED163A6A380DB"

最终我们可以组一个包含了签名的 HTTP 请求了。
(1)请注意第六行的 body 参数必须在一行,不能换行,因为签名计算签名时 body 就是以一行来计算签名的,这里发起请求时需要和签名时的保持一致。
(2)请注意 Authorization的timestamp="1554208460",serial_no="408B07E79B8269FEC3D5D3E6AB8ED163A6A380DB" 必须和您计算签名是传入的值是一致的。
(3)此处只是一个示例,用于大家参考计算的格式,由于示例密钥本身是不可用的,因此以下请求并不真正可用
curl -X POST \\
https://${domain}/openserver/v3/pay/transactions/jsapi \\
-H 'Authorization: WECHATPAY2-SHA256-RSA2048 mchid="202003191046",nonce_str="E6F165123B4E32D8D0D6",signature="gEuexJ547PHFV77TQ6eiE4tphVYfWfUe1Wc2dBmVnoMYU2rl/M4zhw+b3vBhuMw6AC7pteNkryLA7UWU2h+umo0OdSuuLm1++O3NckQPCSfm6dypsjn4GYm84KMqXWFrhFmyxEwIdEJDr3w1UYfxOcu55OQupfLkrt/ZzuOspnliJFrPzGQFUk7lGqMMtpz3EfbDUNxnVsHblORg3hVmuYNmbGWnS2ovU30Y2Q+iKFDxzkaXBk8LTy6HzvxizRo6Q+J4SVM7O0hKXfgo1QdI68kpzNULb3EVBXlhTyPUzhkHzzLxECL1qHl3HH2hEv8++C+4wBlsagF3j/O6PABojA==",timestamp="1554208460",serial_no="408B07E79B8269FEC3D5D3E6AB8ED163A6A380DB"' \\
-H 'Accept: application/json' \\
-H 'Content-Type: application/json' \\
-d '{"appid":"mp1bfa1hnwvaluqb","mchid":"202003191046","description":"goods desc","out_trade_no":"84ssadasd125e32463542341342","notify_url":"https://mini.demo.com/pay/callback:","amount":{"total":100,"currency":"USD"},"payer":{"openid":"oae60e19213a17344EhDZBb25849"}}'


本页内容是否解决了您的问题?
您也可以 联系销售 提交工单 以寻求帮助。

文档反馈