自行实现验签

如果未使用支付宝开放平台SDK,需要自行实现验签过程。

同步返回和异步通知报文格式及验签方法有所区别。

同步返回验签

开发者只对支付宝返回的json中xxx_response的值做验签(xxx代表接口名)。

xxx_response的json值内容需要包含首尾的“{”和“}”两个尖括号,双引号也需要参与验签,如果字符串中包含“http://”的正斜杠,需要先将正斜杠做转义,默认打印出来的字符串是已经做过转义的。建议验签不通过时将正斜杠转义一次后再做一次验签。

如当面付扫码支付获取二维码的返回内容为:

{"alipay_trade_precreate_response":{"code":"10000","msg":"Success","out_trade_no":"6141161365682511","qr_code":"https:\/\/qr.alipay.com\/bax03206ug0kulveltqc80a8"},"sign":"VrgnnGgRMNApB1QlNJimiOt5ocGn4a4pbXjdoqjHtnYMWPYGX9AS0ELt8YikVAl6LPfsD7hjSyGWGjwaAYJjzH1MH7B2/T3He0kLezuWHsikao2ktCjTrX0tmUfoMUBCxKGGuDHtmasQi4yAoDk+ux7og1J5tL49yWiiwgaJoBE="}

则待验签字段为:

{"code":"10000","msg":"Success","out_trade_no":"6141161365682511","qr_code":"https:\/\/qr.alipay.com\/bax03206ug0kulveltqc80a8"}

同时取出签名值sign:

VrgnnGgRMNApB1QlNJimiOt5ocGn4a4pbXjdoqjHtnYMWPYGX9AS0ELt8YikVAl6LPfsD7hjSyGWGjwaAYJjzH1MH7B2/T3He0kLezuWHsikao2ktCjTrX0tmUfoMUBCxKGGuDHtmasQi4yAoDk+ux7og1J5tL49yWiiwgaJoBE=

调用验签函数:使用各自语言对应的SHA256WithRSA(对应sign_type为RSA2)或SHA1WithRSA(对应sign_type为RSA)签名验证函数,传入待验签字段、支付宝公钥、签名内容(sign),验签方法(signType)进行验签,根据返回结果判定是否验签通过。

异步通知验签

某些情况下(比如扫码支付成功时),支付宝会给商户发送异步通知。

如果某商户设置的通知地址为https://api.xx.com/receive_notify.htm,对应接收到通知的示例如下:

https://api.xx.com/receive_notify.htm?total_amount=2.00&buyer_id=2088102116773037&body=大乐透2.1&trade_no=2016071921001003030200089909&refund_fee=0.00&notify_time=2016-07-19 14:10:49&subject=大乐透2.1&sign_type=RSA2&charset=utf-8&notify_type=trade_status_sync&out_trade_no=0719141034-6418&gmt_close=2016-07-19 14:10:46&gmt_payment=2016-07-19 14:10:47&trade_status=TRADE_SUCCESS&version=1.0&sign=kPbQIjX+xQc8F0/A6/AocELIjhhZnGbcBN6G4MM/HmfWL4ZiHM6fWl5NQhzXJusaklZ1LFuMo+lHQUELAYeugH8LYFvxnNajOvZhuxNFbN2LhF0l/KL8ANtj8oyPM4NN7Qft2kWJTDJUpQOzCzNnV9hDxh5AaT9FPqRS6ZKxnzM=&gmt_create=2016-07-19 14:10:44&app_id=2015102700040153&seller_id=2088102119685838&notify_id=4a91b7a78a503640467525113fb7d8bg8e

验签流程:

1.在通知返回参数列表中,除去sign、sign_type两个参数外,凡是通知返回回来的参数皆是待验签的参数。

TIPS:生活号异步通知组成的待验签串里需要保留sign_type参数。

2.将剩下参数进行url_decode, 然后进行字典排序,组成字符串,得到待签名字符串:

body=大乐透2.1&buyer_id=2088102116773037&charset=utf-8&gmt_close=2016-07-19 14:10:46&gmt_payment=2016-07-19 14:10:47&notify_time=2016-07-19 14:10:49&notify_type=trade_status_sync&out_trade_no=0719141034-6418&refund_fee=0.00&subject=大乐透2.1&total_amount=2.00&trade_no=2016071921001003030200089909&trade_status=TRADE_SUCCESS&version=1.0

3.将签名参数(sign)使用base64解码为字节码串。

4.使用RSA的验签方法,通过签名字符串、签名参数(经过base64解码)及支付宝公钥验证签名,根据返回结果判定是否验签通过。

可以参考开放平台SDK源码中的AlipaySignature.rsaCheckV1方法:

/**
@param params 参数列表(包括待验签参数和签名值sign) key-参数名称 value-参数值
@param sign 签名值
@param publicKey 验签公钥
@param charset 验签字符集
@param signType 验签方法
**/
boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey,String charset,String signType)

工具演示异步通知验签过程:

支付宝签名验签工具可以一键生成密钥,并提供签名,验签等功能,此处演示异步通知验签过程。

1. 打开签名工具,切换到“验签”页 ,界面显示如下:

2. “公钥”框请输入“支付宝公钥”。

“报文”内容为支付宝开放平台通知商户网关的内容,剔除网关地址。参考输入框中样例。

选择对应“字符集”及“签名方式”,点击“开始验签”后,工具会从报文中提取出签名值(sign参数),并对报文做格式处理生成最终验签的字符串(“待验签串”):

3. 点击“查看验签详细步骤”,可以了解生成待验签串的详细步骤。

onlineServer