# 藍新金流串接教學
本專案已經把金流程式碼寫好了,你只需要完成以下設定就能讓付款功能運作起來。
---
## Step 1:申請藍新金流測試帳號
### 1.1 註冊
前往藍新金流**測試環境**註冊帳號:https://cwww.newebpay.com/
> 注意網址是 `cwww`(測試環境),不是 `www`(正式環境),兩個是不同的系統。
1. 點擊「註冊」
2. 填寫資料、完成信箱驗證
3. 登入測試環境
### 1.2 建立商店
登入後:
1. 左側選單 →「商店管理」→「新增商店」
2. 填寫商店名稱(隨意取,例如:我的健身平台)
3. 送出後你會看到一組 **商店代號(Merchant ID)**,長得像 `MS158471616`,記下來
### 1.3 取得加密金鑰
1. 左側選單 →「商店管理」→ 點擊你剛建立的商店
2. 找到「API 串接金鑰」區塊
3. 記下以下兩組金鑰:
- **HashKey**(32 個字元)
- **HashIV**(16 個字元)
到這裡你應該拿到三樣東西:
| 項目 | 範例 | 字元數 |
|------|------|--------|
| Merchant ID | MS158471616 | 不固定 |
| HashKey | qrIrpjHcMxO5t9ZjIxXifYwTrcKFdikM | 32 |
| HashIV | CzezTxOFNcLEQBNP | 16 |
---
## Step 2:申請 ngrok
ngrok 的用途是讓藍新的伺服器能連到你本機的 `localhost`。沒有它,藍新付款完成後無法通知你的後端。
### 2.1 註冊 ngrok 帳號
前往 https://ngrok.com/ 註冊(可以用 GitHub 登入)。
### 2.2 安裝 ngrok
```bash
# macOS
brew install ngrok
# Windows / 其他系統
# 從 https://ngrok.com/download 下載
```
### 2.3 設定 authtoken
登入 ngrok 後,到 https://dashboard.ngrok.com/get-started/your-authtoken 複製你的 authtoken,然後執行:
```bash
ngrok config add-authtoken 你的authtoken貼在這裡
```
### 2.4 建立免費 domain
ngrok 免費版需要先建立一個固定 domain:
1. 前往 https://dashboard.ngrok.com/domains
2. 點擊「Create Domain」
3. 系統會給你一個 domain,長得像 `barney-wealthiest-stuporously.ngrok-free.dev`
4. 記下這個 domain
### 2.5 啟動 ngrok
確保 Docker 已啟動(backend 跑在 port 8080),然後開另一個終端機執行:
```bash
ngrok http --url=你的domain名稱 8080
```
例如:
```bash
ngrok http --url=barney-wealthiest-stuporously.ngrok-free.dev 8080
```
> ngrok 執行後不要關閉這個終端機視窗,它需要一直開著。
---
## Step 3:設定 .env
打開專案根目錄的 `.env` 檔案,找到藍新金流設定區塊,填入你的資料:
```env
# === 藍新金流設定 ===
NEWEBPAY_MERCHANT_ID=你的商店代號
NEWEBPAY_HASH_KEY=你的HashKey
NEWEBPAY_HASH_IV=你的HashIV
NEWEBPAY_VERSION=2.0
NEWEBPAY_PAY_GATEWAY=https://ccore.newebpay.com/MPG/mpg_gateway
NEWEBPAY_NOTIFY_URL=https://你的ngrok-domain/api/newebpay/notify
NEWEBPAY_RETURN_URL=https://你的ngrok-domain/api/newebpay/return
FRONTEND_URL=http://localhost:3000
```
> 說明:
> - `NEWEBPAY_MERCHANT_ID`、`NEWEBPAY_HASH_KEY`、`NEWEBPAY_HASH_IV` 填入你在 Step 1 取得的值
> - `NEWEBPAY_NOTIFY_URL` 和 `NEWEBPAY_RETURN_URL` 的 domain 換成你在 Step 2 取得的 ngrok domain
> - 其他欄位(`VERSION`、`PAY_GATEWAY`、`FRONTEND_URL`)維持不動即可
> 填錯最常見的問題:
> - HashKey 不是 32 字元 → 加密會失敗
> - HashIV 不是 16 字元 → 加密會失敗
> - NotifyURL / ReturnURL 沒有改成你自己的 ngrok domain → 付款後無法回到你的網站
---
## Step 4:啟動服務
### 4.1 啟動 Docker
```bash
cd 2025-backend-camp
npm run restart
```
等待出現 `Healthy` 和 `Started` 就代表啟動成功。
### 4.2 確認 ngrok 有在跑
開另一個終端機視窗,輸入以下指令檢查 ngrok 是否在執行:
```bash
ps aux | grep ngrok
```
如果有看到類似 `ngrok http --url=你的domain 8080` 的結果,代表 ngrok 正在運作。
如果沒有,回到 Step 2.5 重新啟動 ngrok。
> ngrok 啟動後會佔用那個終端機視窗,所以你需要**至少開兩個終端機**:一個跑 ngrok、一個做其他操作。
### 4.3 確認服務
- 前端:打開 http://localhost:3000 確認有看到網站
- 後端:打開 http://localhost:8080/healthcheck 確認有回應
---
## Step 5:測試付款
### 5.1 註冊帳號
1. 前往 http://localhost:3000/signup
2. 填寫電子郵件、密碼、暱稱
3. 點擊「註冊」
### 5.2 登入
1. 前往 http://localhost:3000/login
2. 用剛註冊的帳號登入
### 5.3 購買方案
1. 前往 http://localhost:3000/fitness-plans
2. 點擊任一方案的「選擇方案」按鈕
3. 瀏覽器會跳轉到藍新金流的付款頁面
### 5.4 在藍新頁面填寫測試信用卡
使用以下**測試用**信用卡資訊:
| 項目 | 填入內容 |
|------|---------|
| 卡號 | `4000-2211-1111-1111` |
| 有效期限 | 任意未來日期,例如 `12/30` |
| 背面末三碼 | `222` |
| 持卡人姓名 | 隨意填,例如 `TEST` |
| 持卡人電話 | 隨意填,例如 `0912345678` |
| 付款人信箱 | 隨意填 |
勾選兩個確認 checkbox,然後點擊「確認送出」。
### 5.5 確認結果
付款成功後,瀏覽器會自動導回前端,顯示:
- 「付款成功」字樣
- 訂單編號
如果看到這個畫面,恭喜你,金流串接成功了!
---
## Step 6:驗證資料庫(選做)
如果想確認資料有正確寫入資料庫,可以用以下指令:
```bash
# 進入資料庫
docker exec -it 2025-backend-camp-postgres-1 psql -U testHexschool -d test
```
```sql
-- 查看訂單狀態(應該看到 payment_status = paid)
SELECT merchant_order_no, amount, payment_status, payment_type FROM "ORDER";
-- 查看購買記錄
SELECT * FROM "CREDIT_PURCHASE" ORDER BY created_at DESC LIMIT 5;
-- 離開資料庫
\q
```
---
## 常見問題排解
### 點擊「選擇方案」後沒有跳轉到藍新
- 打開瀏覽器 F12 → Network 標籤,看 API 有沒有回傳錯誤
- 檢查 `.env` 的 Merchant ID、HashKey、HashIV 是否填寫正確
### 藍新付款頁面顯示「交易資料錯誤」
- 確認 HashKey 是 32 字元、HashIV 是 16 字元
- 到藍新測試後台重新確認金鑰
### 付款成功但沒有導回前端
- 確認 `.env` 的 `NEWEBPAY_RETURN_URL` 是你的 ngrok 網址
- 確認 ngrok 終端機還在執行、沒有斷線
### 前端顯示「付款失敗」但你確定有付款成功
- 確認 `.env` 的 `NEWEBPAY_NOTIFY_URL` 設定正確
- 查看 ngrok 終端機有沒有收到 POST 請求
- 查看後端 logs:`docker logs 2025-backend-camp-backend-1`
### ngrok 出現提示頁面(不是你的網站)
- 這是 ngrok 免費版的正常行為,點擊頁面上的「Visit Site」按鈕即可
---
## 部署到正式環境時
部署時**程式碼不需要改**,只要調整 `.env`:
| 要改的項目 | 怎麼改 |
|-----------|--------|
| `NEWEBPAY_PAY_GATEWAY` | `ccore.newebpay.com` 改成 `core.newebpay.com` |
| `NEWEBPAY_MERCHANT_ID` | 換成正式環境的商店代號 |
| `NEWEBPAY_HASH_KEY` | 換成正式環境的 HashKey |
| `NEWEBPAY_HASH_IV` | 換成正式環境的 HashIV |
| `NEWEBPAY_NOTIFY_URL` | ngrok 網址改成你的正式伺服器網址 |
| `NEWEBPAY_RETURN_URL` | ngrok 網址改成你的正式伺服器網址 |
| `FRONTEND_URL` | `localhost:3000` 改成正式前端網址 |
> 正式環境有自己的網域,藍新可以直接連到你的伺服器,不再需要 ngrok。
> 正式環境的金鑰要到 https://www.newebpay.com/ (注意是 `www` 不是 `cwww`)重新申請。
---
## 補充:付款流程是怎麼運作的?
當使用者點擊「選擇方案」後,整個付款流程如下:
```
使用者點擊「選擇方案」
↓
前端呼叫後端 API,建立一筆訂單(狀態:未付款)
↓
後端把訂單資訊加密,回傳給前端
↓
前端自動跳轉到藍新金流的付款頁面
↓
使用者在藍新頁面填寫信用卡資訊、完成付款
↓
藍新做兩件事(同時進行):
1. NotifyURL:藍新「主動通知」你的後端付款成功
→ 後端收到後更新訂單狀態為「已付款」,並建立購買記錄
2. ReturnURL:把使用者的瀏覽器「導回」你的網站
→ 後端把使用者重新導向到前端的付款結果頁面
```
簡單來說:**你的程式不會直接處理信用卡資訊**,而是交給藍新金流處理。藍新處理完後,再把結果告訴你的後端。
### 付款流程圖

