最近支付宝给个人账号转账(接口alipay.fund.trans.toaccount.transfer)发现每天额度只有1万,超过了就全提示超过额度打款失败,问客服说是需要升级到新接口才能恢复额度。
新接口:alipay.fund.trans.uni.transfer(单笔转账接口)
试着改接口,改参数提示isv.app-cert-not-exist,发现之前的公钥验证需要改成公钥证书,改了之后只有7天时间老的公钥会失效,需要全部升级成公钥证书。
1. 如何生成公钥证书
在支付宝开放平台接口加密方式修改为公钥证书,然后下载支付宝公钥(如下图),文件名分别为:alipayRootCert.crt,alipayCertPublicKey_RSA2.crt,appCertPublicKey_(appid).crt

2. 自行生成签名
说明: 公钥证书方式下,开发者发送给开放平台网关请求参数中,需携带 应用公钥证书 SN(app_cert_sn)、支付宝根证书 SN(alipay_root_cert_sn),若不携带这两个参数,网关会拒绝请求(具体问题请参考 常见问题 Q9-12)。SN 值是通过解析 X.509 证书文件中签发机构名称(name)以及内置序列号(serialNumber),将二者拼接后的字符串计算 MD5 值获取,可参考开放平台 SDK 源码中 AlipaySignature.getCertSN 实现 app_cert_sn 的提取。
2.1 获取alipay_root_cert_sn
以为获取公钥证书SN很简单,试了N回都是isv.invalid-alipay-root-cert-sn,最后发现坑不少啊。
alipayRootCert里其实有4个证书,需要手动拆成4个文件,然后读取需要信息,其中有两个的dotted_string是1.2.840.113549.1.1.5才是我们需要的证书,最后计算出md5,以下划线_拼接起来就是我们需要的alipay_root_cert_sn
pip install pyOpenSSL
>>> with open("/Users/whoami/root4.crt", "r") as fp:
... crt_data = fp.read()
...
>>> cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, crt_data)
>>> a = cert.to_cryptography()
>>> a.signature_algorithm_oid.dotted_string
'1.2.840.113549.1.1.5'
>>> a.subject
<Name(C=CN,O=iTrusChina,OU=China Trust Network,CN=iTrusChina Class 2 Root CA - G3)>
>>> a.serial_number
957904914256988596466594905800520123123
>>> b = 'CN=iTrusChina Class 2 Root CA - G3,OU=China Trust Network,O=iTrusChina,C=CN'
>>> b += '957904914256988596466594905800520123123'
>>> hashlib.md5(b.encode()).hexdigest()
'02941eef3187dddf3d3b83462e123456'
2.2 获取app_cert_sn
>>> with open("/Users/whoami/appCertPublicKey_appid.crt", "r") as fp:
... crt_data = fp.read()
...
>>> cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, crt_data)
>>> certIssue = cert.get_issuer()
>>> a = cert.to_cryptography()
>>> b = 'CN=' + certIssue.CN + ',' + 'OU=' + certIssue.OU + ',' + 'O=' + certIssue.O + ',' + 'C=' + certIssue.C + str(cert.get_serial_number())
>>> hashlib.md5(b.encode()).hexdigest()
'a7ac269d14de3e3601871f55162fecba'
为何这里获取b的方式跟alipay_root_cert_sn的不一样?我开始时是这么取的,直接报isv.app-cert-not-exist,试了很多次发现这么取值接口才pass。
好了,花了一天半,转账终于成功了
啥?验签失败了,验签公钥换成alipayCertPublicKey_RSA2.crt,OK了
3. 参考链接如下,感谢你们:
同时感谢支付宝在线技术支持的耐心帮助
网友评论