Day 0x12 - 建立 Return URL 的画面

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 13 : Maximum Subarray

>>:  DAY13 - 档案类的物件关系厘清(2) - Object URL, Data URI

Day9-TypeScript(TS)的介面型别(Interface)Part 2

今天要来讲介面型别的使用范例。 通常我们会使用介面来定义函式型别,程序码如下, interface ...

那些多人混战的开发经验谈

今年年初,刚好被大学学长推坑 COSCUP 开发组,这次的官网是以去年为基础去做修改的,所以并没有花...

GNU Compiler Collection

GCC 是 GNU Compiler Collection 的简称,GCC 原本称为 GNU C ...

[D29] : 一个Queue+Docker在Local的实作(3/4)

前面说过Passer如何把请求发到MQ去 今天讲Center怎麽去找MQ把请求取出来。 Cente...