Day 0x17 - 建立订单(赞助)的画面

0x1 前言

发现缺的东西太多了,所以临时改成投赞助的画面

0x2 修改内容

  • 首页画面
    https://ithelp.ithome.com.tw/upload/images/20211003/20141805eeyTWuocHp.png
// resources/views/welcome.blade.php
<div class="mt-8 bg-white dark:bg-gray-800 overflow-hidden shadow sm:rounded-lg">
    <div class="flex justify-center pt-8 sm:justify-start sm:pt-0">
        <!-- 喜欢的SVG -->
    </div>
    <div class="grid grid-cols-1 md:grid-cols-2">
        <div class="p-6">
            <div class="ml-12">
                <a href="{{url('/donate')}}" class="underline text-gray-900 dark:text-white text-lg font-semibold">Donate</a>
                <div class="mt-2 text-gray-600 dark:text-gray-400 text-sm">
                    Buy Me A Coffee.
                </div>
            </div>
        </div>
    </div>
</div>
  • 建立赞助的画面
    https://ithelp.ithome.com.tw/upload/images/20211003/20141805RUorEFrtmX.png
// resources/views/donate.blade.php
<div
    class="relative flex items-top justify-center min-h-screen bg-gray-100 dark:bg-gray-900 sm:items-center py-4 sm:pt-0">
    <div class="max-w-6xl mx-auto sm:px-6 lg:px-8">
        <div class="mt-8 bg-white dark:bg-gray-800 overflow-hidden shadow sm:rounded-lg">
            <div class="grid">
                <div class="p-6 text-center" style="color: #c8c8c8">
                    @if($show_link)
                        <h3>Thank you! {{ $name }}</h3>
                        <a href="{!! $url !!}">Pay Link</a>
                        @if($otp_url)
                            <br/>
                            <a href="{!! $otp_url !!}">OTP Link</a><br>
                            或 转入此帐号 {{ $atm_pay_no }}
                        @endif
                    @else
                        <form method="POST" class="mt-2 text-gray-600 dark:text-gray-400 text-sm flex items-center"
                              style="flex-direction: column">
                            {{ csrf_field() }}
                            <div class="mt-2">
                                <label for="name">Name:</label>
                                <input type="text" name="name" id="name" required autofocus>
                            </div>
                            <div class="mt-2">
                                <label for="amount">Donate amount:</label>
                                <input type="range" value="30" min="30" max="900" name="amount" id="amount" list="donate-amount-list">
                                <datalist id="donate-amount-list">
                                    <option value="30"></option>
                                    <option value="60"></option>
                                    <option value="90"></option>
                                    <option value="120"></option>
                                    <option value="210"></option>
                                    <option value="300"></option>
                                    <option value="600"></option>
                                    <option value="900"></option>
                                </datalist>
                            </div>
                            <div style="margin: .5em 0">
                                NT$ <span id="display-amount">123</span>
                            </div>
                            <div>
                                <label for="pay-atm">ATM</label>
                                <input type="radio" name="pay-type" id="pay-atm" value="A" required checked>
                                <label for="pay-card">Credit Card</label>
                                <input type="radio" name="pay-type" id="pay-card" value="C" required>
                            </div>

                            <div class="mt-2">
                                <input type="submit" value="Donate" class="text-gray-900 dark text-lg font-semibold">
                                <a href="{{url('/')}}" class="text-gray-900 dark:text-white text-lg font-semibold ml-4">Cancel</a>
                            </div>
                        </form>
                        <script>
                            (function () {
                                let target = document.querySelector('#amount'),
                                    display_target = document.querySelector('#display-amount');

                                target.oninput = function () {
                                    display_target.innerText = this.value;
                                    console.log(this.value);
                                }

                                display_target.innerText = target.value;
                            })();
                        </script>
                    @endif
                </div>
            </div>
        </div>
    </div>
</div>
  • 增加 route
// routes/web.php
Route::match(['GET', 'POST'], 'donate', [Web::class, 'donate']);
  • 增加 controller 函数
