使用 yansongda/pay 進行支付寶和微信 App 支付

woann發表於2020-03-03

簡介

    現在很多專案(APP)都會用到微信或支付寶支付,然而官方文件和亂七八糟的簽名會讓很多開發者一臉懵逼,所以github有很多第三方的包,已經封裝好了各種支付,這裡以yansongda/pay這個包為例。

  1. 安裝

    composer require yansongda/pay -vvv
  2. 配置檔案(config/pay.php 這個配置檔案自行建立,不用非得跟我一樣),然後在.env檔案中填寫對應配置。

    <?php
    return [
     'alipay' => [
         // 支付寶分配的 APPID
         'app_id' => env('ALI_APP_ID', ''),
    
         // 支付寶非同步通知地址
         'notify_url' => '',
    
         // 支付成功後同步通知地址
         'return_url' => '',
    
         // 阿里公共金鑰,驗證簽名時使用
         'ali_public_key' => env('ALI_PUBLIC_KEY', ''),
    
         // 自己的私鑰,簽名時使用
         'private_key' => env('ALI_PRIVATE_KEY', ''),
    
         // optional,預設 warning;日誌路徑為:sys_get_temp_dir().'/logs/yansongda.pay.log'
         'log' => [
             'file' => storage_path('logs/alipay.log'),
         //  'level' => 'debug'
         //  'type' => 'single', // optional, 可選 daily.
         //  'max_file' => 30,
         ],
    
         // optional,設定此引數,將進入沙箱模式
         // 'mode' => 'dev',
     ],
    
     'wechat' => [
         // 公眾號 APPID
         'app_id' => env('WECHAT_APP_ID', ''),
    
         // 小程式 APPID
         'miniapp_id' => env('WECHAT_MINIAPP_ID', ''),
    
         // APP 引用的 appid
         'appid' => env('WECHAT_APPID', ''),
    
         // 微信支付分配的微信商戶號
         'mch_id' => env('WECHAT_MCH_ID', ''),
    
         // 微信支付非同步通知地址
         'notify_url' => '',
    
         // 微信支付簽名祕鑰
         'key' => env('WECHAT_KEY', ''),
    
         // 客戶端證照路徑,退款、紅包等需要用到。請填寫絕對路徑,linux 請確保許可權問題。pem 格式。
         'cert_client' => base_path('storage/app/cert/apiclient_cert.pem'),
    
         // 客戶端祕鑰路徑,退款、紅包等需要用到。請填寫絕對路徑,linux 請確保許可權問題。pem 格式。
         'cert_key' =>  base_path('storage/app/cert/apiclient_key.pem'),
    
         // optional,預設 warning;日誌路徑為:sys_get_temp_dir().'/logs/yansongda.pay.log'
         'log' => [
             'file' => storage_path('logs/wechat.log'),
         //  'level' => 'debug'
         //  'type' => 'single', // optional, 可選 daily.
         //  'max_file' => 30,
         ],
    
         // optional
         // 'dev' 時為沙箱模式
         // 'hk' 時為東南亞節點
         // 'mode' => 'dev',
     ],
    ];
  3. 下單獲取客戶端用以吊起支付的引數

  • 微信
    /**
     * @Author woann <www.woann.cn>
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \Illuminate\Validation\ValidationException
     * @des 微信下單獲取支付引數
     */
    public function wechatPay(Request $request)
    {
        $this->validate(
            $request,
            [
                'order_id'           =>  'required|digits_between:1,9|integer',
            ]
        );
        $order_id = $request->get('order_id');
        $order = LevelOrder::find($order_id);
        if (!$order || $order->state != 0) {
            return returnApi(500,'訂單狀態異常');
        }
        //以上為獲取訂單資訊 根據自己業務調整
        $data = [
            'out_trade_no' => $order->order_no,//訂單號
            'body'          => $order->goods_name,//商品名稱
            'total_fee'      => $order->total * 100//金額單位分
        ];
        $config = config('pay.wechat');獲取配置引數
        $config['notify_url'] = env('APP_URL').'/notify';//加入回撥url
        $result = Pay::wechat($config)->app($data);//統一下單
        $json = $result->getContent();
        $res = json_decode($json);
        return returnApi(200,'SUCCESS', $res);//返回支付引數
        /* 返回資料示例
        {
            "code":200,
            "msg":"SUCCESS",
            "data":{
                "appid":"wx1076a204916e103b",
                "partnerid":"1571249771",
                "prepayid":"wx09151331559233021135325f1455481800",
                "timestamp":"1578554011",
                "noncestr":"pfCEOneTh3Ic2RdC",
                "package":"Sign=WXPay",
                "sign":"DCE5402CEA09721C7225F2F5DC563EE3"
            }
        }
        */
    }
  • 支付寶
