Native SDK
约 2703 字大约 9 分钟
2026-04-03
产品概述
产品简介
PingPong Checkout Native SDK 是 PingPong 专为移动应用设计的支付收银台 SDK,提供完整的支付解决方案,支持多种支付方式,包括银行卡支付、Apple Pay、Google Pay等。该 SDK 旨在简化开发者集成支付功能的复杂度,提供统一、安全、流畅的支付体验。
核心价值:
- 一次集成,支持全球主流支付方式
- 半屏支付体验,用户无需离开当前页面
- 符合 PCI DSS 安全标准,降低合规成本
- 智能 3D Secure 验证,平衡安全与转化率
半屏支付体验
什么是半屏体验: 从屏幕底部滑出的支付面板,用户在保持当前页面上下文的同时完成支付操作。
与传统全屏支付对比:
| 特性 | 半屏支付 | 传统全屏支付 |
|---|---|---|
| 上下文保持 | 保留原页面 | 完全跳转 |
| 操作便捷 | 点击关闭 | 点击返回 |
| 用户体验 | 轻量级弹层 | 页面切换 |
| 转化率 | 提升 15-20% | 相对较低 |
| 集成复杂度 | 低(20行代码) | 中 |
设计亮点:
- 动态高度:根据支付方式自动调整面板高度
- 动画过渡:流畅的滑入滑出动画
支持的支付方式
| 支付方式 | iOS | Android | 说明 |
|---|---|---|---|
| Apple Pay | ✅ | - | |
| Google Pay | - | ✅ | |
| 信用卡/借记卡 | ✅ | ✅ | 支持 Visa、Mastercard、Amex 等 |
| 3D Secure | ✅ | ✅ | 自动触发验证流程 |
接入流程概览
整体时序简述:
- 创建会话:服务端调用
/v4/payment/prePay创建支付会话 - 获取 Token:服务端从响应
bizContent.token字段提取 Token - 唤起 SDK:客户端使用 Token 初始化并唤起 SDK
- 返回结果:SDK 通过回调通知支付流程状态(completed/failure/cancel)
平台选择
- iOS 接入详见 iOS 接入指南
- Android 接入详见 Android 接入指南
准备流程
开始接入前,请先完成以下准备工作:
- 开通沙箱账户:详见 准备工作 - 沙箱账户开通
- 获取 API 凭证:联系技术支持获取
accId、clientId、salt,详见 API 使用基本规则
安全提示
salt仅保存在服务端,切勿泄露到客户端- 沙箱环境和生产环境使用不同的凭证
快速开始
整体接入流程
接入步骤说明:
- 创建会话:服务端调用
/v4/payment/prePay创建支付会话 - 获取 Token:服务端从响应
bizContent.token字段提取 Token - 唤起 SDK:客户端使用 Token 初始化并唤起 SDK
- 返回结果:SDK 通过回调通知支付流程状态(completed/failure/cancel)
- 结果确认:客户端向服务端查询最终支付状态
服务端:创建支付会话
接口说明
| 项目 | 内容 |
|---|---|
| 请求方式 | POST |
| 沙箱环境 | https://sandbox-acquirer-payment.pingpongx.com/v4/payment/prePay |
| 生产环境-欧洲 | https://acquirer-payment.pingpongx.com/v4/payment/prePay |
| 生产环境-美国 | https://acquirer-payment-checkout-us.pingpongx.com/v4/payment/prePay |
| Content-Type | application/json |
提示
完整的请求参数说明请参考下单接口(Hosted模式)。
请求参数
公共请求参数
公共请求参数(accId、clientId、signType、sign、version、bizContent)详见 API 使用基本规则。
签名说明
Native SDK 服务端接口遵循 PingPongCheckout 统一签名规约,签名类型支持 MD5 和 SHA256(推荐)。详细的签名算法步骤和代码示例请参考 签名规约。
业务请求参数(bizContent)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| merchantTransactionId | String(64) | M | 商户订单号,全局唯一 |
| amount | String(12) | M | 交易金额 |
| currency | String(3) | M | 交易币种,ISO 4217 |
| shopperIP | String(128) | M | 用户下单IP |
| notificationUrl | String(255) | O | 异步通知地址 |
| goods | Array | M | 商品信息列表 |
| billingAddress | Object | M | 账单地址 |
curl 请求示例
curl -X POST https://sandbox-acquirer-payment.pingpongx.com/v4/payment/prePay \
-H "Content-Type: application/json" \
-d '{
"accId": "2018092714313010016291",
"clientId": "2018092714313010016",
"signType": "SHA256",
"sign": "28178F3C0B0AF10343F715211B9C7791AB4CF091EB4580505E053318E8F37B85",
"version": "1.0",
"bizContent": "{\"merchantTransactionId\":\"ORDER_123456\",\"amount\":\"100.00\",\"currency\":\"USD\",\"shopperIP\":\"222.126.52.24\",\"goods\":[{\"name\":\"Product A\",\"sku\":\"SKU001\",\"unitPrice\":\"100.00\",\"number\":\"1\"}],\"customer\":{\"firstName\":\"James\",\"lastName\":\"LeBron\",\"email\":\"123456@gmail.com\",\"phone\":\"3055787343\"},\"billingAddress\":{\"street\":\"1986 Broad Street\",\"city\":\"Birmingham\",\"state\":\"AL\",\"country\":\"US\",\"postcode\":\"35222\"}}"
}'响应参数
| 参数 | 说明 |
|---|---|
bizContent.token | 收银台 Token,用于初始化 SDK |
bizContent.transactionId | PingPong 交易号 |
响应示例
{
"code": "000000",
"description": "Transaction succeeded",
"accId": "2018092714313010016291",
"clientId": "2018092714313010016",
"signType": "SHA256",
"sign": "337DE4525BECC73D56E262E04CCCC210C7BA70C78D48DA3BB128E4FEC6D01561",
"bizContent": {
"transactionId": "2023092050004591",
"merchantTransactionId": "ORDER_123456",
"token": "EU:vr_YVR8u7rn7C1gG97DOg9_-Y66ubtNtoayJ_wiEEzdCnxCHYIk0pXordJYBjq1g",
"paymentUrl": "https://sandbox-acquirer-payment-ssr.pingpongx.com/v3/checkout?token=xxx",
"innerJsUrl": "https://paycdn.pingpongx.com/production/static/sdk/ppPay.min.js?token=xxx",
"amount": "100.00",
"currency": "USD"
}
}提取 Token
从响应的 bizContent.token 字段获取 Token,传递给客户端 SDK 用于初始化。
客户端:快速唤起支付
以下展示了各平台最小可运行代码(约 20 行):
#import <PPCashDeskSDK/PPCashDeskSDK.h>
// 配置 SDK
PPCDManager *manager = [PPCDManager sharedInstance];
PPCDConfig *config = [[PPCDConfig alloc] init];
config.environmentType = PPCDEnvironmentTypeSandBox; // 沙箱环境
config.shouldStartRecLog = YES;
manager.config = config;
// 唤起收银台
[manager initWithToken:@"your_token"
completed:^(NSString *code) {
// 支付信息提交成功,需服务端确认状态
NSLog(@"支付流程完成: %@", code);
}
failure:^(NSError *error) {
// 支付流程失败
NSLog(@"支付流程失败: %@", error.localizedDescription);
}
cancel:^{
// 用户取消
NSLog(@"用户取消支付");
}];// 1. 创建支付实例
val payment = PPPayment(activity) { result ->
when (result) {
is PaymentResult.Completed -> {
// 支付流程完成(需服务端确认)
Log.d("Payment", "支付信息提交成功,需服务端确认支付状态")
}
is PaymentResult.Canceled -> {
// 用户取消
Log.d("Payment", "用户取消")
}
is PaymentResult.Failed -> {
// 支付流程失败
Log.e("Payment", "支付流程失败: ${result.error}")
}
}
}
// 2. 配置参数
val config = PaymentConfig(
environment = Environment.SANDBOX, // 测试环境
logEnabled = true, // SDK 日志
cardBinLength = true // 设置卡 Bin 位数长度
)
// 3. 唤起收银台
payment.presentPayment(
token = "your_token",
config = config
)验证支付结果
双重验证机制:
- 客户端回调:SDK 通过回调通知交互状态(completed/failure/cancel),不代表支付结果
- 服务端确认:通过 Webhook 或查询接口获取最终支付状态(用于订单状态更新)
重要提示
客户端回调仅供参考,务必以服务端查询结果为准。
支付结果处理
前端状态处理
SDK 回调触发时机及处理逻辑:
| 场景 | 触发回调 | 处理建议 |
|---|---|---|
| 用户点击支付按钮,支付接口响应成功 | iOS:completed Android: Completed | 显示支付中提示,长轮询服务端查询最终支付结果 |
| 用户点击半屏面板关闭按钮 | iOS:cancel Android: Canceled | 返回订单页面,可提示用户"支付已取消" |
| 支付接口异常或网络错误 | iOS:failure Android: Failed | 显示错误信息,提示用户重新尝试支付 |
重要说明
- iOS:
completed(Android:Completed) 回调仅表示支付接口调用成功,不代表支付成功 - 此时支付可能仍在处理中(银行处理中/风控审核中等)
- 必须通过长轮询从服务端获取最终支付状态
后端状态处理
商户后端必须通过以下方式获取最终支付结果:
| 方式 | 说明 | 优先级 |
|---|---|---|
| Webhook 回调 | PingPong 主动推送支付结果 | 推荐 |
| 主动查询 | 调用 query 接口查询订单状态 | 兜底 |
提示
Webhook 异步通知机制详见异步通知文档。
处理流程:
注意事项:
- Webhook 和主动查询结果需进行幂等性控制(建议使用
transactionId+status) - 收到 Webhook 后需返回 HTTP 200,否则将触发重试
- 重试间隔:
5s/5s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h
Webhook 通知报文示例:
{
"clientId": "2023101115545610265",
"code": "000000",
"bizContent": {
"transactionId": "2024050650046448",
"merchantTransactionId": "PMT-K52GNL5ZY21714991465240",
"status": "SUCCESS",
"amount": "100.00",
"currency": "USD"
},
"sign": "...",
"signType": "SHA256"
}Webhook 回调的接收方式、重试机制、验签要求等详见 异步通知。
主动查询接口
| 项目 | 内容 |
|---|---|
| 请求方式 | POST |
| 接口路径 | /v4/payment/query |
| Content-Type | application/json |
查询请求参数(bizContent)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| transactionId | String | C | PingPong 交易流水号 |
| merchantTransactionId | String | C | 商户订单号 |
注意
至少上送一项。
Java 服务示例:
@Service
public class PaymentConfirmationService {
// Webhook 回调处理
public void handleWebhook(PaymentNotification notification) {
processPaymentResult(notification);
}
// 客户端轮询接口
public PaymentStatus queryPaymentStatus(String orderId) {
// 查询数据库缓存的状态
PaymentStatus status = paymentRepository.findStatusByOrderId(orderId);
// 如果状态未终态,主动查询 PingPong
if (!status.isFinal()) {
status = queryFromPingPong(orderId);
paymentRepository.updateStatus(orderId, status);
}
return status;
}
// 定时补偿查询(针对未终态订单)
@Scheduled(fixedDelay = 60000)
public void compensateQuery() {
List<String> pendingOrders = paymentRepository.findPendingOrders();
for (String orderId : pendingOrders) {
PaymentStatus status = queryFromPingPong(orderId);
if (status.isFinal()) {
processPaymentResult(status);
}
}
}
}