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

发表于:2018-3-05 11:34

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:vkvi    来源:51Testing软件测试网采编

  第一步、申请支付宝支付
  这个不属于软件开发,不谈。
  第二步、在支付宝平台创建应用
  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。
  // 去支付宝支付
  IAopClient client = new DefaultAopClient("https://openapi.alipay.com/gateway.do",
      "appId",
      "privateKeyPem",
      "json", "1.0", "RSA",
      "alipayPublicKey",
      "UTF-8", false);
  AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
  request.SetNotifyUrl("https://www.cftea.com/api/");
  request.BizContent = "{" +
  "    \"body\":\"千一网络充值\"," +
  "    \"subject\":\"充值\"," +
  "    \"out_trade_no\":\"订单编码\"," +
  "    \"timeout_express\":\"90m\"," +
  "    \"total_amount\":以元为单位的钱," +
  "    \"product_code\":\"QUICK_WAP_WAY\"" +
  "  }";
  AlipayTradeWapPayResponse response = client.pageExecute(request);
  string form = response.Body;
  Response.Write(form);
  怎么样非常方便吧。不过这里有两点说明:
  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 的通知触发条件是商户签约的产品不支持退款功能的前提下,买家付款成功;或者,商户签约的产品支持退款功能的前提下,交易已经成功并且已经超过可退款期限。
  后面就是根据我们的业务判断、业务逻辑来处理了。


上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号