/**
     * @Author woann <www.woann.cn>
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \Illuminate\Validation\ValidationException
     * @des 支付寶支付
     */
    public function aliPay(Request $request)
    {
        $this->validate(
            $request,
            [
                'order_id'           =>  'required|digits_between:1,9|integer',
            ]
        );
        $order_id = $request->get('order_id');
        $order = Order::find($order_id);
        if (!$order || $order->state != 0) {
            return returnApi(500,'訂單狀態異常');
        }
        //以上為獲取訂單資訊 根據自己業務調整
        $order = [
            'out_trade_no' => $order->order_no,//訂單號
            'total_amount' => $order->total,//金額 單位元
            'subject'      => $order->name,//商品名稱
        ];
        $config = config('pay.alipay');
        $config['notify_url'] = env('APP_URL').'/v1/notify';//加入回撥url
        $alipay = Pay::alipay($config);
        $res = $alipay->app($order)->getContent();
        return returnApi(200,'SUCCESS',['orderInfo' => $res]);
            /* 返回資料示例
            {
                "code":200,
                "msg":"SUCCESS",
                "data":{
                    "orderInfo":"app_id=2021001100636235&format=JSON&charset=utf-8&sign_type=RSA2&version=1.0&notify_url=https%3A%2F%2Fqiangyibo.enumen.com%2Fv1%2Flevel%2Falipay%2Fnotify&timestamp=2020-02-13+10%3A44%3A50&biz_content=%7B%22out_trade_no%22%3A%222020010914545331453%22%2C%22total_amount%22%3A%2259.70%22%2C%22subject%22%3Anull%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%7D&method=alipay.trade.app.pay&sign=cX6uehDLpo8Lw8eat5X0XaoH09hbkZnb%2BNs4hfOokSXd2rhQBUuC45x6b%2FtfjDlNuFgukpPGzF1SlqP%2FFadiOBMYfir%2FZv3D3fEq8ec%2BHhsVk7lrUytyGhLyYgAEVjEA1uJyQAUKfTqDs9FeWgnpi3IiHk8hO4J8zwPjV2YG0RvZnJrEXTgavz6E2gMNkU%2BtaqhICCtVxyq1nbc%2BnYM4k8jT57dEEKC1fn7x1LTU60YPBxun7oKMsn%2BZNYPBycq4KGh9QKh9N7mRreFqT38PwiWFx4zOCwwMUM%2B%2BxxiqaJEg%2BcquTYptF1oxujwHvFB9O25dkxUeUvFUKhFD5MevZQ%3D%3D"
                }
            }
        */
    }
}
  1. 回撥
  • 微信
    public function wechatNotify(Request $request)
      {
          $config = config('pay.wechat');
          $pay = Pay::wechat($config);//例項化支付物件
          try{
              $data = $pay->verify(); // 是的,驗籤就這麼簡單!
              //以下根據自己業務進行支付校驗
              $order = Order::where('order_no', $data->out_trade_no)->first();
              if (!$order || $order->state != 0)  {
                  //如果訂單狀態異常直接退出
                  return $pay->success();
              }
              if (($order->total) != $data->total_fee / 100) {
                  //如果金額不匹配直接退出
                  return $pay->success();
              }
              //進行訂單狀態變更等支付成功操作
              //....
              return $pay->success();
          } catch (\Exception $e) {
          }
      }
  • 支付寶
    public function aliPayNotify(Request $request)
      {
          $config = config('pay.alipay');
          $alipay = Pay::alipay($config);
          try{
              $data = $alipay->verify(); // 是的,驗籤就這麼簡單!
              //以下根據自己業務進行支付校驗
              $order = Order::where('order_no', $data->out_trade_no)->first();
              if (!$order || $order->state != 0)  {
                  //如果訂單狀態異常直接退出
                  return $alipay->success();
              }
              if (($order->total) != $data->total_amount) {
                  return $alipay->success();
              }
              //進行訂單狀態變更等支付成功操作
              //....
              return $alipay->success();
              Log::debug('Alipay notify', $data->all());
          } catch (\Exception $e) {
    //             $e->getMessage();
          }
          return $alipay->success();// laravel 框架中請直接 `return $alipay->success()`
      }
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章