alipay.trade.app.pay


阿里金服 app支付 服务端(PHP)接口开发

summary:
开放平台>文档中心>快速接入 大致了解支付流程.

1.客户端选购商品, 提交商品信息到服务端(Client->[{商品1,1件,¥100},{商品1,1件,¥100}]->Server)
2.服务端订单入库生成订单号反馈给客户端(Server->[2333333,¥200]->Client), 更详细描述是: 服务端生成订单后 调用(支付宝服务端)SDK进行RSA2(or RSA)加密
3.客户端调用(支付宝客户端)SDK携带一些参数(app_id, ..., notify_url, ..., sign 等10个参数)请求支付宝服务器
4.用户支付完成, 支付宝服务器__异步__通知应用服务器(HTTP(or HTTPS)访问http://domain/notify_url), 服务器做验证判断支付是否成功并处理业务逻辑
5.支付完成后, 回到APP, APP收到通知, 访问服务器接口验证支付是否成功.

按照官方Docs来

1
2
3
4
5
6
7
8
9
10
11
STRUCTION:
- alibaba_pay.php // app支付接口, 用于将加签(RSA2加密)后的订单信息返回给app(, 之后由app将信息通过app-sdk发送给支付宝, 支付包进行支付处理, 将处理结果同步返回app端并异步通知服务端[即`setNotifyUrl`]).
- alipay-sdk-PHP-20170307171629 // alibaba server pay sdk
- AopSdk.php // sdk 调用入口文件
- aop
- AopClient.php // 这里修改了sdk部分代码, 1: 去掉了sdk中返回的`alipay_sdk`参数, 2: sdk在格式化时间戳时将空格转义为+号, 这里通过rawurlencode偷偷换成%20
- api
- ext
- app_v2.0
- receive_notify.php // 支付宝 异步通知 服务器的地址

开发中遇到的问题

  • ALI3171 交易状态错误
    原因之一: 订单信息重复. 在开发过程进行签名校对的时候, 把订单信息写死了, 后续开发需要更换新订单.

  • ALI38173
    原因之一: 发给app(android)的字符串app端是不需要url_decode的, 直接转给支付宝.

  • ALI40247
    原因之一: 添加了APP支付功能, 但是未签约.

  • 生产环境(PHP5.3, A) 无法运行 app支付SDK
    方案B: 另开一台(PHP5.5+, B)服务器, 生产环境(不处理app支付)仅将请求转发给B并将请求结果返回. 类似于反向代理, 对移动端来说, 他们仍然访问的是A(B对他们来讲是不存在的).

注意点

1
2
3
4
5
6
7
8
9
10
11
12
0x00. 几个概念要先明确
1. 应用服务商(即我们)是有一个RSA秘钥对的(简称Y), 需要告知支付宝Y-公钥.
2. Y-私钥用来加密订单信息, 这样支付宝用Y-公钥解密的时候可以__确认我是就我__.
3. 支付宝也有一个RSA秘钥对(简称Z), 需要告知我们Z-公钥.
4. Z-私钥用来加密支付宝返回给我们的订单支付信息, 这样我们用Z-公钥解密的时候可以__确认这货确实是支付宝, 不是骗子__.
0x01. 当前版本(alipay-sdk-PHP-20170307171629) 需要PHP5.5+, 开发必须要用公网地址
0x02. 服务端SDK已经封装的很简单了, 不用关心什么10个参数必须有还必须字母曾序排列, url_encode转码必须是所有一级value什么的.
0x03. RSA签名验签工具 用来生产RSA2秘钥对, 加签验签. 我们选的生成秘钥方式是PKCS1 2048
0x04. 调试过程中没少遇到 ALI38173, ALI40247. 开发文档上的排查思路并没有多大用处.
0x05. 支付流程(沙箱模式)测试完成. 确认问题为: 发给app(android)的字符串app端是不需要url_decode的, 直接转给支付宝就可以了
0x06. 沙箱模式 调式 app支付 仅支持android(不支持iOS)
0x07. 线上测试 需要 在 管理中心 > 开发者中心 > 我的应用 > APP支付(签约, "状态"为`生效`), 并且 应用状态 由`开发中` 经 `提交审核` 至 `应用上线` 方可.


rsa-tool-rule-1
rsa-tool-rule-2


技术点

非对称加密RSA

1
2
m^1 % n === m // step 1
1 === ed // step 2, e为公钥, d为私钥

附录:

网上查询的一些概念, 不一定准确, 参考一下.
---

- 0x00 交易系统 vs 支付系统: 交易是生成订单;支付是对订单进行付款
- 0x01 支付分类
    - 单次支付: 支付验证要素(卡号、密码、手机号、CVN2、CVV2等),结合安全认证(例如短信验证码),让持卡人完成互联网支付。
    - 认证支付: 指用户在绑卡时,将卡信息提供给电商。这样在支付时,用户无需再输入这些信息,由电商在服务器侧保留用户的账户信息,比如身份证号,卡号,手机号。在用户支付时,无需再输入这些内容,最多就提供个密码或者校验码,就可以完成支付。这基本不会打断用户的使用体验,所以也是电商喜欢的支付方式。但认证支付最让人诟病的就是安全性。一方面需要向电商暴露个人信息,一旦被窃取,资金就容易被盗走。还有在手机上执行支付,一旦手机丢失,窃取者就可以轻而易举的使用或者转移资金。
    - 快捷支付: 快捷支付和认证支付类似,不同点在于绑卡之后,有些银行接口会返回token,后续使用token来作为支付凭证,无需提供卡号信息,这样电商也不需要本地保留卡号了。目前主要是银联有提供token接口。
    - 网银支付: 相对来说,网银支付要安全很多。网银支付是由银联或者银行提供支付界面,用户必须在页面上输入卡号,密码等验证信息才可以执行支付。大部分银行还要求用户使用U盾或者其它安全硬件。但安全和易用永远是个矛盾。网银使用会打断用户体验,增加用户使用难度。对使用硬件加密的支付,不可能天天带着U盘跑。另外网银主要用在web端,在手机端,嵌入网银页面,还是比较难看的
- 0x02 蚂蚁金服 沙箱模式:
    
1
2
3
4
5
6
7
8
9
10
11
商家信息
    商家账号 xxxxxxxxxx@sandbox.com
    商户UID  20880123456789ab
    登录密码 111111
买家信息
    买家账号 yyyyyyyyyy@sandbox.com
    登录密码 111111
    支付密码 111111
    用户名称 沙箱环境
    证件类型 身份证(IDENTITY_CARD)
    证件号码 0123456789abcdefff
- 0x03 蚂蚁金服 - 当面付 - 支付宝收款 - app支付 - 手机网站支付 异步通知POST数据 --- // 格式化 POST参数, 沙箱模式 { "total_amount": "0.01", "buyer_id": "2088102170XXXXXX", "trade_no": "2017041321001004770200YYYYYY", "body": "cece_body", "notify_time": "2017-04-13 10:29:35", "subject": "cece_subject", "sign_type": "RSA2", "buyer_logon_id": "scc***@sandbox.com", "auth_app_id": "2016080400ZZZZZZ", "charset": "UTF-8", "notify_type": "trade_status_sync", "invoice_amount": "0.01", "out_trade_no": "cece2017032813021492LLLLLL", "trade_status": "TRADE_SUCCESS", "gmt_payment": "2017-04-13 10:29:34", "version": "1.0", "point_amount": "0.00", "sign": "G\/VfEEogUZptu11pJhM6EQdWZnvvtFC7h+SSnoyWoM6NgEVRZrC9zkrcRlA76gsNtPZ\/NgTtyf8g5COjg5bYKP7nVCVShnqlMsKNAKiSPJpBQWhZqMJUAMAyHDe1wggeeFEBNTBt5epYFsuQ0WrhsfWETXHed59IlXuH\/2P4pgm05yJrUwNJThqu1TTMuqC+40vbib1NOMtrTQvGgpG3oTkjhf1GpCnod3bbziNYKrShCeq+PoL2FeW+wlw+KYVo0pkguxdkL3P1fKiJAq1B\/H7cvB\/MNMuLgH87GWkxvb6hBAUjnLt16AAjDcleRxhjw8Y\/ny+yqB8lGV9W5UouxA==", "gmt_create": "2017-04-13 10:29:33", "buyer_pay_amount": "0.01", "receipt_amount": "0.01", "fund_bill_list": "[{\"amount\":\"0.01\",\"fundChannel\":\"ALIPAYACCOUNT\"}]", "app_id": "2016080400MMMMMM", "seller_id": "2088102169NNNNNN", "notify_id": "1269bf930d3fb2fdb39f7eb5ac04OOOOOO", "seller_email": "gylh******@sandbox.com" }