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'));
}