昨天訂單總算建立完成了,今天來把回覆的訊息解開並驗證
回覆的結構如下
{
"Version": "1.0.0",
"ShopNo": "商店代碼",
"APIService": "OrderCreate",
"Sign": "回覆會提供",
"Nonce": "回覆會提供",
"Message": "回覆會提供"
}
解密的需求是 AES key(hash id), IV, Encrypt message,簡單介紹一下流程
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
];
}
...
建立訂單的 Amount 需要有 00 結尾
解密的部分是直接複製範例程式,今天解密就比較順利,
明天把建立訂單的紀錄寫進資料庫,就這樣啦,明天見