### 前端跳轉到藍新付款頁的原理
你可能會好奇:「前端怎麼跳到藍新的頁面?」
因為一般的 API 呼叫(fetch/axios)只會拿到資料,瀏覽器不會跳頁。所以前端收到後端回傳的加密資料後,會用 JavaScript 自動建立一個「看不見的表單」,表單的 action 指向藍新的網址,然後自動送出。瀏覽器就會跳轉到藍新的付款頁面了。

---
## 補充:每個檔案的用途
以下是金流功能涉及的檔案,說明每個檔案負責什麼事情:
### 後端檔案
| 檔案 | 用途 |
|------|------|
| `backend/config/newebpay.js` | 讀取 `.env` 裡的藍新金流設定(商店代號、金鑰等),讓其他檔案可以方便取用 |
| `backend/entities/Order.js` | 定義「訂單」的資料結構(有哪些欄位、跟哪些資料表有關聯),讓資料庫自動建立對應的表 |
| `backend/utils/newebpayEncrypt.js` | 負責加密和解密:送給藍新的資料需要加密,藍新回傳的資料需要解密 |
| `backend/controllers/order.js` | 處理三件事:①建立訂單 ②收到藍新的付款通知 ③把使用者導回前端 |
| `backend/routes/order.js` | 定義「建立訂單」的 API 路徑,並要求使用者先登入 |
| `backend/routes/newebpay.js` | 定義藍新「通知」和「導回」的 API 路徑(這兩個不需要登入,因為是藍新伺服器呼叫的) |
### 前端檔案
| 檔案 | 用途 |
|------|------|
| `frontend/src/api/order.js` | 呼叫後端的「建立訂單」API |
| `frontend/src/pages/public/FitnessPlans.vue` | 健身方案頁面,點擊「選擇方案」後會建立訂單並跳轉到藍新付款 |
| `frontend/src/pages/public/PaymentResult.vue` | 付款結果頁面,顯示「付款成功」或「付款失敗」 |
| `frontend/src/router/index.js` | 註冊 `/payment-result` 這個頁面路徑 |
### 設定檔
| 檔案 | 用途 |
|------|------|
| `.env` | 存放藍新金流的商店代號、加密金鑰、回呼網址等設定 |