跳至主要内容

2 篇文章 含有標籤「第三方支付」

檢視所有標籤

金流使用 Hash 原因入門教學筆記 | 學習筆記

· 閱讀時間約 5 分鐘
kdchang

在金流(第三方支付或自建金流)系統中使用 Hash(雜湊) 的原因,主要是為了安全性防止資料被竄改。以下是更詳細的解釋:


一、為什麼金流需要 Hash?

金流交易涉及敏感資料(如金額、訂單編號、使用者資訊、驗證參數等),若這些資料在傳輸過程中被竄改,將造成:

  • 金額錯誤(被調整為更小金額)
  • 偽造付款成功通知
  • 使用者資料外洩
  • 金流詐騙行為

因此,金流平台與商家之間需要一種方式來驗證資料完整性與來源,這就是使用 Hash 的目的。


二、Hash 的功能與好處

1. 防止資料被竄改

將參數與商家的金鑰(如 HashKey, HashIV, Secret) 一起進行加密產生 Hash,當接收到資料時重新運算比對 Hash 是否一致,可判斷資料是否遭到中間人修改。

2. 驗證資料來源(防偽)

因為 Hash 中包含商家密鑰,只有商家與金流平台知道,第三方無法偽造相同的 Hash 值。

3. 簽章比對(防止偽造)

如同電子簽章,確保伺服器回傳的付款成功訊息未被偽造。


三、常見應用場景

  1. 交易請求(Payment Request)

    • 商家送出訂單資訊與 Hash 到金流平台。
    • 金流平台驗證 Hash 是否正確。
  2. 金流回傳通知(Callback)

    • 金流平台回傳付款成功訊息與 Hash。
    • 商家伺服器驗證 Hash 是否正確,確保通知未被偽造。

四、常見演算法

常用於金流驗證的 Hash 演算法包括:

  • SHA-256(常見於 Line Pay、藍新金流)
  • SHA-1 / MD5(部分舊系統使用,不建議,因為已知有碰撞風險)

五、範例(以 SHA-256 為例)

import hashlib
import urllib.parse

def generate_hash(params, hash_key, hash_iv):
# 1. 排序參數
sorted_params = sorted(params.items())

# 2. 組合參數字串
query = urllib.parse.urlencode(sorted_params)

# 3. 加入 HashKey 和 HashIV
raw = f"HashKey={hash_key}&{query}&HashIV={hash_iv}"

# 4. URL encode 並轉為小寫
encoded = urllib.parse.quote_plus(raw).lower()

# 5. SHA-256 雜湊後轉大寫
hash_value = hashlib.sha256(encoded.encode('utf-8')).hexdigest().upper()

return hash_value

六、重點摘要

  • 什麼是 Hash?

    • 一種不可逆的單向編碼函數。
    • 輸入內容不論長短,輸出皆為固定長度的字串(雜湊值)。
  • Hash 的特性

    • 不可逆性(無法由輸出推回輸入)。
    • 輸入微幅變動會產生截然不同的結果。
    • 相同輸入會產生相同輸出(穩定性)。
  • 金流為何需要 Hash?

    1. 資料驗證:確保交易資料在傳送過程未遭竄改。
    2. 身份驗證:用來確認請求是否來自可信來源(如商家端或金流平台)。
    3. 防止偽造:Hash 搭配密鑰可防止惡意第三方偽造交易請求。
    4. 簽章與紀錄:用於產生交易紀錄摘要,利於日後比對查核。
  • 常見應用場景

    • 第三方金流(如:藍新、綠界、Line Pay)API 請求驗證。
    • 商店端對回傳交易結果進行驗證(例如 callback 處理)。
    • 加密交易參數避免資料外洩。

實際範例

以下以台灣常見的金流服務商 綠界科技(ECPay) 為例,說明 Hash 如何在金流流程中使用。

📌 模擬付款請求流程中的 Hash 機制

假設我們要透過金流平台建立一筆訂單,商家需呼叫綠界的 API 送出交易請求,為確保資料未被竄改,綠界要求每筆請求需附帶經 Hash 加密的驗證碼(CheckMacValue)。

1. 建立交易資料

