---
url: >-
https://acquirer-api-docs-v4-en.pingpongx.com/notes/zh/integrate/sdk-elements/index.md
description: 说明 PingPong Element SDK 的组件化接入方式,覆盖支付元素创建、事件监听、下单支付和钱包绑定场景。
---
# PingPong Element SDK 集成指南
## SDK集成流程
```mermaid
%%{init: {
'theme': 'base',
'themeVariables': {
'primaryColor': '#E3F2FD',
'primaryTextColor': '#0D47A1',
'primaryBorderColor': '#1976D2',
'lineColor': '#1565C0',
'secondaryColor': '#BBDEFB',
'tertiaryColor': '#90CAF9',
'background': '#F8FBFF',
'mainBkg': '#E3F2FD',
'secondBkg': '#BBDEFB',
'tertiaryBkg': '#90CAF9',
'actorBkg': '#2196F3',
'actorBorder': '#1976D2',
'actorTextColor': '#FFFFFF',
'actorLineColor': '#1565C0',
'signalColor': '#0D47A1',
'signalTextColor': '#0D47A1',
'c0': '#E8F4FD',
'c1': '#D1E7DD',
'c2': '#B3D9FF',
'c3': '#81C784',
'noteBkgColor': '#E1F5FE',
'noteTextColor': '#01579B',
'noteBorderColor': '#0288D1',
'loopTextColor': '#0D47A1',
'activationBkgColor': '#B3E5FC',
'activationBorderColor': '#0277BD'
}
}}%%
sequenceDiagram
participant User as 👤 用户
participant Browser as 🌐 浏览器
participant Frontend as 💻 商户前端
participant Backend as 🏪 商户后端
participant SDK as 📦 Element SDK
participant PP as 🔄 PingPong服务端
Note over User, PP: 🚀 Element SDK 完整集成流程
User->>Browser: 1. 选择商品
Browser->>Frontend: 2. 打开支付页面
Note over Frontend, Backend: 📋 初始化阶段
Frontend->>+Backend: 3. 请求初始化 sdkAccessToken
Backend->>+PP: 4. 请求初始化 sdkAccessToken
PP-->>-Backend: 5. 返回初始化 sdkAccessToken
Backend-->>-Frontend: 6. 返回初始化 sdkAccessToken
Frontend->>+SDK: 7. 使用 sdkAccessToken 初始化 SDK
Note right of SDK: PingPongSDK.init()
SDK->>+PP: 8. 查询店铺配置
PP-->>-SDK: 9. 返回店铺配置
SDK-->>-Frontend: 10. SDK 初始化完成
SDK->>Frontend: 11. 触发 ready 事件
Frontend->>SDK: 12. 创建支付元素
Note right of SDK: createElement()
SDK-->>Frontend: 13. 支付元素已就绪
Frontend->>Browser: 14. 在支付页面中渲染支付按钮
Note over User, PP: 💳 支付流程开始
Frontend->>User: 15. 显示支付按钮
User->>Frontend: 16. 点击支付按钮
Frontend->>+SDK: 17. 触发支付流程
SDK->>+Frontend: 18. 调用 createOrder()
activate Frontend
Note over Frontend: 校验 billing、shipping、优惠券
Frontend->>+Backend: 19. 发送订单详情
Backend->>+PP: 20. 下单(原V4下单接口)
PP-->>-Backend: 21. 返回交易 token
Backend-->>-Frontend: 22. 返回交易 token
Frontend-->>-SDK: 23. 从 createOrder 返回 token
deactivate Frontend
SDK->>+PP: 24. 请求支付(支付信息 + token)
PP->>PP: 25. 处理支付
Note right of PP: • 风控检查
• 支付路由
• 第三方调用
PP-->>-SDK: 26. 支付响应
alt ❌ 支付失败
SDK->>Frontend: 27. 调用 error(code, msg)
activate Frontend
Note over Frontend: 处理支付失败逻辑
deactivate Frontend
else ✅ 支付成功或处理中
SDK->>Browser: 28. 跳转到支付结果页面
Note right of Browser: merchantResultUrl
else 🔒 需要 3DS 验证
SDK->>Browser: 29. 跳转到 3DS 验证页面
end
Note over User, PP: 🎯 支付流程结束
```
## 架构设计
### 核心模块
| 模块 | 职责 |
| --- | --- |
| **PingPongSDK** | SDK 唯一入口,暴露 init / createElement 方法 |
| **PingPongElement** | 所有支付按钮的基类,提供 .on() / .off() 事件机制 |
### 支付模式
SDK 支持两种主要模式:
- **Payment**: 下单并支付模式,适用于标准支付流程
- **Vault**: PayPal 独立签约模式,用于绑定钱包
## 接入流程
### 1. 获取 sdkAccessToken
商户后端系统通过调用获取 sdkAccessToken 接口得到访问凭证。
**支付场景:**
- 调用 `/v4/session/init` 接口获取 sdkAccessToken
**签约场景:**
- POST 调用已有签约接口获取 sdkAccessToken 和 JS URL
### 2. 引入 Element SDK
根据您的业务环境,选择相应的 SDK 版本进行引入:
:::: code-tabs
@tab 🧪 沙箱环境
```html
```
@tab 🇪🇺 FRA 生产环境
```html
```
@tab 🇸🇬 SG 生产环境
```html
```
::::
### 3. 初始化 SDK
#### 入参说明
::::: field-group
:::: field name="mode" type="string" required
业务模式
`Payment`(支付) 或 `Vault`(PayPal 独立签约)
::::
:::: field name="env" type="string" required
运行环境
`sandbox`(沙箱) 或 `production`(生产)
::::
:::: field name="amount" type="string" required
交易金额
用于收银台展示
::::
:::: field name="currency" type="string" required
交易币种
::::
:::: field name="country" type="string" required
国家/地区代码
如 `US`、`CN`、`UK` 等
::::
:::: field name="accId" type="string" required
商户账户 ID
::::
:::: field name="locale" type="string" required
界面语言
`en`、`zh-CN` 等
::::
:::: field name="region" type="string" optional default="fra"
地区
`sg` 或 `fra`
::::
:::: field name="sdkAccessToken" type="string" required
SDK 访问凭证
::::
:::: field name="merchantResultUrl" type="string" required
支付完成后的跳转地址
::::
:::: field name="createOrder" type="Function" optional
下单函数
mode 为 `Payment` 时必传。该函数接收一个包含 `payMethod` 的对象参数,表示用户选择的支付方式
::::
:::: field name="goods" type="Array" required
商品信息数组
详见下方 [goods 数组结构](#goods-数组结构)
::::
:::: field name="biztype" type="string" optional
业务类型
可选值: `CodeGrant`
::::
:::: field name="recurringInfoDTO" type="Object" optional
Recurring 配置,ApplePay 签约必传
::::
:::::
#### 初始化示例
```javascript:line-numbers title="src/sdk-init.js"
await PingPongSDK.init({
mode: 'Payment', // 业务模式: Payment 或 Vault
env: 'sandbox', // 运行环境
amount: '19.99', // 交易金额
currency: 'USD', // 交易币种
country: 'US', // 国家/地区代码
accId: 'ACC_123', // 商户账户ID
locale: 'en', // 语言设置
region: 'fra', // 地区: sg 或 fra
sdkAccessToken: 'your_sdk_token', // SDK访问令牌
merchantResultUrl: 'https://merchant-result.com', // 支付完成跳转地址
// mode 为 Payment 时必传
createOrder: async ({payMethod}) => {
console.log('用户选择的支付方式:', payMethod);
// 调用商户后端下单接口
const response = await fetch('/xx/xx', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
payMethod, // 传递支付方式到后端
xx: 'xx'
})
});
const result = await response.json();
return result.token; // 返回订单 token
},
// 商品信息数组(必填)
goods: [
{
name: '商品名称',
description: '商品描述',
imgUrl: 'https://example.com/product.jpg',
sku: 'SKU123',
unitPrice: '19.99',
number: '2',
virtualProduct: 'N'
}
],
// ApplePay 签约时必传
recurringInfoDTO: {
recurringPaymentStartDate: '2024-06-01 00:00:00',
recurringPaymentIntervalUnit: 'month',
recurringPaymentIntervalCount: '6',
recurringPaymentEndDate: '2024-12-01 00:00:00'
}
});
```
### goods 数组结构
商品信息数组包含每个商品的详细信息。
::::: field-group
:::: field name="name" type="string" required
商品名称
::::
:::: field name="description" type="string" optional
商品描述
::::
:::: field name="imgUrl" type="string" optional
商品图片 URL
::::
:::: field name="sku" type="string" optional
商品 SKU
::::
:::: field name="unitPrice" type="string" required
商品单价
::::
:::: field name="number" type="string" required
商品数量
::::
:::: field name="virtualProduct" type="string" optional
是否为虚拟产品
`Y` 或 `N`
::::
:::::
**示例:**
```javascript:line-numbers title="src/goods-example.js"
goods: [
{
name: '无线蓝牙耳机',
description: '高品质音质,30小时续航',
imgUrl: 'https://cdn.example.com/product1.jpg',
sku: 'HEADPHONE-BT-001',
unitPrice: '99.99',
number: '1',
virtualProduct: 'N'
},
{
name: '音乐会员月卡',
description: '畅听千万首正版音乐',
imgUrl: 'https://cdn.example.com/product2.jpg',
sku: 'VIP-MUSIC-1M',
unitPrice: '15.00',
number: '1',
virtualProduct: 'Y'
}
]
```
### 4. 创建支付元素
#### 4.1 Apple Pay 按钮
```javascript:line-numbers title="src/apple-pay.js"
const applePay = await PingPongSDK.createElement('applePayButton', {
buttonType: 'buy', // 按钮类型: buy | plain
buttonColor: 'black', // 按钮颜色: black | white | white-outline
style: {
width: '100%',
height: '40px',
borderRadius: '4px'
},
payDiscount: { // 营销活动配置(可选)
activityNo: 'EEE',
costAmount: '19.99', // 原始金额
discountAmount: '2.00' // 折扣金额
}
});
```
#### 4.2 Google Pay 按钮
```javascript:line-numbers title="src/google-pay.js"
const googlePay = await PingPongSDK.createElement('googlePayButton', {
buttonType: 'buy', // 按钮类型: buy | subscribe
buttonColor: 'black', // 按钮颜色: black | white
isChallengeIframe: true, // 使用 iframe 展示 3DS Challenge 页面
style: {
width: '100%',
height: '40px',
borderRadius: '4px'
},
payDiscount: {
activityNo: 'EEE',
costAmount: '19.99',
discountAmount: '2.00'
}
});
```
**Google Pay options 参数:**
::::: field-group
:::: field name="buttonType" type="string" optional
按钮类型,可选值:`buy`、`subscribe`
::::
:::: field name="buttonColor" type="string" optional
按钮颜色,可选值:`black`、`white`
::::
:::: field name="isChallengeIframe" type="boolean" optional
是否使用 iframe 展示 3DS Challenge 页面。当设置为 `true` 时,将通过 iframe 承载 Challenge 流程。
::::
:::: field name="style" type="object" optional
按钮样式配置
::::
:::: field name="payDiscount" type="object" optional
营销活动配置
::::
:::::
#### 4.3 PayPal 按钮
```javascript:line-numbers title="src/paypal.js"
const paypal = await PingPongSDK.createElement('paypalButton', {
buttonType: 'buttons', // buttons | marks | card-fields | funding-eligibility
style: {
borderRadius: 4,
color: 'gold', // gold | blue | silver | white | black
height: 40,
label: 'paypal', // paypal | checkout | buynow | pay | installment | subscribe | donate
layout: 'vertical', // vertical | horizontal
shape: 'rect' // rect | pill | sharp
}
});
// PayPal 不需要监听 completed 事件
// 当支付完成时,SDK 会发起重定向到 merchantResultUrl
```
### 5. 事件监听
所有支付元素都支持统一的事件模型:
```javascript:line-numbers title="src/event-listeners.js"
// 监听 ready 事件
applePay.on('ready', () => {
console.log('Apple Pay 已渲染');
});
// 监听 success 事件
applePay.on('success', (event) => {
console.log('Apple Pay 支付完成', event.detail);
// event.detail 包含 transactionId 等信息
});
// 监听 error 事件
applePay.on('error', (event) => {
console.error('Apple Pay 错误', event.detail);
// event.detail 包含 code 和 message
});
// 监听 cancel 事件
applePay.on('cancel', () => {
console.log('Apple Pay 用户取消');
});
```
### 6. 挂载与卸载
```javascript:line-numbers title="src/lifecycle.js"
// 挂载到指定容器
applePay.mount('#apple-pay-container');
// 卸载元素
applePay.unmount();
```
## API 参考
### PingPongSDK.init()
初始化 SDK 配置。
**参数:**
::::: field-group
:::: field name="mode" type="string" required
`Payment` 或 `Vault`
::::
:::: field name="env" type="string" required
`sandbox` 或 `production`
::::
:::: field name="amount" type="string" required
交易金额
::::
:::: field name="currency" type="string" required
交易币种
::::
:::: field name="country" type="string" required
国家/地区代码
如 `US`、`CN`、`UK` 等
::::
:::: field name="accId" type="string" required
商户账户 ID
::::
:::: field name="locale" type="string" required
界面语言
::::
:::: field name="region" type="string" optional default="fra"
`sg` 或 `fra`
::::
:::: field name="sdkAccessToken" type="string" required
SDK 访问凭证
::::
:::: field name="merchantResultUrl" type="string" required
支付完成跳转地址
::::
:::: field name="createOrder" type="Function" optional
mode 为 `Payment` 时必传。该函数接收一个包含 `payMethod` 的对象参数,表示用户选择的支付方式
::::
:::: field name="goods" type="Array" required
商品信息数组
::::
:::: field name="biztype" type="string" optional
业务类型
可选值: `CodeGrant`
::::
:::: field name="recurringInfoDTO" type="Object" optional
ApplePay 签约必传
::::
:::::
### PingPongSDK.createElement()
创建支付元素实例。
**参数:**
::::: field-group
:::: field name="type" type="string" required
`applePayButton`、`googlePayButton`、`paypalButton`
::::
:::: field name="options" type="object" required
元素配置参数
::::
:::::
**返回:** Promise\
### element.on()
注册事件监听器。
**支持的事件:**
::::: field-group
:::: field name="ready" type="Event"
元素初始化完成
::::
:::: field name="success" type="Event"
支付成功
::::
:::: field name="error" type="Event"
支付失败
::::
:::: field name="cancel" type="Event"
用户取消
::::
:::::
### element.off()
移除事件监听器。
### element.mount()
将支付元素挂载到 DOM。
**参数:**
::::: field-group
:::: field name="selector" type="string" required
CSS 选择器
::::
:::::
### element.unmount()
从 DOM 中卸载元素,释放资源。