AgentSkillsCN

TapPay Integration

TapPay 支付流程对接指南——前端 SDK 配置、后端 API 对接、测试与调试

SKILL.md
--- frontmatter
name: TapPay Integration
description: TapPay 金流串接指南 - 前端 SDK 設定、後端 API 串接、測試與除錯

TapPay 金流串接指南

本 Skill 提供 TapPay 金流系統的完整串接指南,包含前端 SDK 設定、後端 API 呼叫、測試卡號及除錯方法。


1. TapPay 基本概念

付款流程

code
使用者輸入卡號 → 前端取得 Prime → 後端呼叫 Pay by Prime API → 回傳交易結果

兩種付款方式

方式說明使用情境
Pay by Prime使用一次性的 prime 字串進行交易一般單次付款
Pay by Token使用 card_key + card_token 進行交易訂閱制、定期扣款

環境 URL

環境URL
Sandbox (測試)https://sandbox.tappaysdk.com/tpc/payment/pay-by-prime
Production (正式)https://prod.tappaysdk.com/tpc/payment/pay-by-prime

2. 取得串接金鑰

前往 TapPay 廠商管理後台:

  1. APP ID & APP Key: 開發者 → 應用程式
  2. Partner Key: 帳戶資訊
  3. Merchant ID: 商家管理 → 商家設置 → 正式/測試環境

Sandbox 測試金鑰 (本專案使用)

javascript
// 前端 SDK
APP_ID: 166632
APP_KEY: 'app_eLtyNlnXhUY9PkZoJUw8wjU0o7Ts0iCe14YW6CND4AqYmi5hq8KR4PhKL9DA'

// 後端 API
PARTNER_KEY: 'partner_PHNbIt8d88834446583'
MERCHANT_ID: 'GlobalTesting_CTBC'

3. 前端設定 (React/TypeScript)

Step 1: 載入 TapPay SDK

index.html 加入:

html
<script src="https://js.tappaysdk.com/sdk/tpdirect/v5.18.0"></script>

Step 2: 初始化 SDK

typescript
declare const TPDirect: any;

// 設定 SDK
TPDirect.setupSDK(
    166632, // APP_ID
    'app_eLtyNlnXhUY9PkZoJUw8wjU0o7Ts0iCe14YW6CND4AqYmi5hq8KR4PhKL9DA', // APP_KEY
    'sandbox' // 'sandbox' 或 'production'
);

Step 3: 設定信用卡輸入欄位

typescript
TPDirect.card.setup({
    fields: {
        number: {
            element: '#card-number',
            placeholder: '**** **** **** ****'
        },
        expirationDate: {
            element: '#card-expiration-date',
            placeholder: 'MM / YY'
        },
        ccv: {
            element: '#card-ccv',
            placeholder: 'CCV'
        }
    },
    styles: {
        'input': { 'color': 'gray' },
        '.valid': { 'color': 'green' },
        '.invalid': { 'color': 'red' }
    }
});

Step 4: 取得 Prime

typescript
const onSubmit = () => {
    const tappayStatus = TPDirect.card.getTappayFieldsStatus();

    if (tappayStatus.canGetPrime === false) {
        console.error('卡片資訊不完整');
        return;
    }

    TPDirect.card.getPrime((result: any) => {
        if (result.status !== 0) {
            console.error('取得 Prime 失敗:', result.msg);
            return;
        }

        const prime = result.card.prime;
        // 將 prime 傳送至後端
        sendToBackend(prime);
    });
};

HTML 結構

html
<div id="card-number" class="tappay-field"></div>
<div id="card-expiration-date" class="tappay-field"></div>
<div id="card-ccv" class="tappay-field"></div>

4. 後端 API 串接 (Node.js/Express)

Pay by Prime API

typescript
import axios from 'axios';

const TAPPAY_PARTNER_KEY = process.env.TAPPAY_PARTNER_KEY;
const TAPPAY_MERCHANT_ID = process.env.TAPPAY_MERCHANT_ID;
const TAPPAY_URL = 'https://sandbox.tappaysdk.com/tpc/payment/pay-by-prime';

export const payByPrime = async (req, res) => {
    const { prime, amount, orderId } = req.body;

    try {
        const response = await axios.post(TAPPAY_URL, {
            prime,
            partner_key: TAPPAY_PARTNER_KEY,
            merchant_id: TAPPAY_MERCHANT_ID,
            details: "商品描述",
            amount: amount,
            cardholder: {
                phone_number: "0912345678",
                name: "王小明",
                email: "test@example.com"
            },
            remember: false // 設為 true 可取得 card_key/card_token
        }, {
            headers: {
                'Content-Type': 'application/json',
                'x-api-key': TAPPAY_PARTNER_KEY
            }
        });

        const data = response.data;

        if (data.status === 0) {
            // 交易成功
            return res.json({
                success: true,
                transactionId: data.rec_trade_id,
                bankTransactionId: data.bank_transaction_id
            });
        } else {
            // 交易失敗
            return res.status(400).json({
                success: false,
                error: data.msg,
                status: data.status
            });
        }
    } catch (error) {
        console.error('TapPay API Error:', error);
        return res.status(500).json({ error: 'Payment processing failed' });
    }
};

