美文网首页
tp6使用yansongdaPay调用支付宝支付笔记。

tp6使用yansongdaPay调用支付宝支付笔记。

作者: DragonersLi | 来源:发表于2021-02-04 23:43 被阅读0次
    项目框架从tp5升级到tp6,原来的支付宝支付,改用yansongda/pay,使用沙箱模拟支付流程基本ok,切换正式参数,频繁报错,每次接入支付都花费很长时间调试。特此记录,以供以后遇到同样问题快速解决!
    网上说subjectbody传递的中文改成英文依旧报错,那就不是编码问题、之后又遇到检验RSA2密钥是否匹配问题,根据云排查可能是公钥私钥之类配置错误。重新生成配置。重新生成应用公私钥,公钥上传对应应用上,并获取支付宝公钥和应用私钥配置到支付宝配置文件。终于可以唤醒支付宝支付了,支付完成发现并没有回调成功,经过自助工具调式,发现服务器返回500,发现有代码有问题,处理完毕,整个支付流程ok。
    支付宝配置文件:config/alipay.php,其中app_id,支付宝公钥,应用私钥,网关,编码格式,签名方式,全部和旧的支付配置一样。
    <?php
    // +----------------------------------------------------------------------
    // | 支付宝支付设置
    // +----------------------------------------------------------------------
    
    return [
        'app_id' => "20191219600502xx",//应用ID
        'notify_url' => env('app.host')."/api/notify/alipay",//异步通知地址
        'return_url' => env('app.host')."/upgrade", //同步跳转 
        'ali_public_key' => "xxx",    //支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。 
        'private_key' => "xxx",//商户私钥,您的原始格式RSA私钥 
        'charset' => "UTF-8", //编码格式
        'sign_type'=>"RSA2", //签名方式
        'gatewayUrl' => "https://openapi.alipay.com/gateway.do",//支付宝网关
        //如果是沙箱模式用这个支付宝网关:'https://openapi.alipaydev.com/gateway.do',
        'log' => [ 
            'file' => app()->getRuntimePath() .'api'.DIRECTORY_SEPARATOR.'log'.DIRECTORY_SEPARATOR.date('Ymd').DIRECTORY_SEPARATOR.'alipay.log',//日志文件路径
            'level' => 'info', // 建议生产环境等级调整为 info,开发环境为 debug
            'type' => 'single', // optional, 可选 daily.
            'max_file' => 30, // optional, 当 type 为 daily 时有效,默认 30 天
        ],
        'http' => [
            'timeout' => 5.0,
            'connect_timeout' => 5.0,
            // 更多配置项请参考 [Guzzle](https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html)
        ],
        //'mode' => 'dev', // 开启此参数,将进入沙箱模式 
    
    ];
    
    
    
    
    
    在微信公众号环境跳浏览器打开唤醒支付宝支付,然后跳到错误页面:
    在订单结束,进入支付页面的时候出现
    错误代码 invalid-signature 错误原因: 验签出错,
    建议检查签名字符串或签名私钥与应用公钥是否匹配,网关生成的验签字符串为:
    alipay_sdk=alipay-sdk-java-4.8.10.ALL&app_id=2016102600763118&biz_content={"out_trade_no":"xxx","total_amount":"100","subject":"xxx","body":"xxx","product_code":"FAST_INSTANT_TRADE_PAY"}&charset=utf-8&format=json&method=alipay.trade.page.pay&notify_url=xxx&return_url=xxx&sign_type=RSA2&timestamp=xxx&version=1.0
    
    错误代码 invalid-signature
    秘钥工具生成秘钥:
    支付宝开放平台开发助手,根据系统下载软件,安装完成后,选择RSA2,PKCS1秘钥格式,
    然后生成秘钥(应用公私钥)。秘钥匹配验证应用公私钥是否匹配。
    
    一、应用公钥(public key)、应用私钥(private key)自己用工具生成并上传公钥到支付宝商户后台对应的app_id应用。
    
    二、支付宝公钥为支付宝提供,支付宝传递数据用支付宝私钥加密,用户用支付宝公钥解密,
    用户传递数据用应用私钥加密,支付宝用上传的公钥解密。
    
    三、登录支付宝商户后台,根据app_id找到对应的应用,上传应用公钥。并获取支付宝公钥,和应用私钥一起写入配置文件
    
    生成秘钥(应用公私钥)
    验证应用公私钥
    根据app_id查看支付宝公钥和应用公钥
    开发工具 > 支付宝开放平台开发助手 > 支付宝公共开发文档
    历史接口接入指南 > 签约与审核
    开发工具 > 云排查:https://opensupport.alipay.com/support/knowledge/01/201602472811
    自助工具调试(需登录),支付请求返回错误信息和异步回调问题排查https://opensupport.alipay.com/support/tools/cloudparse?ant_source=openmonitor
    自助工具调试:请求问题排查和异步回调排查
    路由配置:
     //支付必须登录状态下
        Route::group('pay', function () use($version){
            Route::any('wechat',"{$version}.Pay/wechat");//微信支付
            Route::any('alipay',"{$version}.Pay/alipay");//阿里支付 
        })->middleware('Jwt');
    
    
        //回调
        Route::group('notify', function () use($version){
            Route::any('wechat',"{$version}.Pay/wechat_notify");//微信支付回调
            Route::any('alipay',"{$version}.Pay/alipay_notify");//阿里支付回调 
        });
    
    支付逻辑代码:
    
        /**
         * 支付宝支付
         * @return array|mixed
         */
        public function alipay(){
            $uid = 0;//当前登录账户的ID
            $user = User::where(['id'=>$uid])->find(); 
            if($user->vip){
                $order_data = Order::where(['userId'=>$uid,'status'=>0])->find();//未支付订单
           
                if(empty($order_data)){ 
                    $order_data[ 'uid'] = $uid;
                    $order_data[ 'mobile'] = $user->mobile;
                    $order_data[ 'order_sn'] =  time();//订单号   
                    $order_data[ 'create_time'] = time();
                    $order_data[ 'order_money'] = config('system.upgrade_money')*100;
                    //升级费用单位元,写入数据库单位为分
                    $order_id = Order::insertGetId($order_data);  //订单入库
                } 
                if($order_id)
                return Pay::alipay(config('alipay'))->wap( [
                    'out_trade_no' =>  $order_data[ 'order_sn'],//本地订单号
                    'total_amount' => $order_data[ 'order_money']/100,//支付金额,单位元
                    'subject' => '升级会员',//支付界面显示标题
                ])->send();
    
            }
    
    
        }
    
    
    回调处理代码:
    
        public static function alipay_notify()
        {
           
            $alipay = Pay::alipay(config('alipay'));
          
            try{
                $data = $alipay->verify(); // 是的,验签就这么简单!
         
                // 请自行对 trade_status 进行判断及其它逻辑进行判断,
                // 在支付宝的业务通知中,只有交易通知状态为 TRADE_SUCCESS 或 TRADE_FINISHED 时,
                // 支付宝才会认定为买家付款成功。
                // 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号;
                // 2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额);
                // 3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no
               // 这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email);
                // 4、验证app_id是否为该商户本身。
                // 5、其它业务逻辑情况
                if(in_array($data['trade_status'],['TRADE_SUCCESS','TRADE_FINISHED'])){
                    $order_sn = htmlspecialchars($data['out_trade_no']);
                    $order = Order::where(['orderSn'=>$order_sn])->find();
                 
                    if(empty($order)){//订单不存在
                        trace("订单{$order_sn}不存在", 'info'); 
                    }
                    if(!$order->status) {//未支付
                        if (bccomp($order->order_money/ 100, $data['total_amount'], 2) != 0) {
                            //实际支付与订单金额不符
                            trace("订单{$order_sn}金额不符合", 'info'); 
                            exit('FAILE');
                        }
                         //此处编写回调处理逻辑
                        //返回返佣数据,先查数据库有没有生成,若生成则忽略,没生成则生成
                       //防止多次回调生成多余数据
                       //更新订单状态
                      //更新用户成会员
                       //未支付订单清除
                    }
                }
            } catch (\Exception $e) { 
                trace('alipay_notify', $e->getMessage());
            } 
            return $alipay->success()->send();
    
        }
    

    相关文章

      网友评论

          本文标题:tp6使用yansongdaPay调用支付宝支付笔记。

          本文链接:https://www.haomeiwen.com/subject/mdjnrxtx.html