支付宝支付的服务端接入流程
支付宝支付的服务端接入流程
0、写在前面的话
支付宝支付官网上服务端没有提供C++语言的SDK,所以如果要用C++接入的话要自己实现签名验证,醉了,当然是用Java了。。。官网上的流程不清不楚的,所以自己整理了一下。
1、RSA**
应用公钥:
商户自己生成的RSA公钥,需要上传到支付宝平台,以便支付宝验证交易是否由商户发起的
应用私钥:
商户自己生成的RSA私钥,商户用该私钥对请求字符串进行加签
支付宝公钥:
支付宝的RSA公钥,商户使用该公钥验证结果是否由支付宝返回的
生成**以及签名教程,参考此处
简述:利用支付宝提供的工具生成一对RSA**(应用公钥、应用私钥),上传应用公钥到支付宝上获取到支付宝公钥,使用应用私钥对订单请求内容进行签名,使用支付宝公钥验签包括同步返回验签(客户端处理)、异步通知验签(服务器端处理)。
2、功能流程
1.客户端将订单信息以请求参数发送给服务端,服务端对请求参数使用应用私钥进行签名,再返回给客户端。
客户端请求参数的格式:按照key=value&key=value方式拼接的未签名原始字符串,如
app_id=2015052600090779&biz_content={"timeout_express":"30m","product_code":"QUICK_MSECURITY_PAY","total_amount":"0.01","subject":"1","body":"我是测试数据","out_trade_no":"IQJZSRC1YMQB5HU"}&charset=utf-8&format=json&method=alipay.trade.app.pay¬ify_url=http://domain.merchant.com/payment_notify&sign_type=RSA2×tamp=2016-08-25 20:26:31&version=1.0
请求参数说明参考此处。-
参数说明:
- notify_url:支付宝服务器主动通知商户服务器里指定的页面http/https路径。
- 请求参数的sign字段请务必在服务端完成签名生成(不要在客户端本地签名)。
- 支付请求中的订单金额total_amount,请务必依赖服务端,不要轻信客户端上行的数据(客户端本地上行数据在用户手机环境中无法确保一定安全)。
服务端使用开放平台SDK接入时,开放平台SDK封装了签名实现,只需在创建DefaultAlipayClient对象时,设置请求网关(gateway),应用id(app_id),应用私钥(private_key),编码格式(charset),支付宝公钥(alipay_public_key),签名类型(sign_type)即可,报文请求时会自动进行签名。如果未使用开放平台SDK,需要自行实现签名过程,参考此处。
2、客户端发送支付请求给支付宝SDK后,支付宝SDK对请求支付数据处理完成后,会将结果同步反馈给客户端。
3、服务端收到支付宝SDK发过来的异步通知,对通知内容使用支付宝公钥进行验证并返回。
异步通知 :App支付产生的交易,支付宝会根据原始支付API中传入的异步通知地址notify_url,通过POST请求的形式将支付结果作为参数通知到app服务端。如客户端设置的通知地址为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¬ify_time=2016-07-19 14:10:49&subject=大乐透2.1&sign_type=RSA2&charset=utf-8¬ify_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¬ify_id=4a91b7a78a503640467525113fb7d8bg8e
对通知内容使用支付宝公钥进行验证签名,支付宝的服务端SDK中封装了签名&验签、HTTP接口请求等基础功能,如果要自行验签,参考异步返回结果的验签。
- 验证签名正确后,必须校验通知数据的正确性,数据正确则返回success
- 商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号
- 判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额)
- 校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)
- 验证app_id是否为该商户本身。
- 上述1、2、3、4有任何一个验证不通过,则表明本次通知是异常通知,务必忽略。在上述验证通过后商户必须根据支付宝不同类型的业务通知,正确的进行不同的业务处理,并且过滤重复的通知结果数据。在支付宝的业务通知中,只有交易通知状态为TRADE_SUCCESS或TRADE_FINISHED时,支付宝才会认定为买家付款成功。
-
注意:同步返回的数据,客户端可以在服务端验证,验证通过后,可以认为本次用户付款成功。由于同步通知和异步通知都可以作为支付完成的凭证,且异步通知支付宝一定会确保发送给商户服务端。为了简化集成流程,商户可以将同步结果仅仅作为一个支付结束的通知(忽略执行校验),实际支付是否成功,完全依赖服务端异步通知。
必须保证服务器异步通知页面(notify_url)上无任何字符,如空格、HTML标签、开发系统自带抛出的异常提示信息等;
- 服务器间的交互,不像页面跳转同步通知可以在页面上显示出来,这种交互方式是不可见的;
- 程序执行完后必须打印输出“success”(不包含引号)。如果商户反馈给支付宝的字符不是success这7个字符,支付宝服务器会不断重发通知,直到超过24小时22分钟。一般情况下,25小时以内完成8次通知(通知的间隔频率一般是:4m,10m,10m,1h,2h,6h,15h);
- 程序执行完成后,该页面不能执行页面跳转。如果执行页面跳转,支付宝会收不到success字符,会被支付宝服务器判定为该页面程序运行出现异常,而重发处理结果通知;
- 该方式的作用主要防止订单丢失,即页面跳转同步通知没有处理订单更新,它则去处理;