API Request 參數

參數類型必填說明
primestring前端取得的一次性 token
partner_keystring商戶金鑰
merchant_idstring商戶 ID
amountnumber交易金額 (TWD: 1-20,000,000)
detailsstring商品描述
cardholderobject持卡人資訊
rememberboolean是否記憶卡片 (預設 false)

API Response 欄位

欄位說明
status0 = 成功, 其他 = 失敗
msg錯誤訊息
rec_trade_idTapPay 交易編號
bank_transaction_id銀行交易編號
card_key卡片金鑰 (remember=true 時)
card_token卡片 token (remember=true 時)

5. LINE Pay 整合

前端取得 LINE Pay Prime

typescript
TPDirect.linePay.getPrime((result: any) => {
    if (result.status !== 0) {
        console.error('LINE Pay Prime 失敗:', result.msg);
        return;
    }

    const prime = result.prime;
    sendToBackend(prime, 'line_pay');
});

後端處理 (需額外設定)

LINE Pay 需要設定 result_url 用於付款完成後跳轉:

typescript
const response = await axios.post(TAPPAY_URL, {
    prime,
    partner_key: TAPPAY_PARTNER_KEY,
    merchant_id: TAPPAY_MERCHANT_ID,
    amount: amount,
    details: "商品描述",
    cardholder: { /* ... */ },
    result_url: {
        frontend_redirect_url: "https://your-site.com/payment/result",
        backend_notify_url: "https://your-site.com/api/payment/notify"
    }
});

6. 測試卡號

信用卡測試號碼

卡別卡號有效期CCV
VISA (正常)4242-4242-4242-4242任意未來日期123
VISA (3D驗證)4311-9522-2222-2222任意未來日期123
MasterCard5425-2334-3010-9903任意未來日期123
JCB3530-1113-3330-0000任意未來日期123

測試失敗情境

卡號模擬情境
4111-1111-1111-1111餘額不足
4222-2222-2222-2222拒絕交易

7. 錯誤代碼

常見 Status Code

Status說明處理方式
0成功正常處理
-1系統錯誤重試或聯繫 TapPay
10003Prime 已過期 (90秒)重新取得 Prime
10009Prime 已使用重新取得 Prime
100信用卡授權失敗請用戶確認卡片資訊
10007Partner Key 無效檢查金鑰設定

8. 本專案實作參考

相關檔案位置

檔案說明
client/src/components/PaymentModal.tsx前端支付彈窗
server/src/controllers/paymentController.ts後端支付處理
server/src/routes/paymentRoutes.ts支付路由定義

環境變數 (.env)

bash
# TapPay 設定 (後端)
TAPPAY_PARTNER_KEY=partner_xxxxx
TAPPAY_MERCHANT_ID=your_merchant_id

API 端點

code
POST /api/payment/pay
Content-Type: application/json
Authorization: Bearer <token>

{
    "prime": "prime_string_from_frontend",
    "paymentMethod": "credit_card",
    "details": {
        "amount": 90,
        "currency": "TWD"
    },
    "purchaseType": "PREMIUM"
}

9. 除錯指南

前端問題排查

javascript
// 檢查 SDK 是否載入
console.log(typeof TPDirect); // 應為 'object'

// 檢查欄位狀態
const status = TPDirect.card.getTappayFieldsStatus();
console.log(status);
// {
//   canGetPrime: true/false,
//   hasError: true/false,
//   status: { number: 2, expiry: 2, ccv: 2 } // 2=valid, 0=empty, 1=invalid
// }

後端問題排查

bash
# 測試 TapPay API 連線
curl -X POST https://sandbox.tappaysdk.com/tpc/payment/pay-by-prime \
  -H "Content-Type: application/json" \
  -H "x-api-key: partner_PHNbIt8d88834446583" \
  -d '{
    "prime": "test_prime",
    "partner_key": "partner_PHNbIt8d88834446583",
    "merchant_id": "GlobalTesting_CTBC",
    "amount": 100,
    "details": "Test",
    "cardholder": {
      "phone_number": "0912345678",
      "name": "Test",
      "email": "test@test.com"
    }
  }'

常見問題

問題原因解決方式
TPDirect is undefinedSDK 未載入確認 script tag 在 HTML head
canGetPrime = false欄位資訊不完整檢查卡號、日期、CCV 格式
Prime 過期超過 90 秒重新呼叫 getPrime
401 UnauthorizedPartner Key 錯誤檢查 x-api-key header
CORS Error前端直接呼叫 TapPayPrime 要透過後端送出

10. 參考資源


Last Updated: 2026-01-19 Maintainer: Wishlist App Team