支付宝支付接口流程及那些坑

作者:vkvi 来源:ITPOW(原创) 日期:2018-3-1

第一步、申请支付宝支付

这个不属于软件开发,不谈。

第二步、在支付宝平台创建应用

https://openhome.alipay.com/,登录后,创建一个应用,然后线上签约支付,比如要开通手机网站支付,就要签约“手机网站支付”,如果要开通 APP 支付,就要签约“APP支付”。然后等等审核。

然后指定这个应用的密钥,有两种密钥:

  • 接口签名密钥,有 RSA(SHA-1)、RSA2(SAHA-256) 两种,后面这种更安全些。
  • 内容加密密钥,一般情况下,使用明文就可以了,因为本身 HTTPS 也会对内容加密,即使网络传输也是明文,也只是被人探听到内容,无法冒充、无法篡改。

这一步比微信支付麻烦些。

关于密钥,有个软件,下载地址是:https://docs.open.alipay.com/291/106097。

第三步、发起支付

我们以网页支付为例。先下载 SDK,地址:https://docs.open.alipay.com/54/103419。

怎么样非常方便吧。不过这里有两点说明:

DefaultAopClient 有个参数 alipayPublicKey,表示支付宝公钥,但是我用应用公钥也是一样的。什么,有两个公钥?是的,在前面步骤中创建的应用中,可以看到,如下图:

支付宝应用公钥和支付宝公钥

还有一点就是 SetNotifyUrl,支付宝的示例中,并没有添加这个参数,开始我也以为不需要添加这个参数,我以为支付完成后,支付宝会将支付发送到我在应用中配置的应用网关网址(或者授权回调地址),可是后来通过监测发现,支付宝虽然会定时扫描这两个网址,但是并不会在支付完成后向这两个地址发送结果,所以必须指定 NotifyUrl,这样支付宝在完成支付后,会立即向这个地址发送支付结果。

我们也可以做沙盒测试,所有的支付都不涉及真钱,但是那个需要申请,并不是换了网址就是沙盒了。

第四步、接收支付结果

支付宝网页支付完成后,需要一个网址来接收支付宝发过来的支付结果。

这里面首先就要验证签名,也就是说要确信是支付宝发过来的。步骤也挺简单,只是坑多。

1、将所有 POST 值取出来,存在 Dictionary 中。

2、调用 AlipaySignature.RSACheckV1 验证 POST 过来的值,如果返回 true,说明是支付宝过来的结果,签名正确。

坑:

1、文档上说要剔除 sign、sign_type,其实那是说签名的具体细节,但是我们使用了 SDK 的方法,RSACheckV1() 中会帮我们剔除的。

2、sign 不能人工剔除,因为 RSACheckV1() 在剔除 sign、sign_type 前,会用到 sign。

3、文档上说 value 需要 UrlDecode,实际不能,加了反而错。

4、文档上说要对 POST 的项进行排序,其实也是不必,因为 RSACheckV1() 会帮我们排。

5、还有就是不同方法中 signType、keyFromFile 这两个参数的顺序不一样,看来当初设计的时候有点乱。

6、这里也是用支付宝公钥,而不是应用公钥。

以上完成了签名后,支付宝还建议作一些业务上的判断,比如:

1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号

2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额)

3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)

4、验证app_id是否为该商户本身。

5、然后根据 trade_status 作相应的处理。

  • TRADE_SUCCESS  的通知触发条件是商户签约的产品支持退款功能的前提下,买家付款成功;
  • TRADE_FINISHED 的通知触发条件是商户签约的产品不支持退款功能的前提下,买家付款成功;或者,商户签约的产品支持退款功能的前提下,交易已经成功并且已经超过可退款期限。

后面就是根据我们的业务判断、业务逻辑来处理了。

相关文章