主题
Payment JavaScript SDK 使用文档
本 SDK 帮助开发者在 Web 应用中集成多种支付功能,支持银行卡支付、ApplePay、STCPay、Tabby、Tamara 等方式。
提示
使用本对接方式,商户可以自行定义收银台的页面样式与信息展示,付款人无需跳转中间页面,支付体验更流畅。
集成流程概览
1. 引入 SDK 脚本
↓
2. 商户服务端下单,获取 orderId
↓
3. 实例化 PaymentSDK(传入 orderId 及支付参数)
↓
4. 注册 paymentSuccess / paymentError 事件回调
↓
5. 调用 init() 渲染支付 UI 组件
↓
6. 用户填写信息后,调用 submit() 提交支付1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
集成 Demo 见 附录 - 测试信息及 Demo
引入 SDK
在 HTML 页面的 <head> 或 <body> 中,通过 <script> 标签引入 SDK:
- 测试环境:
html
<script src="https://h5-dev.gccpay.cn/jssdk/gccpay.payment.sdk.1.0.0.js"></script>1
- 生产环境:
html
<script src="https://cashier.sgate.sa/jssdk/gccpay.payment.sdk.1.0.0.js"></script>1
SDK 参数说明
实例化 PaymentSDK 时需传入以下五个参数,其中 orderId 由商户服务端下单后从响应中获取:
| 参数 | 类型 | 说明 |
|---|---|---|
orderId | String | 平台订单号,由商户调用服务端下单接口后,平台返回的订单号 |
paymentType | String | 支付方式:cardpay: 卡支付 applepay: ApplePaystcpay: STCPay tabby: Tabby 分期 tamara: Tamara 分期 |
orderType | String | 交易码,当前固定值:online_payin |
iframe3DSFlag | Boolean | 3DS 验证页面是否以 iframe 嵌入收银台:true: 嵌入 false: 另开新页面 |
contentLanguage | String | 页面语言:en-US: 英语 ar-SA: 阿拉伯语 |
javascript
const paymentInstance = new PaymentSDK(
orderId, // 平台订单号
"cardpay", // 支付方式
"online_payin", // 交易码
true, // 3DS 嵌入方式
"en-US", // 语言
);1
2
3
4
5
6
7
2
3
4
5
6
7
事件监听
使用 paymentInstance.on(eventName, callback) 监听支付流程状态,建议在调用 init() 前注册。
paymentSuccess:支付成功时触发,回调接收包含成功信息的data对象。
javascript
paymentInstance.on("paymentSuccess", (data) => {
console.log("支付成功:", data);
// 处理支付成功逻辑,例如跳转订单详情页
});1
2
3
4
2
3
4
paymentError:支付失败或处理出错时触发,回调接收包含message字段的data对象。
javascript
paymentInstance.on("paymentError", (data) => {
console.error("支付失败:", data.message);
// 处理失败逻辑,例如提示用户重试
});1
2
3
4
2
3
4
初始化 UI 组件
调用 await paymentInstance.init(options) 将支付输入框(通过 iframe 渲染)注入到指定的 HTML 容器中。
注意
container为必填项,必须指向页面中已存在的 DOM 元素。init()是异步方法,必须使用try...catch捕获初始化异常。
javascript
try {
await paymentInstance.init({
container: document.getElementById("container"),
cardNumber: {
container: document.getElementById("cardNumber"),
},
cardHolderName: {
container: document.getElementById("cardHolderName"),
},
expiryDate: {
container: document.getElementById("expiryDate"),
},
cvv: {
container: document.getElementById("cvv"),
},
payerEmail: {
container: document.getElementById("payerEmail"),
},
submit: {
container: document.getElementById("submit"),
},
applepay: {
container: document.getElementById("applepayContainer"),
},
});
} catch (error) {
console.error("SDK 初始化失败:", error.message);
document.body.innerHTML = `<div style="color: red;">支付组件初始化失败:${error.message}</div>`;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
不同支付方式需要的容器字段不同,详见下方各支付方式集成示例。
提交支付
非 ApplePay 支付时,用户填写信息后,在"支付"按钮的点击事件中调用 paymentInstance.submit() 触发支付:
javascript
document.getElementById("submit").addEventListener("click", () => {
paymentInstance.submit();
});1
2
3
2
3
支付方式集成示例
卡支付(Card Payment)
html
<div id="container" class="content">
<div class="mt-20">
<label>Email</label>
<div class="input-wrap" id="payerEmail"></div>
</div>
<div class="mt-20">
<label>Name on card</label>
<div class="input-wrap" id="cardHolderName"></div>
</div>
<div class="mt-20">
<label>Card information</label>
<div class="input-wrap" id="cardNumber"></div>
<div class="mt-10 grid">
<div class="col-6">
<div class="input-wrap" id="expiryDate"></div>
</div>
<div class="col-6">
<div class="input-wrap" id="cvv"></div>
</div>
</div>
</div>
<div class="mt-20">
<button id="submit" class="bg-green">Pay</button>
</div>
</div>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
javascript
const initializePayment = async (orderId) => {
try {
const paymentInstance = new PaymentSDK(
orderId,
"cardpay",
"online_payin",
true,
"en-US",
);
paymentInstance.on("paymentSuccess", (data) => {
console.log("paymentSuccess", data);
});
paymentInstance.on("paymentError", (data) => {
console.log("paymentError", data);
});
await paymentInstance.init({
container: document.getElementById("container"),
cardNumber: { container: document.getElementById("cardNumber") },
cardHolderName: { container: document.getElementById("cardHolderName") },
expiryDate: { container: document.getElementById("expiryDate") },
cvv: { container: document.getElementById("cvv") },
payerEmail: { container: document.getElementById("payerEmail") },
submit: { container: document.getElementById("submit") },
});
document.getElementById("submit").addEventListener("click", () => {
paymentInstance.submit();
});
} catch (error) {
document.body.innerHTML = `<div style="color: red;">初始化失败:${error.message}</div>`;
}
};
// 传入服务端下单返回的订单号
initializePayment(orderId);1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
ApplePay
html
<div>
<div class="formInput" id="applepayContainer"></div>
</div>1
2
3
2
3
javascript
async function initializePayment(orderId) {
console.log("initializePayment", orderId);
try {
const paymentInstance = new PaymentSDK(orderId, "applepay", "online_payin");
paymentInstance.on("paymentError", (data) => {
console.log("paymentError---", data);
});
await paymentInstance.init({
applepay: {
container: document.getElementById("applepayContainer"),
},
});
} catch (error) {
document.body.innerHTML =
'<div style="color: red;">Initialization failed:' +
error.message +
"</div>";
}
}
const urlParams = new URLSearchParams(window.location.search);
const orderId = urlParams.get("orderId");
initializePayment(orderId);1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
STCPay
html
<div id="container">
<div class="mt-20">
<label>Mobile Number</label>
<div class="input-wrap" id="mobileNumber"></div>
</div>
<div class="mt-20">
<button id="submit" class="bg-green">Pay</button>
</div>
</div>1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
javascript
const initializePayment = async (orderId) => {
try {
const paymentInstance = new PaymentSDK(
orderId,
"stcpay",
"online_payin",
true,
"en-US",
);
paymentInstance.on("paymentSuccess", (data) => {
console.log("paymentSuccess", data);
});
paymentInstance.on("paymentError", (data) => {
console.log("paymentError", data);
});
await paymentInstance.init({
container: document.getElementById("container"),
mobileNumber: { container: document.getElementById("mobileNumber") },
submit: { container: document.getElementById("submit") },
});
document.getElementById("submit").addEventListener("click", () => {
paymentInstance.submit();
});
} catch (error) {
document.body.innerHTML = `<div style="color: red;">初始化失败:${error.message}</div>`;
}
};
// 传入服务端下单返回的订单号
initializePayment(orderId);1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Tabby / Tamara
使用 Tamara 时,将
"tabby"替换为"tamara"即可,其余代码相同。
html
<div id="container">
<div class="mt-20">
<label>Email</label>
<div class="input-wrap" id="payerEmail"></div>
</div>
<div class="mt-20">
<label>Mobile Number</label>
<div class="input-wrap" id="mobileNumber"></div>
</div>
<div class="mt-20">
<button id="submit" class="bg-green">Pay</button>
</div>
</div>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
javascript
const initializePayment = async (orderId) => {
try {
const paymentInstance = new PaymentSDK(
orderId,
"tabby", // Tamara 替换为 "tamara"
"online_payin",
false,
"en-US",
);
paymentInstance.on("paymentSuccess", (data) => {
console.log("paymentSuccess", data);
});
paymentInstance.on("paymentError", (data) => {
console.log("paymentError", data);
});
await paymentInstance.init({
container: document.getElementById("container"),
payerEmail: { container: document.getElementById("payerEmail") },
mobileNumber: { container: document.getElementById("mobileNumber") },
submit: { container: document.getElementById("submit") },
});
document.getElementById("submit").addEventListener("click", () => {
paymentInstance.submit();
});
} catch (error) {
document.body.innerHTML = `<div style="color: red;">初始化失败:${error.message}</div>`;
}
};
// 传入服务端下单返回的订单号
initializePayment(orderId);1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
错误处理
| 错误类型 | 来源 | 处理方式 |
|---|---|---|
| 初始化错误 | new PaymentSDK() / init() | 用 try...catch 捕获,向用户展示友好提示 |
| 支付流程错误 | paymentError 事件回调 | 读取 data.message 提示用户修正输入或更换支付方式 |
初始化错误常见原因:orderId / paymentType / orderType 无效,或 container 对应的 DOM 元素不存在。
支付流程错误常见原因:卡号无效、支付被拒、网络超时等,均通过 paymentError 事件回调通知。
样式定制
SDK 将支付输入框以 <iframe> 形式渲染到您指定的容器中。您可以通过调整容器 <div> 元素的 CSS 来控制其在页面中的布局与外观,<iframe> 内部样式不可直接修改。
css
.content {
margin: 0 auto;
padding: 20px;
width: 100%;
height: 100%;
max-width: 580px;
}
.mt-20 {
margin-top: 20px;
}
/* 输入框容器 */
.input-wrap {
padding: 0 16px;
width: 100%;
height: 40px;
border: 1px solid #d1d1d1;
border-radius: 6px;
outline-style: none;
font-size: 14px;
color: #161616;
transition: border-color 0.2s ease-in-out;
}
/* 支付按钮 */
button {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 40px;
border: none;
border-radius: 6px;
color: #fff;
font-size: 15px;
cursor: pointer;
font-family: -apple-system, "BlinkMacSystemFont", "Open Sans", Sans-Serif;
}
.bg-green {
background-color: #009d8a;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
如有技术问题,请联系我们的相关技术人员。
