> ## Documentation Index
> Fetch the complete documentation index at: https://sdk.qfapi.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 支付組件 (Element) SDK

> 使用 QFPay 的 Element SDK，在您的網站中嵌入卡支付或多種支付方式 UI，兼顧靈活性與支付安全。

QFPay 的 **支付組件（Element）SDK** 可讓商戶使用 QFPay 提供的預建 UI 元件，自行建立結帳流程。

此 SDK 提供靈活的前端整合方式，同時由 QFPay 負責處理敏感支付資料，以符合支付安全及 PCI 規範。

除了標準付款流程外，**信用卡付款**亦支援產生支付 Token，供支援的後續 Token 支付場景使用。

本指南將介紹如何將 QFPay Element SDK 整合至您的網站或應用程式。

***

## 整合流程總覽

![Element Sequence diagram](https://www.plantuml.com/plantuml/png/VLF1ZXCn3BtdAwozmuAuzO1s0Qs4458H7r0bgQTZTPBCEiukvUjn9bEbhO1BbTX-p--zPXwoM9OI9cEz90PVigI033OlPpDhcppDDWhSVKVsOpqzSOg2SG-VH_J7L0Isze1t5HM6Vs0-MNzKI1jorqC_dhRs13XXGBt-_F9jcNeUjFAtmKvLXvpUZ36sI8ebE6HJbSERZwfb0_wiK0rIYYOCIyTTT1YV2whNu6gh4MgRqGh2R4-BAAg6nSIaDQR3AEPn-tK3zsj_jug_Vtb_tv2xSsT5rhWgsZ1AuVWVukiElD8qWKF0NpCnxhKC7zv1e5W4SwSDxcnvNT2okYPhzbko6wsHa9teDuAtl8SXST1rCjwYMg8TE5H9CgumYXLeQxpNqK_aZv2B2oJWYaYApUQ4WvWARqK82geEASmjHNNfJX3MfzCztgX_IKVKcufzwrCSYCDsrJsKw8MkzhLKTeMdwXCqIMBq0dFXEMNiInRw_X3MBFepQVKB8NqWbqaQlcNGUpvLRsgiJiqfwi83fp833N2XZ39alA4uA-qVfwHBp2kwJB8OC2lfOpv5FtAAgUHgYWRoxV_fueFhwdBn7lFDQELxq9yIfZy0)

### 流程摘要

1. 透過 QFPay API 建立 **Payment Intent（支付意圖）**。
2. 使用 `QFpay.config()` 初始化 SDK。
3. 渲染支付介面。
4. 收集顧客付款資料。
5. 使用 `payment.pay()` 或 `payment.walletPay()` 發起付款。
6. 使用 `confirmPayment()` 或 `confirmWalletPayment()` 確認付款結果。
7. 如於信用卡付款時提供 `customer_id`，QFPay 會另外產生對應的 `token_id`。

<Info>
  產生支付 Token 為可選功能。

  如未提供 `customer_id`，系統將按照一般付款流程處理交易，不會產生支付 Token。
</Info>

***

## 支援的支付方式

支付組件（Element）SDK 支援以下支付方式：

* 支付寶（中國內地／香港）
* 微信支付
* 銀聯／雲閃付
* FPS 轉數快
* PayMe
* Visa / Mastercard
* Apple Pay
* Visa / Mastercard 預授權

***

# 整合步驟

## 步驟一：載入 SDK

於您的網頁中引入 SDK：

```html theme={null}
{/* Sandbox */}
<script src="https://cdn-int.qfapi.com/qfpay_element/qfpay.js"></script>

{/* Live Testing */}
<script src="https://test-cdn-hk.qfapi.com/qfpay_element/qfpay.js"></script>

{/* Production */}
<script src="https://cdn-hk.qfapi.com/qfpay_element/qfpay.js"></script>
```

***

## 步驟二：初始化 SDK

初始化 SDK 並設定區域及環境。

```js theme={null}
const qfpay = QFpay.config({
  region: 'hk',
  env: 'prod'
});
```

| 參數       | 必填 | 可選值                      | 說明                                             |
| -------- | -- | ------------------------ | ---------------------------------------------- |
| `region` | 否  | `hk` \| `qa`             | 指定區域。`hk` 為香港正式環境，`qa` 為沙盒環境。                  |
| `env`    | 否  | `prod` \| `test` \| `qa` | 指定執行環境。`prod` 為正式環境，`test` 為線上測試環境，`qa` 為沙盒環境。 |

初始化完成後會回傳全域 `qfpay` 物件，供後續 SDK 操作使用。

***

## 步驟三：建立 Payment Intent（後端）

**API Endpoint：** `/payment_element/v1/create_payment_intent`

**Method：** `POST`

### Headers

| Header         | 必填 | 說明          |
| -------------- | -- | ----------- |
| `X-QF-APPCODE` | 是  | 商戶 App Code |
| `X-QF-SIGN`    | 是  | API 簽名      |

### 請求參數

| 參數             | 必填 | 說明                  |
| -------------- | -- | ------------------- |
| `txamt`        | 是  | 支付金額（單位：分，建議大於 200） |
| `txcurrcd`     | 否  | 幣別，例如 `HKD`         |
| `pay_type`     | 是  | 支付方式代碼              |
| `out_trade_no` | 是  | 商戶訂單號               |
| `mchid`        | 否  | 商戶 ID（代理商模式適用）      |
| `return_url`   | 否  | 支付成功後跳轉網址           |
| `failed_url`   | 否  | 支付失敗後跳轉網址           |
| `notify_url`   | 否  | 支付結果通知網址            |

### 回應範例

```json theme={null}
{
  "respcd": "0000",
  "payment_intent": "38aec7ce...",
  "intent_expiry": "2026-01-01 12:00:00"
}
```

***

## 步驟四：取得 Payment Intent（前端）

完成 Payment Intent 建立後，請於前端取得並驗證 Payment Intent。

```js theme={null}
const qfpay = QFpay.config();

const result = qfpay.retrievePaymentIntent();

if (result.code === '0000') {
  console.log('Payment intent is valid');
} else {
  console.error('Invalid or expired payment intent');
}
```

***

## 步驟五：設定外觀樣式（選用）

初始化 UI 元件處理器，用於渲染信用卡表單或多種支付方式介面。

您可以透過 `appearance` 物件自訂介面樣式及顯示的帳單地址欄位。

```js theme={null}
const appearance = {
  theme: 'night',
  variables: {
    fontFamily: 'cursive',
    fontWeight: '400',
    colorText: 'black',
    sizeFontSubTitle: 'inherit',
    colourBackground: '#fff',
    colourPrimary: '#ced4da',
    colourComponentText: 'purple',
    sizeComponentText: '15px',
    colourErrorMessage: '#da5d4a',
    sizeErrorMessage: 'inherit',
    colorPaymentButton: '#000000',
    colorPaymentButtonText: '#FFFFFF',
    colorQRCodeTopPromptContent: '#000000',
    colorQRCodeBottomPromptContent: '#000000',
    fontWeightQRCodeTopPrompt: '900',
    fontWeightQRCodeBottomPrompt: '300'
  },
  billingAddressDisplay: {
    city: true,
    address1: true,
    address2: true
  }
};

const elements = qfpay.element(appearance);
```

***

## 步驟六：渲染付款介面

### 多種支付方式介面（電子錢包 + 信用卡）

使用 `elements.createEnhance()` 建立支援多種支付方式的付款介面。

```js theme={null}
const elements = qfpay.element(appearance);

elements.createEnhance({
  selector: '#container',
  email: true,
  tab: true,
  element: 'payment',
  lang: 'en'
});
```

### 僅顯示信用卡付款表單

使用 `elements.create()` 建立僅支援信用卡付款的表單。

```js theme={null}
elements.create('#container');
```

***

## 步驟七：發起付款

### 信用卡付款

使用 `payment.pay()` 收集信用卡付款資料並發起付款。

```js theme={null}
payment.pay({
  goods_name: 'Premium Product',
  paysource: 'payment_element'
}, intentParams.payment_intent);
```

### 多種支付方式付款

使用 `payment.walletPay()` 初始化多種支付方式介面。

```js theme={null}
payment.walletPay({
  lang: 'en',
  goods_info: 'Premium membership',
  goods_name: 'VIP Access',
  paysource: 'payment_element_checkout',
  out_trade_no: intentParams.out_trade_no,
  txamt: intentParams.txamt,
  txcurrcd: intentParams.txcurrcd,
  support_pay_type: [
    'Alipay',
    'AlipayHK',
    'WeChat',
    'FPS',
    'UnionPay',
    'PayMe',
    'VisaMasterCardPayment',
    'ApplePay',
    'VisaMasterCardPreAuth'
  ]
}, intentParams.payment_intent);
```

完成 `walletPay()` 呼叫後，請使用 `elements.createWallet()` 將付款介面渲染至指定容器：

```js theme={null}
elements.createWallet({
  selector: '#container'
});
```

<Note>
  * 建議於後端建立 Payment Intent 時，同時產生並回傳 `txamt`、`txcurrcd` 及 `out_trade_no` 給前端使用。
  * 如未指定 `support_pay_type`，SDK 將依商戶已開通的支付方式自動顯示可用選項。
  * `walletPay()` 不會直接回傳最終交易結果，請配合 `qfpay.confirmWalletPayment()` 完成付款確認。
</Note>

***

## （選用）產生支付 Token（僅適用於信用卡付款）

Element SDK 支援於信用卡付款成功後產生支付 Token，方便商戶於支援的 Token 支付場景中使用。

如需產生支付 Token，請於呼叫 `payment.pay()` 時傳入 `customer_id`。

當付款成功完成後，QFPay 會為該顧客建立支付 Token，並回傳對應的 `token_id`。

<Note>
  目前支付 Token **僅支援信用卡付款**。

  使用 `payment.walletPay()` 的電子錢包付款方式目前**不支援**產生支付 Token。
</Note>

<Info>
  產生支付 Token 為選用功能。

  如未提供 `customer_id`，系統將按照一般付款流程處理交易，不會產生 `token_id`。
</Info>

***

### Token 產生流程

1. 建立 Payment Intent。
2. 使用 Element SDK 建立付款介面。
3. 顧客輸入信用卡付款資料。
4. 使用包含 `customer_id` 的 `payment.pay()` 發起付款。
5. 顧客完成付款。
6. QFPay 產生支付 Token。
7. 回傳 `token_id`。
8. 商戶於後端儲存 `token_id`。

***

### Token 相關參數

如需產生支付 Token，可於 `payment.pay()` 中加入以下參數：

| 參數                | 必填            | 說明                                  |
| ----------------- | ------------- | ----------------------------------- |
| `customer_id`     | 是（產生 Token 時） | 商戶自訂的顧客識別碼。提供此欄位後，付款成功時將產生支付 Token。 |
| `token_expiry`    | 否             | 指定支付 Token 的有效期限。                   |
| `token_reason`    | 否             | 商戶自訂的 Token 建立原因，例如綁定卡片或定期付款。       |
| `token_reference` | 否             | 商戶自訂參考編號，可用於對帳或內部追蹤。                |

***

### 範例

```js theme={null}
payment.pay({
  goods_name: 'Premium Product',
  paysource: 'payment_element',
  customer_id: 'CUST123456',
  token_expiry: '2026-01-01',
  token_reason: 'Save Card',
  token_reference: 'INV-0987'
}, intentParams.payment_intent);
```

***

### Token 回傳

當信用卡付款成功且提供 `customer_id` 時，QFPay 將產生支付 Token，並回傳 `token_id`。

<Tip>
  建議商戶於後端安全儲存 `token_id`，並與您的顧客資料建立對應關係。

  請勿僅儲存於瀏覽器或前端應用程式中。
</Tip>

***

### 建議使用 Token 建立通知作為最終結果

雖然 `confirmPayment()` 可能會同步回傳 `token_id`，**QFPay 建議以 Token 建立通知（Token Creation Notification）作為支付 Token 建立成功的最終依據**。

商戶應於收到通知後，再將 `token_id` 寫入後端系統，以確保資料完整及一致。

<Warning>
  **Token 建立通知使用獨立的通知網址（Webhook Endpoint），與一般付款結果通知使用不同的通知網址。**

  如需啟用 Token 建立通知，請聯絡 QFPay Technical Support，並提供以下資料：

  * Merchant ID
  * Store ID
  * Token 建立通知網址（Webhook URL）

  Email：[**technical.support@qfpay.com**](mailto:technical.support@qfpay.com)
</Warning>

<Tip>
  建議將：

  * `confirmPayment()` 的回應作為前端顯示付款結果使用。
  * Token 建立通知作為後端儲存 `token_id` 的最終依據。
</Tip>

<Warning>
  請勿儲存信用卡卡號或其他敏感支付資料。

  請僅儲存由 QFPay 回傳的 `token_id`。
</Warning>
