PHP新手30天實戰金流, Laravel6我們今天的目標是要將原本 ECPay的付款成功畫面改為我們自己的前端頁面。
我們會傳 ReturnURL 當作付款完成通知回傳的網址,為了讓 ECPay server 可以找到我們在本機建立的 server,我們使用 Ngrok 來連接外網
brew cask install ngrok
ngrok http 8000
ngrok by @inconshreveable                                                            (Ctrl+C to quit)
                                                                                                     
Session Status                online                                                                 
Session Expires               7 hours, 59 minutes                                                    
Version                       2.3.34                                                                 
Region                        United States (us)                                                     
Web Interface                 http://127.0.0.1:4040                                                  
Forwarding                    http://4c1b0ff5.ngrok.io -> http://localhost:8000                      
Forwarding                    https://4c1b0ff5.ngrok.io -> http://localhost:8000                     
                                                                                                     
Connections                   ttl     opn     rt1     rt5     p50     p90                            
                              0       0       0.00    0.00    0.00    0.00 
現在我們開啟 http://4c1b0ff5.ngrok.io 就等於連到 http://localhost:8000
我們在 Day 13 的時候 有在 payByWebsite 函式中設定 API 參數-- "ReturnURL" , 現在加一個 "OrderResultURL",這主要是可以將付款後的畫面轉到我們自己的頁面,差異如下表。
$order->update([
                    'payment_no'        => $MerchantTradeNo,
                ]);
p.s ['ReturnURL'], ['OrderResultURL'], ['ClientBackURL']中的 ngrok 臨時 url 須自行更換唷!
    public function payByWebsite(Order $order)
    {
        $this->authorize('own', $order);
        // 訂單已支付或關閉
        if ($order->paid_at || $order->closed) {
            throw new InvalidRequestException('無法付款');
        }
        include('ECPay.Payment.Integration.php');
            try {
                
                $obj = new ECPay_AllInOne();
           
                //服務參數
                $obj->ServiceURL  = "https://payment-stage.ecpay.com.tw/Cashier/AioCheckOut/V5";  //服務位置
                $obj->HashKey     = '5294y06JbISpM5x9' ;                                          //測試用Hashkey,請自行帶入ECPay提供的HashKey
                $obj->HashIV      = 'v77hoKGq4kWxNNIS' ;                                          //測試用HashIV,請自行帶入ECPay提供的HashIV
                $obj->MerchantID  = '2000214';                                                    //測試用MerchantID,請自行帶入ECPay提供的MerchantID
                $obj->EncryptType = '1';                                                          //CheckMacValue加密類型,請固定填入1,使用SHA256加密
        
                $MerchantTradeNo = substr($order['no'],10,10).time() ; 
                //基本參數(請依系統規劃自行調整)
                $obj->Send['ReturnURL']         = "http://4af10922.ngrok.io/payment/website/listenPayResult" ;     //付款完成通知回傳的網址
                $obj->Send['OrderResultURL']    = "http://4af10922.ngrok.io/payment/website/notify";
                $obj->Send['ClientBackURL']    ="http://4af10922.ngrok.io/orders";
                $obj->Send['MerchantTradeNo']   = $MerchantTradeNo;              //訂單編號
                $obj->Send['MerchantTradeDate'] = date('Y/m/d H:i:s');                        //交易時間
                $obj->Send['TotalAmount']       = $order->total_amount;                                       //交易金額
                $obj->Send['TradeDesc']         = "ecpay test" ;                           //交易描述
                $obj->Send['ChoosePayment']     = ECPay_PaymentMethod::ALL ;
                                  //付款方式:全功能
                $order->update([
                    'payment_no'        => $MerchantTradeNo,
                ]);
                
            }catch (Exception $e) {
                echo $e->getMessage();
            }  
            //訂單的商品資料
            foreach ($order['items'] as $a_item)
            {
                array_push($obj->Send['Items'], array('Name'     => $a_item['product']->title,
                                                        'Price'    => (int) $a_item->price,
                                                        'Currency' => "元",
                                                        'Quantity' => (int) $a_item['amount'],
                                                        'URL'      => "dedwed"));
            }
            
            $obj->CheckOut();
            return redirect()->route('orders.show', [$order]);
    }
我們將 ReturnURL 設為 listenPayResult,這裡回傳 '1|OK' 給 ECPay;
將 OrderResultURL 設為 websiteNotify,回傳一個前端畫面。
public function listenPayResult(Request $request)
{
    if ($request->all()['RtnCode']){
        $data = $request->all();
        $order = Order::where('payment_no', $data['MerchantTradeNo'])->first();
        $order->update([
            'paid_at'        => now(),
            'payment_method' => 'website',
        ]);
    }
    return '1|OK';
}
public function websiteNotify(Request $request)
{
    return redirect()->route('orders.show', compact('order'));
}