php 服务端集成支付宝APP支付

支付宝支付分为了很多种场景,这里只讲述支付宝APP支付功能集成,期间遇到了特别大的坑,因此我简单描述下集成过程,并概述遇到的问题及解决方案


由于公司业务简单,只支持支付宝支付,而无需关心退款,查询等等额外功能,因此该篇内容仅仅讲述支付宝支付接口时服务端如何准备APP拉取支付订单的信息,大概流程如下


一、创建应用及配置

首先,需要到蚂蚁金服开发平台(open.alipay.com)注册应用,并获取应用ID,并配置应用,这里在配置时主要是签约,生成应用的RSA2公私钥,同时获取到支付宝提供的支付公钥等,这部分官网后台都有提示,比较简单


二、下载对应SDK

这里我是在PHP后台集成服务,因此下载的是PHP SDK,地址:https://docs.open.alipay.com/54/103419/


三、准备一个可以访问的真实域名


四、案例

当以上三部完成之后,此时就可以进入配置我们自己的业务代码了

4.1、组织APP支付时的支付订单信息


  1. <?php  
  2.   
  3. require_once (__DIR__.'/alipay-sdk-PHP-20171023143822/AopSdk.php');  
  4.   
  5. class Alipay  
  6. {  
  7.     /** 
  8.      * 应用ID 
  9.      */  
  10.     const APPID = '你的应用ID';  
  11.     /** 
  12.      *请填写开发者私钥去头去尾去回车,一行字符串 
  13.      */  
  14.     const RSA_PRIVATE_KEY = '应用对应开发者私钥';  
  15.     /** 
  16.      *请填写支付宝公钥,一行字符串 
  17.      */  
  18.     const ALIPAY_RSA_PUBLIC_KEY = '支付宝提供的公钥';  
  19.     /** 
  20.      * 支付宝服务器主动通知商户服务器里指定的页面 
  21.      * @var string 
  22.      */  
  23.     private $callback = "http://www.test.com/notify/alipay_notify.php";  
  24.   
  25.     /** 
  26.      *生成APP支付订单信息 
  27.      * @param string $orderId   商品订单ID 
  28.      * @param string $subject   支付商品的标题 
  29.      * @param string $body      支付商品描述 
  30.      * @param float $pre_price  商品总支付金额 
  31.      * @param int $expire       支付交易时间 
  32.      * @return bool|string  返回支付宝签名后订单信息,否则返回false 
  33.      */  
  34.     public function unifiedorder($orderId$subject,$body,$pre_price,$expire){  
  35.         try{  
  36.             $aop = new \AopClient();  
  37.             $aop->gatewayUrl = "https://openapi.alipay.com/gateway.do";  
  38.             $aop->appId = self::APPID;  
  39.             $aop->rsaPrivateKey = self::RSA_PRIVATE_KEY;  
  40.             $aop->format = "json";  
  41.             $aop->charset = "UTF-8";  
  42.             $aop->signType = "RSA2";  
  43.             $aop->alipayrsaPublicKey = self::ALIPAY_RSA_PUBLIC_KEY;  
  44.             //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay  
  45.             $request = new \AlipayTradeAppPayRequest();  
  46.             //SDK已经封装掉了公共参数,这里只需要传入业务参数  
  47.             $bizcontent = "{\"body\":\"{$body}\","      //支付商品描述  
  48.                 . "\"subject\":\"{$subject}\","        //支付商品的标题  
  49.                 . "\"out_trade_no\":\"{$orderId}\","   //商户网站唯一订单号  
  50.                 . "\"timeout_express\":\"{$expire}m\","       //该笔订单允许的最晚付款时间,逾期将关闭交易  
  51.                 . "\"total_amount\":\"{$pre_price}\"," //订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000]  
  52.                 . "\"product_code\":\"QUICK_MSECURITY_PAY\""  
  53.                 . "}";  
  54.             $request->setNotifyUrl($this->callback);  
  55.             $request->setBizContent($bizcontent);  
  56.             //这里和普通的接口调用不同,使用的是sdkExecute  
  57.             $response = $aop->sdkExecute($request);  
  58.             //htmlspecialchars是为了输出到页面时防止被浏览器将关键参数html转义,实际打印到日志以及http传输不会有这个问题  
  59.             return htmlspecialchars($response);//就是orderString 可以直接给客户端请求,无需再做处理。  
  60.         }catch (\Exception $e){  
  61.             return false;  
  62.         }  
  63.   
  64.     }  
  65. }  

4.2、支付宝支付成功之后异步回调处理


  1. <?php  
  2. /** 
  3.  * alipay_notify.php. 
  4.  * User: lvfk 
  5.  * Date: 2017/10/26 0026 
  6.  * Time: 13:48 
  7.  * Desc: 支付宝支付成功异步通知 
  8.  */  
  9. include_once (__DIR__.'/../alipay-sdk-PHP-20171023143822/AopSdk.php');  
  10.   
  11. //验证签名  
  12. $aop = new \AopClient();  
  13. $aop->alipayrsaPublicKey = \Comm\Pay\Alipay::ALIPAY_RSA_PUBLIC_KEY;  
  14. $flag = $aop->rsaCheckV1($_POST, NULL, "RSA2");  
  15.   
  16. //验签  
  17. if($flag){  
  18.     //处理业务,并从$_POST中提取需要的参数内容  
  19.     if($_POST['trade_status'] == 'TRADE_SUCCESS'  
  20.         || $_POST['trade_status'] == 'TRADE_FINISHED'){//处理交易完成或者支付成功的通知  
  21.         //获取订单号  
  22.         $orderId = $_POST['out_trade_no'];  
  23.         //交易号  
  24.         $trade_no = $_POST['trade_no'];  
  25.         //订单支付时间  
  26.         $gmt_payment = $_POST['gmt_payment'];  
  27.         //转换为时间戳  
  28.         $gtime = strtotime($gmt_payment);  
  29.   
  30.         //此处编写回调处理逻辑  
  31.   
  32.         //处理成功一定要返回 success 这7个字符组成的字符串,  
  33.         //die('success');//响应success表示业务处理成功,告知支付宝无需在异步通知  
  34.           
  35.     }  
  36. }  

五、遇到的问题

5.1、一直报错40001=>isv.invalid-signature

为了搞清楚原因,先后多次重新生成应用的RSA2公私密钥,发现都没有作用。最后结合网上资料,才发现,原来是支付宝回调地址notifyUrl不能有 '?' 以及 ?后面加参数


5.2、支付宝异步通知成功了,但是$_POST为空

这个也花费了一点时间查找,开始做的时候就是遵照支付宝的建议使用HTTS方式请求。但这样应用后台一直通知没有参数内容。最后才想起来由于我们的应用使用了HTTS双向认证,这个原因导致支付宝的服务器回调的参数为空。最后,把回调地址改为了HTTP方式,验证通过


 通过遇到的问题,首先查看支付宝的文档描述以及支付宝提供的错误码解释,实在不行就百度或者谷歌,再加上自己不断测试验证,最终一定可以解决问题


至此,支付宝APP支付这块功能完成,其他的APP退款、对账单等等功能就没继续做,不过按照支付宝官网文档以及支付宝提供的SDK,集成到自己应用也只是时间问题。

猜你喜欢

转载自blog.csdn.net/qq_36663951/article/details/80755681