Day 0xD - 解开建立订单回覆的讯息,建立订单的 Amount 要注意

0x1 前言

昨天订单总算建立完成了,今天来把回覆的讯息解开并验证

0x2 处理流程

  • 回覆的结构如下

    {
     "Version": "1.0.0",
     "ShopNo": "商店代码",
     "APIService": "OrderCreate",
     "Sign": "回覆会提供",
     "Nonce": "回覆会提供",
     "Message": "回覆会提供"
    }
    
  • 解密的需求是 AES key(hash id), IV, Encrypt message,简单介绍一下流程

    1. 用回覆的 Nonce 计算 IV
    2. 用自己的 4 把 Hash key 算出 hash id
    3. 解密加密讯息
    4. 验证讯息是否跟 Sign 相符
    5. 判断回覆的状态是否为 S0000 – 处理成功 (要注意那个减号不是 \x2D 的那个减号,是全形吗? 需要大神解释一下)

程序如下

// app/Http/Controllers/Controller.php
...
public function create_order(Request $request)
{
    $sinopac = $this->initSinopac();
    $data = [
        'ShopNo'        => $sinopac->shop_no,
        'OrderNo'       => 'A' .date('YmdHis'),
        'Amount'        => random_int(4000, 10000) . '00',
        'CurrencyID'    => 'TWD',
        'PrdtName'      => '大河',
        'ReturnURL'     => $request->getBaseUrl() . '/order_reply',
        'BackendURL'    => $request->getBaseUrl() . '/receive_msg',
        'PayType'       => 'A',
        'ATMParam'      => [
            'ExpireDate' => date('Ymd', time() + 604800),
        ],
    ];

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

    $reply_nonce = $message['Nonce'] | '';
    if (!$reply_nonce) {
        $msg = 'Reply message haven\'t Nonce';
        Log::error($msg , $message);
        throw new \HttpResponseException($msg);
    }

    // 1. nonce 计算 iv
    $iv = $sinopac->calculateIv($reply_nonce);
    // 2. 计算 hash_id (AES key)
    $hash_id = $sinopac->calcHashId();
    // 3. message 解密
    $decrypt_message = $sinopac->decryptMessage($message['Message'], $hash_id, $iv);
    // 4. 验证 sign
    $sign = $sinopac->generateSign($decrypt_message, $reply_nonce, $hash_id);

    if (!($sign === $message['Sign'])) {
        throw new \HttpResponseException('验证错误,内文签章不同');
    }

    // 这里的 – 是 \xE2  不是 \x2D
    $description = explode(' – ', $decrypt_message['Description']);
    if ($description[0] !== 'S0000') {
        Log::alert('订单未建立成功', $decrypt_message['Description']);
        throw new \HttpResponseException("订单未建立成功");
    }

    return [
        'Reply_Message' => $message,
        'Decrypt_content' => $decrypt_message
    ];
}
...

0x3 补充

建立订单的 Amount 需要有 00 结尾
https://ithelp.ithome.com.tw/upload/images/20210922/201418057yzKCJeNTs.png

0x4 今日结语

解密的部分是直接复制范例程序,今天解密就比较顺利,
明天把建立订单的纪录写进资料库,就这样啦,明天见


<<:  Day 08 : Longest Mountain in Array

>>:  [Day 9] - 『转职工作的Lessons learned』 - GraphQL (Hasura) - Webhook身份验证

Day2-LeetCode 118. Pascal's Triangle

Problem: 118. Pascal's Triangle(Easy) Pascal's Tri...

如何衡量程序的好与坏?浅谈时间复杂度

刷题的重点在於写出「好的」程序码 就如同前两天提到的,比起盲目地刷题更重视的是如何写出好的程序码品...

Day 10. 状况篇 Zabbix 安装问题排除

今天跟大家分享从维运手册调出来的遇到问题与排除。 就是如果在 WEB 介面设定完以後发现设定失败该怎...

【我可以你也可以的Node.js】第二五篇 - 蛞蝓能不能变蜗牛 #租房是残忍的 #我好想要有个家

事情是这样的,我最近一直都在忙找新的租屋处, 不续租的原因有很多,最主要的原因是目前的房子会漏水啊...

[Day25] - Using Redux with Web Component

使用组件跟组件的组合 , 形成一个页面 势必会遇到经典的组件传值 issue (下图左侧) 以大家常...