温馨提示
  • 欢迎您光临共享屋素材网,本站所有资源均来自网络或用户自主上传,本站所有素材仅交流学习用途,请勿商用。
  • 支付宝支付接入流程

    支付宝支付需要签约,并有商家号,但是测试环境中,我们可以使用支付宝提供的沙箱环境,在这个后台中进行配置,接通后,可以进行模拟支付。正式开发时,需要到开发者中心创建应用,并选择要使用的功能,以及签约。

    框架:ThinkPHP 5.0

    演示的支付接口:支付宝电脑网站支付(手机网站支付操作一样)

    下载官方 Demo

    进入支付宝开放平台,选择文档中心,在选择电脑网站支付,找到 demo 进行下载。下载解压后,将目录名修改为 “AlipayTradePagePay”,由于是手动下载的第三方类库,所以放置到框架的 extend 目录下,如下图:

    附功能说明图:

    完善配置项

    demo 中有个 config.php 文件,我们为了方便,将这个文件中的配置项先复制下来,到 application/extra 目录下,创建名为 alipay.php 配置文件,并将刚复制的配置项放置在这里。extra 目录下是放置扩展配置文件的,完成后效果如下:

    application/extra/alipay.php

    <?php
        return [
            //应用ID,您的APPID。
            'app_id' => "",
    
            //商户私钥,也就是支付宝开发助手上生成的应用私钥
            'merchant_private_key' => "",
    
            //异步通知地址
            'notify_url' => "http://zhifu.acier.cn/index/index/notify_url",
    
            //同步跳转
            'return_url' => "http://zhifu.acier.cn/index/index/return_url",
    
            //编码格式
            'charset' => "UTF-8",
    
            //签名方式
            'sign_type'=>"RSA2",
    
            //支付宝网关,沙箱环境和正式环境不一样,这里使用沙箱环境
            'gatewayUrl' => "https://openapi.alipaydev.com/gateway.do",
    
            //支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
            'alipay_public_key' => "",
        ];

    完善上述配置,打开支付宝沙箱环境页面,在“必看部分”可以看到 APPID ,支付宝网关的信息,然后设置 RSA2(SHA256)密钥,这部分内容和之前写过支付宝第三方登录获取公钥私钥是一样的,首先需要下载“支付宝开放平台开发助手”这个工具,打开工具,选择下图所示选项,然后点击 “生成密钥” 按钮,就生成了应用私钥和应用公钥了。

    在沙箱环境的“RSA2(SHA256)密钥”选项处点击“设置/查看”按钮,将应用公钥复制到弹出的框内:

    保存设置,然后就能生成支付宝公钥,如下图:

    将商户私钥(应用私钥)和支付宝公钥粘贴到配置文件中,notify_url 和 return_url 自己设定。

    访问:域名/index/index/index

    控制器代码:

    <?php
    namespace app\index\controller;
    
    class Index
    {
        public function index()
        {
            dump(config('alipay'));
        }
    }

    访问后,确保刚配置的信息可以正常打印出来。

    创建函数文件

    位置:application/index/common.php,内容如下:

    <?php
    
    //生成唯一订单号
    function build_order_no(){
        return date('Ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
    }
    /**
     * 支付宝 电脑网站支付
     * @auhor hongweizhiyuan
     * @param $out_trade_no     商户订单号
     * @param $subject          订单名称
     * @param $total_amount     订单金额
     * @param $body             商品描述
     * @example alipayPagepay('201791711599526','商品标题','0.01','商品描述');
     */
    function alipayPagepay($out_trade_no,$subject,$total_amount,$body)
    {
        //step1:获取配置
        import('AlipayTradePagePay.pagepay.service.AlipayTradeService',EXTEND_PATH,'.php');// 加载交易服务类
        $config=config('alipay');
        $aop=new AlipayTradeService($config);
    
        //step2:加载表单,构造参数
        import('AlipayTradePagePay.pagepay.buildermodel.AlipayTradePagePayContentBuilder',EXTEND_PATH,'.php');  // 支付宝电脑网站支付
        $payRequestBuilder = new AlipayTradePagePayContentBuilder();
        $payRequestBuilder->setBody($body);
        $payRequestBuilder->setSubject($subject);
        $payRequestBuilder->setTotalAmount($total_amount);
        $payRequestBuilder->setOutTradeNo($out_trade_no);
    
        //step3:创建支付
        $response = $aop->pagePay($payRequestBuilder,$config['return_url'],$config['notify_url']);
    
        //输出表单
        var_dump($response);
    
    }
    
    /**
     * 支付宝 电脑网站 交易查询
     * @param $WIDTQout_trade_no     商户订单号,商户网站订单系统中唯一订单号(请二选一设置)
     * @param $WIDTQtrade_no         支付宝交易号(请二选一设置)
     */
    function alipayQuery($WIDTQout_trade_no,$WIDTQtrade_no)
    {
        //step1:获取配置
        import('AlipayTradePagePay.pagepay.service.AlipayTradeService',EXTEND_PATH,'.php');// 加载交易服务类
        $config=config('alipay');
        $aop = new AlipayTradeService($config);
    
        //step2:加载表单,构造参数
        import('AlipayTradePagePay.pagepay.buildermodel.AlipayTradeQueryContentBuilder',EXTEND_PATH,'.php');  // 支付宝电脑网站支付查询接口
        $RequestBuilder = new AlipayTradeQueryContentBuilder();
        $RequestBuilder->setOutTradeNo($WIDTQout_trade_no);
        $RequestBuilder->setTradeNo($WIDTQtrade_no);
    
        /**
         * alipay.trade.query (统一收单线下交易查询)
         * @param $builder 业务参数,使用buildmodel中的对象生成。
         * @return $response 支付宝返回的信息
         */
        $response = $aop->Query($RequestBuilder);
        var_dump($response);
    }
    
    /**
     * 支付宝 电脑网站 退款
     * @param $out_trade_no     商户订单号,商户网站订单系统中唯一订单号(请二选一设置)
     * @param $trade_no         支付宝交易号(请二选一设置)
     * @param $refund_amount    需要退款的金额,该金额不能大于订单金额,必填
     * @param $refund_reason    退款的原因说明
     * @param $out_request_no   标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传
     */
    function alipayRefund($out_trade_no,$trade_no,$refund_amount,$refund_reason,$out_request_no)
    {
        //step1:获取配置
        import('AlipayTradePagePay.pagepay.service.AlipayTradeService',EXTEND_PATH,'.php');// 加载交易服务类
        $config=config('alipay');
        $aop = new AlipayTradeService($config);
    
        //step2:加载表单,构造参数
        import('AlipayTradePagePay.pagepay.buildermodel.AlipayTradeRefundContentBuilder',EXTEND_PATH,'.php');  // 支付宝电脑网站支付退款接口
        $RequestBuilder=new AlipayTradeRefundContentBuilder();
        $RequestBuilder->setOutTradeNo($out_trade_no);
        $RequestBuilder->setTradeNo($trade_no);
        $RequestBuilder->setRefundAmount($refund_amount);
        $RequestBuilder->setOutRequestNo($out_request_no);
        $RequestBuilder->setRefundReason($refund_reason);
    
        /**
         * alipay.trade.refund (统一收单交易退款接口)
         * @param $builder 业务参数,使用buildmodel中的对象生成。
         * @return $response 支付宝返回的信息
         */
        $response = $aop->Refund($RequestBuilder);
        var_dump($response);;
    }
    
    /**
     * 支付宝 电脑网站 退款查询
     * @param $out_trade_no         商户订单号,商户网站订单系统中唯一订单号(请二选一设置)
     * @param $trade_no             支付宝交易号(请二选一设置)
     * @param $out_request_no       请求退款接口时,传入的退款请求号,如果在退款请求时未传入,则该值为创建交易时的外部交易号,必填
     */
    function alipayRefundQuery($out_trade_no,$trade_no,$out_request_no)
    {
        //step1:获取配置
        import('AlipayTradePagePay.pagepay.service.AlipayTradeService',EXTEND_PATH,'.php');// 加载交易服务类
        $config=config('alipay');
        $aop = new AlipayTradeService($config);
    
        //step2:加载表单,构造参数
        import('AlipayTradePagePay.pagepay.buildermodel.AlipayTradeFastpayRefundQueryContentBuilder',EXTEND_PATH,'.php');  // 支付宝电脑网站 统一收单交易退款查询
        $RequestBuilder=new AlipayTradeFastpayRefundQueryContentBuilder();
        $RequestBuilder->setOutTradeNo($out_trade_no);
        $RequestBuilder->setTradeNo($trade_no);
        $RequestBuilder->setOutRequestNo($out_request_no);
    
        /**
         * 退款查询   alipay.trade.fastpay.refund.query (统一收单交易退款查询)
         * @param $builder 业务参数,使用buildmodel中的对象生成。
         * @return $response 支付宝返回的信息
         */
        $response = $aop->refundQuery($RequestBuilder);
        var_dump($response);
    }
    
    /**
     * 支付宝 电脑网站 交易关闭
     * @param $out_trade_no     商户订单号,商户网站订单系统中唯一订单号(请二选一设置)
     * @param $trade_no         支付宝交易号(请二选一设置)
     */
    function alipayClose($out_trade_no,$trade_no)
    {
        //step1:获取配置
        import('AlipayTradePagePay.pagepay.service.AlipayTradeService',EXTEND_PATH,'.php');// 加载交易服务类
        $config=C('ALIPAY_CONFIG');
        $aop = new AlipayTradeService($config);
    
        //step2:加载表单,构造参数
        import('AlipayTradePagePay.pagepay.buildermodel.AlipayTradeCloseContentBuilder',EXTEND_PATH,'.php');  // 支付宝电脑网站 统一收单交易关闭接口
        $RequestBuilder=new AlipayTradeCloseContentBuilder();
        $RequestBuilder->setOutTradeNo($out_trade_no);
        $RequestBuilder->setTradeNo($trade_no);
    
        /**
         * alipay.trade.close (统一收单交易关闭接口)
         * @param $builder 业务参数,使用buildmodel中的对象生成。
         * @return $response 支付宝返回的信息
         */
        $response = $aop->Close($RequestBuilder);
        var_dump($response);
    }

    开始使用

    本功能官方文档:https://opendocs.alipay.com/apis/api_1/alipay.trade.page.pay

    设置 demo 中 log.txt 权限为 777。

    访问:域名/index/index/pagepayTest

    方法代码:

    public function pagepayTest()
    {
        alipayPagepay(build_order_no(),'商品标题','666','商品描述');
    }

    访问后,如果使用 PHP 7.2 版本,会发现有报错。打开框架配置文件 applica/config.php ,开启调试模式和应用Trace,可以看到错误提示:

    发现是 each() 这个函数已经废弃了,并且框架把错误的代码也贴出来了。将鼠标放在错误提示上,即可看到错误位置的具体路径:

    根据提示,查找到 /extend/AlipayTradePagePay/aop/AopClient.php 这个文件的413行,将:

    while (list ($key, $val) = each ($para_temp)) {

    替换为:

    foreach ($para_temp as $key => $val) {

    发现可以正常访问了。若出现以下情况:

    可以通过尝试更换浏览器解决。正常情况是可以扫码支付了。

    这里不能用我们自己的支付宝扫码支付,需要下载沙箱环境专用的支付宝APP来进行支付,在沙箱应用中有下载地址。

    支付后的回调

    刚在支付宝配置文件中我们设置了 同步跳转 和 异步通知地址,简单来说,同步跳转 是当用户支付完成后,页面要跳到的地址,使用户能够回到项目中继续其他操作。而 异步通知 是支付后用来处理业务逻辑信息的,例如修改数据库中该件商品的支付状态,减库存等等。

    支付后,同步跳转 return_url() 方法会接收到如下参数:

    out_trade_no:商户订单号

    total_amount:交易金额

    trade_no:支付宝交易号

    seller_id:收款支付宝账号对应的支付宝唯一用户号

    在 demo 中,已经集成了 return_url.php 和 notify_url.php 两个文件,分别对应这两种回调类型,可以参考。

    最后再说一下,异步通知中,因为是支付宝主动发送,cookie 和 session 会失效。若支付后,参数 trade_status 有两种值,TRADE_FINISHED 和 TRADE_SUCCESS ,前者是交易完结了,后续不会有其它操作了,如退款。后者仅代表本次交易成功,后续可能会有退款,若没有,三个月后,会再次发送过来 TRADE_FINISHED 值。数据库设计中,应确保有这两个字段。即时到账普通版接口没有退款,高级版有退款。

    还有最重要一点,异步通知程序执行完后,一定要打印输出 “success” 这七个字符,否则支付宝服务器会不断重发通知,直到超过24小时22分钟。在25小时内完成6~10次通知(通知频率:5s,2m,10m,15m,1h,2h,6h,15h)。

    其他接口,例如订单查询,退款等,都在 common.php 中已经写好,组织好参数调用即可。

    手机网站支付

    手机网页上使用支付宝支付,需要下载手机网站支付 demo ,下载后使用方式和电脑支付一样,只是载入的类名不一样,配置文件和电脑支付都是一样的,可以共用。同样,这里我们也封装在函数里,下面演示一下:

    /**
     * 支付宝 手机网站支付
     * @auhor hongweizhiyuan
     * @param $out_trade_no     商户订单号
     * @param $subject          订单名称
     * @param $total_amount     订单金额
     * @param $body             商品描述
     * @example alipayPagepay('201791711599526','商品标题','0.01','商品描述');
     */
    function alipayWappay($out_trade_no,$subject,$total_amount,$body)
    {
        //step1:获取配置
        import('AlipayTradeWapPay.wappay.service.AlipayTradeService',EXTEND_PATH,'.php');// 加载交易服务类
        $config=config('alipay');
        $aop=new AlipayTradeService($config);
    
        //超时时间
        $timeout_express="1m";
    
        //step2:加载表单,构造参数
        import('AlipayTradeWapPay.wappay.buildermodel.AlipayTradeWapPayContentBuilder',EXTEND_PATH,'.php');  // 支付宝电脑网站支付
        $payRequestBuilder = new AlipayTradeWapPayContentBuilder();
        $payRequestBuilder->setBody($body);
        $payRequestBuilder->setSubject($subject);
        $payRequestBuilder->setTotalAmount($total_amount);
        $payRequestBuilder->setOutTradeNo($out_trade_no);
        $payRequestBuilder->setTimeExpress($timeout_express);
    
        //step3:创建支付
        $response = $aop->wapPay($payRequestBuilder,$config['return_url'],$config['notify_url']);
    
        //输出表单
        var_dump($response);
    }
    
    登录开启无限免费下载