// app/Http/Controllers/Web.php
public function donate(Request $request)
{
    if ($request->method() === 'POST') {
        $otp_url = $atm_pay_no = '';
        $amount = $request->post('amount', 30);

        $order = $this->create_order(
            $request->post('name', 'anonymous'),
            $amount,
            $request->post('pay-type', 'A')
        );

        $data = $order['dataset'];
        if ($data['pay_type'] === 'C') {
            $url = $data['card_pay_url'];
        } else {
            $url = $data['web_atm_url'];
            $otp_url = $data['otp_url'];
            $atm_pay_no = $data['atm_pay_no'];
        }

        return view('donate', [
            'show_link' => true,
            'name' => $data['prdt_name'],
            'url' => $url,
            'otp_url' => $otp_url,
            'atm_pay_no' => $atm_pay_no
        ]);
    }

    return view('donate', [
        'show_link' => false
    ]);
}
  • 修正 create_order,并且把 api 的 create_order 注解
public function create_order($name, $amount, $pay_type)
{
    $sinopac = $this->initSinopac();
    $order_no = date('YmdHis');
    $pay_type = ($pay_type === 'C') ? 'C' : 'A';
    $expire_date = date('Ymd', time() + 604800);

    $data = [
        'ShopNo'        => $sinopac->shop_no,
        'OrderNo'       => $order_no,
        'Amount'        => $amount . '00',
        'CurrencyID'    => 'TWD',
        'PrdtName'      => $name,
        'ReturnURL'     => 'https://4fac-2001-b011-b800-e7af-c50-15d3-ec0-74cc.ngrok.io/payment',
        'BackendURL'    => 'https://4fac-2001-b011-b800-e7af-c50-15d3-ec0-74cc.ngrok.io/api/receive_msg',
        'PayType'       => $pay_type,
    ];

    if ($pay_type === 'C') {
        $data['CardParam'] = ['AutoBilling' => 'Y'];
    } else {
        $data['ATMParam'] = ['ExpireDate' => $expire_date];
    }

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

    $decrypt_message = $this->reply_message_decrypt($sinopac, $message);
    $description = $this->description_process($decrypt_message);

    if ($description['status'] !== 'S0000') {
        Log::alert('订单未建立成功', $decrypt_message);
    }

    $dataset = [
        'customer_id'       => 0,
        'order_no'          => $order_no,
        'total'             => $amount,
        'pay_type'          => $pay_type,
        'expire_date'       => $expire_date,
        'ts_no'             => $decrypt_message['TSNo'],
        'status'            => $description['status'],
        'description'       => $description['description'],
        'mailing_address'   => '',
        'prdt_name'         => $name,
    ];
    if ($pay_type === 'C') {
        // 信用卡
        $card_param = $decrypt_message['CardParam'];
        $dataset = array_merge($dataset, [
            'card_pay_url'  => $card_param['CardPayURL'],
        ]);
    } else {
        // 虚拟帐号
        $atm_param = $decrypt_message['ATMParam'];
        $dataset = array_merge($dataset, [
            'atm_pay_no'    => $atm_param['AtmPayNo'],
            'web_atm_url'   => $atm_param['WebAtmURL'],
            'otp_url'       => $atm_param['OtpURL'],
        ]);
    }
    $id = sale_order::create($dataset)->id;

    return [
        'dataset' => $dataset,
        'id' => $id
    ];
}
  • 测试出来的画面如下
    • ATM
      https://ithelp.ithome.com.tw/upload/images/20211003/20141805SkIpysGLkX.png
    • 信用卡
      https://ithelp.ithome.com.tw/upload/images/20211003/20141805bwc2zVl7BY.png

0x3 今日结语

临时改成非常简单的赞助画面,东西缺的有点多,
因为还有其他事情要处理,只能先这样应急了,不然文章写不出来,
明天会对於laravel 开发的过程做个结论,以及自我检讨的部分
第25天到30天会对於odoo addons的开发进行动作。


<<:  Day17【Web】网路攻击:点击劫持 Clickjacking

>>:  [Day21]- 正则表达式

Ruby on Rails RESTful 网址设计

REST 是 Representational State Transfer 的缩写,中⽂翻译成「具...

第二十九日-MYSQL预存程序 STORED PROCEDURE:来写一个BMI小程序(2)

昨天已经认识分隔符号 DELIMITER和STORED PROCEDURE建立语法, 建立出BMI小...

[FHIR 从入门到放弃] Day 02-FHIR 基本概念

因为工作关系,忙到没空写文,拖稿拖了好久...... FHIR 是什麽,能吃吗? 为什麽会有 FHI...

[Day 02] 建立开发环境,做好行前准备

老套说:「工欲善其事,必先利其器」— 要写网页,就不能没有好用的开发环境。在开始认识各种前端技能之前...

Day10:今天来讲一下microsoft defender for endpoint的装置执行动作

在我们导入microsoft defender for endpoint後,我们主要工作是修复事件。...