MerchantID=2000132
MerchantTradeNo=KD123456789
MerchantTradeDate=2025/06/12 15:00:00
PaymentType=aio
TotalAmount=1000
TradeDesc=測試交易
ItemName=測試商品1件
ReturnURL=https://www.kdchang.me/callback
ChoosePayment=ALL

2. 組合字串(需加上 HashKey 與 HashIV)

HashKey=5294y06JbISpM5x9
HashIV=v77hoKGq4kWxNNIS

組合前格式如下(依照參數 ASCII 排序):
HashKey=5294y06JbISpM5x9&ChoosePayment=ALL&ItemName=測試商品1件&MerchantID=2000132&MerchantTradeDate=2025/06/12 15:00:00&MerchantTradeNo=KD123456789&PaymentType=aio&ReturnURL=https://www.kdchang.me/callback&TotalAmount=1000&TradeDesc=測試交易&HashIV=v77hoKGq4kWxNNIS

3. 進行 URL Encode 與轉成小寫,再做 Hash(通常使用 SHA256)

經過 SHA256 計算後會得到一段長度為 64 字元的十六進位字串:

CheckMacValue=5F8BCE79E9D2748F443D751B34EC5085EDB8C52265521FC42D6F807F208F47D2

此值將作為驗證碼隨交易資料一併傳送至金流平台。

4. 綠界端驗證流程

綠界收到資料後,會根據相同的規則計算一次 Hash 值並與商家提供的 CheckMacValue 比對,若一致,才表示資料未遭竄改,交易請求才會被接受。


延伸說明:為什麼不用密碼明文?

有些人可能會問:「為何不直接傳送密碼或 token 來驗證身分?」原因在於:

  • 密碼若明文傳輸容易被攔截。
  • 即使是 HTTPS 傳輸,也無法防止伺服器端遭駭後資料外洩。
  • Hash 機制能將敏感資訊加密為單向摘要,即使外洩也難以還原原始資料。

若搭配 時間戳記一次性 tokenHMAC(含密鑰的 Hash),可大幅提升安全性。

七、總結

金流使用 Hash 的核心目的是「確保資料未被篡改並驗證來源合法性」。它就像資料的「指紋」,能保證交易資訊的完整性與安全性。若缺乏這種驗證機制,金流系統就容易遭受攻擊或詐騙,對商家與消費者都造成風險。

因此,不論是在串接金流 API、處理回傳通知或比對訂單資訊時,妥善處理 Hash 的生成與比對,是金流串接不可忽略的重要環節。

LINE Pay API 入門教學筆記 | 學習筆記

· 閱讀時間約 4 分鐘
kdchang

一、前言

在電子商務與線上交易日益普及的今天,提供穩定又方便的金流服務已成為網站與應用程式不可或缺的一環。LINE Pay 是由 LINE Corporation 推出的行動支付平台,除了在線上與實體店面支援消費者付款外,也提供開發者 API 介面來整合第三方商務服務,使開發者可以在網站或應用程式中無縫串接付款功能。

本篇教學筆記將帶你了解 LINE Pay API 的基本觀念、運作流程,以及如何透過簡單的實作實現付款功能,協助你更快進入金流整合領域。


二、重點摘要

  • LINE Pay 是 LINE 提供的電子支付平台,可整合至網站或 App。

  • LINE Pay API 採用 RESTful 設計,以 HTTPS POST/GET 傳遞 JSON 格式。

  • API 主要分為以下幾個步驟:

    • Request:建立付款請求
    • Redirect:用戶跳轉至 LINE Pay 完成付款
    • Confirm:付款成功後確認交易
  • 使用前需在 LINE Pay 商戶後台 申請帳戶與 Channel。

  • API 使用需要 Channel ID、Channel Secret Key,以及測試或正式的 LINE Pay API Endpoint。

  • 所有請求需附加簽章(Signature Header)以進行授權與安全驗證。

  • 支援多種付款方式(LINE Pay 錢包、信用卡、優惠券等)。


三、整體交易流程圖

  1. 使用者在你的網站點擊「立即付款」
  2. 後端呼叫 request API 建立交易
  3. 將使用者導向 LINE Pay 的付款畫面
  4. 用戶完成付款後,LINE 會導回你設定的 redirect URL
  5. 你後端呼叫 confirm API 完成交易驗證

