iT邦幫忙

2021 iThome 鐵人賽

DAY 18
0

0x1 前言

廢話不多說,今日流程如下先觀察傳進內容,在針對內容刻畫面

0x2 建立 Route 跟 view

指定 /payment

// routes/web.php
Route::post('/payment', [Web::class, 'payment']);

在 Controller 建立 payment 函數,先 dd 傳送的要求看內容

public function payment(Request $request)
{
    dd($request->all());
    return view('payment', [
        'dataset' => $request->all()
    ]);
}

建立信用卡訂單並模擬付款完成的時候,覺得一切順利的時候,跳出這個畫面
https://ithelp.ithome.com.tw/upload/images/20210926/20141805VhCV49QAAL.png

查到這篇 stack overflow 的文章 後發現是 csrf protection 的問題,需要去把這個路徑加進排外名單

// app/Http/Middleware/VerifyCsrfToken.php
protected $except = [
    '/payment'
];

補充一個看傳入的方法,不用寫 dd 印出
開啟開發者工具(F12) -> Network -> All -> 選擇 payment -> Header 拉到最下面有 Form Data 的內容
https://ithelp.ithome.com.tw/upload/images/20210926/201418056xe07SHuwp.png

看來跟 receive_msg 一樣,只是需要能回吐解密訊息,那就修改一下這個函數,增加一個參數 return_data,其為 true 時則回傳 data

// app/Http/Controllers/Controller.php
public function receive_msg(Request $request, bool $return_data = false)
{
    Log::alert('Receive message Content', $request->all());
    $PayToken = $request->get('PayToken');

    if (!$PayToken) {
        Log::alert('PayToken Not exist');
        return ['Status' => 'F'];
    }

    $sinopac = $this->initSinopac();
    $data = $sinopac->requestDataset('OrderPayQuery', $request->all());
    $message = $sinopac->callApi('https://apisbx.sinopac.com/funBIZ/QPay.WebAPI/api/Order', $data);

    $decrypt_message = $this->reply_message_decrypt($sinopac, $message);
    Log::info('Reply message', (array) $decrypt_message);

    $record = sale_order::where('ts_no', $decrypt_message['TSResultContent']['TSNo']);
    if (!$record->count()) {
        Log::alert('Not found order!');
        return ['Status' => 'F'];
    }

    $record->update([
        'pay_token'     => $decrypt_message['PayToken'],
        'ap_type'       => $decrypt_message['TSResultContent']['APType'],
        'status'        => $decrypt_message['Status'],
        'description'   => $decrypt_message['Description']
    ]);

    return $return_data ? $decrypt_message : ['Status' => 'S'];
}

接著修改 Web Controller 的 payment,因為是繼承 Controller,所以可以呼叫到 receive_msg

// app/Http/Controllers/Web.php
public function payment(Request $request)
{
    $message = $this->receive_msg($request, true);
    $order = sale_order::where('ts_no', $message['TSResultContent']['TSNo']);
    $paid = false;
    $display_message = '付款尚未完成';

    if ($message['TSResultContent']['APType'] === 'PayOut') {
        $order->update([
            'pay_datetime' => DateTime::createFromFormat('YmdHi', $message['TSResultContent']['PayDate'])
        ]);

        $paid = true;
        $display_message = '付款完成';
    }

    return view('payment', [
        'paid'      => $paid,
        'message'   => $display_message,
        'order_no'  => $order->first()->order_no
    ]);
}

接著增加 payment.blade.php

// resources/views/payment.blade.php
<h2>訂單 {{ $order_no }}</h2>
<h1>{{ $message }}</h1>

爬 Log 把剛剛紀錄的 json 複製到 Postmen 傳一次要求,看個結果
https://ithelp.ithome.com.tw/upload/images/20210927/20141805PuLQUuSwxX.png

重新產生信用卡訂單後再模擬付款一次,跳轉回來的畫面就跟預想的一樣
https://ithelp.ithome.com.tw/upload/images/20210927/20141805tc9yJrUkuD.png

再看一下訂單清單,有寫進去就行了
https://ithelp.ithome.com.tw/upload/images/20210927/20141805i1g2xbSnuW.png

0x3 今日結語

一開始想說需要再寫一次 initSinopac,突然看到 Web 是繼承 Controller
https://ithelp.ithome.com.tw/upload/images/20210927/20141805pwPQlUTHQA.png
節省不少重寫的時間
明天把查詢訂單API解讀一下,寫個Controller,畫面的話就看時間吧。


上一篇
Day 0x11 - 建立信用卡付款的訂單
下一篇
Day 0x13 - 訂單查詢 (Part1 : Controller & Route)
系列文
試著讀懂與串接永豐金融APIs30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言