四、準備工作

  1. 註冊商戶帳號:至 LINE Pay Developer Center 申請開發者帳號與商戶帳戶。
  2. 建立 Channel:建立 LINE Pay Channel 取得 Channel IDChannel Secret Key
  3. 設定 Redirect URL:設置付款成功/失敗的回傳網址。
  4. 測試環境:LINE Pay 提供 Sandbox 環境(沙盒),可模擬交易流程。

五、實際範例(使用 Python Flask 示範)

1. 建立付款請求:/create_payment

import requests, json, time, hashlib, hmac
from flask import Flask, redirect, request

app = Flask(__name__)

CHANNEL_ID = '你的Channel ID'
CHANNEL_SECRET = '你的Secret Key'
LINE_PAY_ENDPOINT = 'https://sandbox-api-pay.line.me'
CONFIRM_URL = 'https://你的網站.com/confirm_payment'
RETURN_HOST = 'https://你的網站.com'

def generate_signature(uri, body, nonce, secret):
message = secret.encode('utf-8')
raw = f"{secret}{uri}{json.dumps(body, separators=(',', ':'))}{nonce}"
return hmac.new(message, raw.encode('utf-8'), hashlib.sha256).hexdigest()

@app.route('/create_payment')
def create_payment():
uri = '/v3/payments/request'
url = f"{LINE_PAY_ENDPOINT}{uri}"
nonce = str(int(time.time() * 1000))
headers = {
'Content-Type': 'application/json',
'X-LINE-ChannelId': CHANNEL_ID,
'X-LINE-Authorization-Nonce': nonce,
'X-LINE-Authorization': generate_signature(uri, {
"amount": 100,
"currency": "TWD",
"orderId": "ORDER123456",
"packages": [{
"id": "1",
"amount": 100,
"name": "商品",
"products": [{"name": "測試商品", "quantity": 1, "price": 100}]
}],
"redirectUrls": {
"confirmUrl": CONFIRM_URL,
"cancelUrl": f"{RETURN_HOST}/cancel"
}
}, nonce, CHANNEL_SECRET)
}

body = {
"amount": 100,
"currency": "TWD",
"orderId": "ORDER123456",
"packages": [{
"id": "1",
"amount": 100,
"name": "商品",
"products": [{"name": "測試商品", "quantity": 1, "price": 100}]
}],
"redirectUrls": {
"confirmUrl": CONFIRM_URL,
"cancelUrl": f"{RETURN_HOST}/cancel"
}
}

res = requests.post(url, headers=headers, json=body)
res_data = res.json()
payment_url = res_data['info']['paymentUrl']['web']
return redirect(payment_url)

2. 完成付款後確認交易:/confirm_payment

@app.route('/confirm_payment')
def confirm_payment():
transaction_id = request.args.get('transactionId')
uri = f"/v3/payments/{transaction_id}/confirm"
url = f"{LINE_PAY_ENDPOINT}{uri}"
nonce = str(int(time.time() * 1000))
body = {
"amount": 100,
"currency": "TWD"
}
headers = {
'Content-Type': 'application/json',
'X-LINE-ChannelId': CHANNEL_ID,
'X-LINE-Authorization-Nonce': nonce,
'X-LINE-Authorization': generate_signature(uri, body, nonce, CHANNEL_SECRET)
}
res = requests.post(url, headers=headers, json=body)
return res.json()

六、注意事項

  • 所有請求必須使用 HTTPS。
  • 金額與幣別需與建立交易時一致,否則確認交易會失敗。
  • 建議使用 UUID 或時間戳記作為 orderId 以避免重複。
  • 正式環境與 Sandbox 的 API Endpoint 不同,測試時請使用 sandbox 網址。

七、總結

LINE Pay API 提供了強大的付款整合能力,對於電商網站、小型應用或自有服務都有極大的幫助。透過良好的 API 設計與嚴謹的安全驗證,開發者可以快速、安全地建置付款機制。建議開發者先熟悉 sandbox 測試流程,再導入正式環境,以確保交易安全與穩定性。

若你有更多需求,例如分期付款、自動收款、退款等,也可進一步參考官方完整文件:LINE Pay API 技術文件