📃 接入说明
请求 URI
{URI-scheme}://{Endpoint}/{resource-path}
| 属性 |
描述 |
<font style="color:rgb(52, 58, 64);">URI-scheme</font> |
表示用于传输请求的协议,当前所有 API 均采用 HTTPS 协议 |
<font style="color:rgb(52, 58, 64);">Endpoint</font> |
指定支付环境的服务器域名 |
<font style="color:rgb(52, 58, 64);">resource-path</font> |
资源路径,也即 API 访问路径,从具体 API 的 URI 模块获取 |
请求消息头
| 属性 |
描述 |
是否必填 |
示例 |
<font style="color:rgb(52, 58, 64);"></font>account-id |
账户ID |
是 |
acct_1SZLEsF4etCUqTsx |
<font style="color:rgb(52, 58, 64);"></font>oncestr |
随机字符串 |
是 |
7dbTdYEcDiMi6GtRhX4t9ac5fy0W5KDn |
<font style="color:rgb(52, 58, 64);"></font>timestamp |
时间戳 |
是 |
1777341839 |
signture |
签名 |
是 |
6UvszUxKIowWboyp |
<font style="color:rgb(52, 58, 64);"></font>site |
绑定网址 |
是 |
https://www..com* |
<font style="color:rgb(52, 58, 64);"></font>content-type |
|
是 |
application/json |
响应消息体
| 参数名 |
必选 |
类型 |
说明 |
code |
是 |
int |
成功:200 |
msg |
是 |
string |
描述 |
data |
是 |
object |
业务响应参数 |
测试数据
⌨️** AES-256-GCM 加密算法**
💡 统一加密规则(所有语言必须遵守)
:::warning
- 密钥必须 32 个字符(AES-256 要求)
- IV 固定 12 字节
- 认证标签固定 16 字节
- 拼接顺序:IV + 密文 + 标签 → Base64
- 所有语言编码统一使用 UTF-8
:::
PHP 示例
function encrypt(string $plaintext, string $key): string
{
// 必须32字节密钥
if (strlen($key) !== 32) {
throw new Exception('密钥必须是32个字符');
}
// 生成12字节IV
$iv = random_bytes(12);
// 加密
$ciphertext = openssl_encrypt(
$plaintext,
'aes-256-gcm',
$key,
OPENSSL_RAW_DATA,
$iv,
$tag
);
// 拼接:IV + 密文 + 标签
return base64_encode($iv . $ciphertext . $tag);
}
Python 示例
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import base64
def encrypt(plaintext, key):
if len(key) != 32:
raise Exception('密钥必须是32个字符')
key = key.encode('utf - 8')
aesgcm = AESGCM(key)
iv = aesgcm.generate_nonce(12)
ciphertext = aesgcm.encrypt(iv, plaintext.encode('utf - 8'), None)
data = iv + ciphertext + aesgcm.verify(iv, ciphertext, None)
return base64.urlsafe_b64encode(data).decode('utf - 8')
Node.js 示例
const crypto = require('crypto')
function encrypt(plaintext, key) {
if (key.length!== 32) {
throw new Error('密钥必须是32个字符')
}
const iv = crypto.randomBytes(12)
const cipher = crypto.createCipheriv('aes - 256 - gcm', key, iv)
let ciphertext = cipher.update(plaintext, 'utf8', 'binary')
ciphertext += cipher.final('binary')
const tag = cipher.getAuthTag()
const combined = Buffer.concat([iv, Buffer.from(ciphertext, 'binary'), tag])
return combined.toString('base64')
}
⌨️** 签名算法**
💡 规则概述
:::tips
请求体 + oncestr + timestamp + key 然后使用 HMAC-SHA256 加密转大写
例如:http原始请求报文如下
:::
GET /test HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0
Accept: text/html,application/xhtml+xml,application/json
Accept-Encoding: gzip, deflate
Connection: keep-alive
Account-Id: acct_1SZLEsF4etCUqTsx
Oncestr: 7dbTdYEcDiMi6GtRhX4t9ac5fy0W5KDn
Timestamp: 1777341839
{"name":"test","age":18}
:::info
- 拼接字符串:
{“name”:”test”,”age”:18}{oncestr}{timestamp}{key}
:::
:::info
- 计算签名:
使用 HMAC-SHA256 计算上一步拼接的字符串,最终转大写
:::
PHP 示例
$data = '{"name":"test","age":18}{oncestr}{timestamp}{key}';
$key = '***';
$sign = strtoupper(hash_hmac('sha256', $data, $key));
Python 示例
import hmac
import hashlib
data = '{"name":"test","age":18}{oncestr}{timestamp}{key}'
key = '***'
hmac_obj = hmac.new(key.encode('utf-8'), data.encode('utf-8'), hashlib.sha256)
sign = hmac_obj.hexdigest().upper()
Node.js 示例
const crypto = require('crypto')
const data = '{"name":"test","age":18}{oncestr}{timestamp}{key}'
const key = '***'
const sign = crypto
.createHmac('sha256', key)
.update(data, 'utf8')
.digest('hex')
.toUpperCase()
📣** 异步通知 POST**
请求头
| 参数名 |
类型 |
说明 |
<font style="color:rgb(52, 58, 64);"></font>account-id |
string |
账户ID |
<font style="color:rgb(52, 58, 64);"></font>oncestr |
string |
随机字符 |
<font style="color:rgb(52, 58, 64);"></font>timestamp |
string |
时间戳 |
signture |
string |
签名 |
charge 载体内容
{
"event_type": "charge",
"event_data": {
"payment_id": "2511250428189164", // 支付单号
"order_no": "1764062341", // 商户单号
"amount": "20.99", // 订单金额
"currency": "EUR", // 订单币种
"pay_time": "2025-11-25 17:30:24", // 支付时间
"status": "success", // success:支付成功 fail:支付失败 pending:待支付
"reason": "" // 支付失败原因
}
}
refund 载体内容
{
"event_type": "refund",
"event_data": {
"payment_id": "2511250428189164", // 支付单号
"order_no": "1764062341", // 商户单号
"amount": "20.99", // 本次退款金额
"currency": "EUR", // 本次退款币种
"status": "success" // success:退款成功 fail:退款失败 pending:退款中
}
}
:::info
💡 备注
- 验签逻辑,参照签名算法计算签名,然后和请求头的 signture 进行比较。
:::
📋 创建支付订单
🔖 Host
:::tips
- 简要描述:跳转收银台
- 请求URL:
/**open-api/payment/host**
- 请求方式:
POST
:::
请求参数
| 参数名 |
必选 |
类型 |
说明 |
return_url |
是 |
string |
支付完成后跳转的链接 |
callback_url |
是 |
string |
异步通知地址 |
order_no |
是 |
string |
订单号 |
amount |
是 |
float |
金额 |
shipping_fee |
否 |
float |
运费 |
discount |
否 |
float |
折扣金额 |
currency |
是 |
string |
币种 eg. USD |
product |
是 |
string |
eg. json 对象数组:[{“name”:”product name”,”quantity”:2,”unit_amount”:150} ] |
customer_firstname |
否 |
string |
顾客姓名: 不超过50个字符 实物商品需传参 |
customer_lastname |
否 |
string |
顾客姓名: 不超过50个字符 实物商品需传参 |
customer_address1 |
否 |
string |
顾客地址: 不超过200个字符 实物商品需传参 |
customer_address2 |
否 |
string |
顾客地址: 不超过200个字符 |
customer_city |
否 |
string |
顾客地址所在城市: 不超过50个字符 实物商品需传参 |
customer_state |
否 |
string |
顾客地址所在州: 不超过50个字符 |
customer_country |
是 |
string |
顾客地址所在国家: 不超过50个字符 eg.US 实物商品需传参 |
customer_phone |
否 |
string |
顾客电话: 不超过50个字符 实物商品需传参 |
customer_email |
是 |
string |
顾客邮箱: 不超过200个字符 |
customer_ip |
否 |
string |
顾客IP: 不超过100个字符 实物商品需传参 |
customer_user_agent |
否 |
string |
顾客浏览器: 不超过500个字符 实物商品需传参 |
customer_zip |
否 |
string |
顾客邮编: 不超过50个字符 实物商品需传参 |
customer_language |
否 |
string |
顾客语言: 不超过200个字符 实物商品需传参 |
shipping_firstname |
否 |
string |
收件人姓名: 不超过50个字符 实物商品需传参 |
shipping_lastname |
否 |
string |
收件人姓名: 不超过50个字符 实物商品需传参 |
shipping_street_address1 |
否 |
string |
收件人详细地址: 不超过200个字符 实物商品需传参 |
shipping_street_address2 |
否 |
string |
收件人详细地址: 不超过200个字符 |
shipping_city |
否 |
string |
收件人城市: 顾客地址所在城市 不超过50个字符 实物商品需传参 |
shipping_state |
否 |
string |
收件人州: 顾客地址所在城市 不超过50个字符 |
shipping_country |
是 |
string |
收件人国家: 顾客地址所在城市 不超过50个字符 实物商品需传参 |
shipping_zip |
否 |
string |
收件人邮编: 顾客地址所在城市 不超过50个字符 实物商品需传参 |
返回示例
{
"code": 200,
"msg": "操作成功",
"data": {
"checkout_link": "https://checkout.stripe.com/c/pay/cs_test_a1kr73iej0S0AAP6gfsc9NqQcGYkYnJGKdC6J8Ab4GTUA7VlvJkXotvGhj#fidnandhYHdWcXxpYCc%2FJ2FgY2RwaXEnKSd2cXdsdWBEZmZqcGtxJz8nZGZmcVo0VlVka3BDSXdMMEE0UEhDJyknZHVsTmB8Jz8ndW5acWB2cVowNE5fPTQxQzI9NTN1M2hVaTxjR2pEYjNmX3FMUUI2cUE1Rn12UHRcaV03MkxGY3RzPWZ3dnwwazEyaUNkY2xSXXFGa2JHXUJWS1ZuNXNPMUF9PEZpMkozSDU1bl9qf3NhbEgnKSdjd2poVmB3c2B3Jz9xd3BgKSdnZGZuYndqcGthRmppancnPycmY2NjY2NjJyknaWR8anBxUXx1YCc%2FJ3Zsa2JpYFpscWBoJyknYGtkZ2lgVWlkZmBtamlhYHd2Jz9xd3BgeCUl",
"payment_id": "2511100357564331"
}
}
返回参数说明
| 参数名 |
类型 |
说明 |
checkout_link |
string |
支付连接 |
payment_id |
string |
支付单号 |
🔖 Element
:::tips
- 简要描述:Element
- 请求URL:
/**open-api/payment/element**
- 请求方式:
POST
:::
请求参数
| 参数名 |
必选 |
类型 |
说明 |
return_url |
是 |
string |
支付完成后跳转的链接 |
callback_url |
是 |
string |
异步通知地址 |
order_no |
是 |
string |
订单号 |
amount |
是 |
float |
金额 |
shipping_fee |
否 |
float |
运费 |
discount |
否 |
float |
折扣金额 |
currency |
是 |
string |
币种 eg. USD |
product |
是 |
string |
eg. json 对象数组:[{“name”:”product name”,”quantity”:2,”unit_amount”:150} ] |
customer_firstname |
否 |
string |
顾客姓名: 不超过50个字符 实物商品需传参 |
customer_lastname |
否 |
string |
顾客姓名: 不超过50个字符 实物商品需传参 |
customer_address1 |
否 |
string |
顾客地址: 不超过200个字符 实物商品需传参 |
customer_address2 |
否 |
string |
顾客地址: 不超过200个字符 |
customer_city |
否 |
string |
顾客地址所在城市: 不超过50个字符 实物商品需传参 |
customer_state |
否 |
string |
顾客地址所在州: 不超过50个字符 |
customer_country |
是 |
string |
顾客地址所在国家: 不超过50个字符 eg.US 实物商品需传参 |
customer_phone |
否 |
string |
顾客电话: 不超过50个字符 实物商品需传参 |
customer_email |
是 |
string |
顾客邮箱: 不超过200个字符 |
customer_ip |
否 |
string |
顾客IP: 不超过100个字符 实物商品需传参 |
customer_user_agent |
否 |
string |
顾客浏览器: 不超过500个字符 实物商品需传参 |
customer_zip |
否 |
string |
顾客邮编: 不超过50个字符 实物商品需传参 |
customer_language |
否 |
string |
顾客语言: 不超过200个字符 实物商品需传参 |
shipping_firstname |
否 |
string |
收件人姓名: 不超过50个字符 实物商品需传参 |
shipping_lastname |
否 |
string |
收件人姓名: 不超过50个字符 实物商品需传参 |
shipping_street_address1 |
否 |
string |
收件人详细地址: 不超过200个字符 实物商品需传参 |
shipping_street_address2 |
否 |
string |
收件人详细地址: 不超过200个字符 |
shipping_city |
否 |
string |
收件人城市: 顾客地址所在城市 不超过50个字符 实物商品需传参 |
shipping_state |
否 |
string |
收件人州: 顾客地址所在城市 不超过50个字符 |
shipping_country |
是 |
string |
收件人国家: 顾客地址所在城市 不超过50个字符 实物商品需传参 |
shipping_zip |
否 |
string |
收件人邮编: 顾客地址所在城市 不超过50个字符 实物商品需传参 |
返回示例
{
"code": 200,
"msg": "操作成功",
"data": {
"pk": "pk_test_51SZ723FLsOTJb7kmstfva0qb150x163ZrbeBqEO98ArtVyltmiarnzXgJMO6AykCughhw9xknQYY08wtsJqg531x00NZ9mYmwE",
"client_secret": "cs_test_a1URpOm9NaeoIAyGPBQNfUIBWKH32qVgnKR23bxQmSDz5nu7CZZapWSZ4d_secret_fidnandhYHdWcXxpYCc%2FJ2FgY2RwaXEnKSd2cXdsdWBEZmZqcGtxJz8nZGZmcVo0VlVka3BDSXdMMEE0UEhDJyknZHVsTmB8Jz8ndW5acWB2cVowNE5fPTQxQzI9NTN1M2hVaTxjR2pEYjNmX3FMUUI2cUE1Rn12UHRcaV03MkxGY3RzPWZ3dnwwazEyaUNkY2xSXXFGa2JHXUJWS1ZuNXNPMUF9PEZpMkozSDU1bl9qf3NhbEgnKSdwbEhqYWAnPydgaGdgYWFgYScpJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ3dgYWx3YGZxSmtGamh1aWBxbGprJz8nZGlyZHx2JyknZ2RmbmJ3anBrYUZqaWp3Jz8nJmNjY2NjYyd4JSUl",
"payment_id": "2511112049447231"
}
}
返回参数说明
| 参数名 |
类型 |
说明 |
pk |
string |
stripe 公钥 |
<font style="color:rgb(52, 58, 64);background-color:rgb(249, 249, 249);">client_secret</font> |
string |
客户端密钥 |
payment_id |
string |
支付单号 |
使用 stripe.js 完成支付 (示例)
🔗 stripe.js 文档地址
Stripe JS Reference
<script src="https://js.stripe.com/v3/"></script>
<script type="text/javascript">
var stripe = Stripe('stripe 公钥', {
stripeAccount: 'account_id'
})
var appearance = {
theme: 'stripe'
}
var options = {
layout: {
type: 'tabs',
defaultCollapsed: false,
}
}
var elements = stripe.elements({
clientSecret: '客户端密钥',
appearance
})
var stripePaymentElement = elements.create('payment', options)
stripePaymentElement.mount('#payment-element')
const { error } = await stripe.confirmPayment({
elements,
confirmParams: {
return_url: '支付成功跳转页面',
},
})
if (error.type === 'card_error' || error.type === 'validation_error') {
layer.msg(error.message)
} else {
layer.msg('An unexpected error occurred.')
}
</script>
🔖 S2S
:::tips
- 简要描述:跳转收银台
- 请求URL:
/**open-api/payment/host**
- 请求方式:
POST
:::
请求参数
| 参数名 |
必选 |
类型 |
说明 |
return_url |
是 |
string |
支付完成后跳转的链接 |
callback_url |
是 |
string |
异步通知地址 |
order_no |
是 |
string |
订单号 |
amount |
是 |
float |
金额 |
shipping_fee |
否 |
float |
运费 |
discount |
否 |
float |
折扣金额 |
currency |
是 |
string |
币种 eg. USD |
product |
是 |
string |
eg. json 对象数组:[{“name”:”product name”,”quantity”:2,”unit_amount”:150} ] |
customer_firstname |
否 |
string |
顾客姓名: 不超过50个字符 实物商品需传参 |
customer_lastname |
否 |
string |
顾客姓名: 不超过50个字符 实物商品需传参 |
customer_address1 |
否 |
string |
顾客地址: 不超过200个字符 实物商品需传参 |
customer_address2 |
否 |
string |
顾客地址: 不超过200个字符 |
customer_city |
否 |
string |
顾客地址所在城市: 不超过50个字符 实物商品需传参 |
customer_state |
否 |
string |
顾客地址所在州: 不超过50个字符 |
customer_country |
是 |
string |
顾客地址所在国家: 不超过50个字符 eg.US 实物商品需传参 |
customer_phone |
否 |
string |
顾客电话: 不超过50个字符 实物商品需传参 |
customer_email |
是 |
string |
顾客邮箱: 不超过200个字符 |
customer_ip |
否 |
string |
顾客IP: 不超过100个字符 实物商品需传参 |
customer_user_agent |
否 |
string |
顾客浏览器: 不超过500个字符 实物商品需传参 |
customer_zip |
否 |
string |
顾客邮编: 不超过50个字符 实物商品需传参 |
customer_language |
否 |
string |
顾客语言: 不超过200个字符 实物商品需传参 |
shipping_firstname |
否 |
string |
收件人姓名: 不超过50个字符 实物商品需传参 |
shipping_lastname |
否 |
string |
收件人姓名: 不超过50个字符 实物商品需传参 |
shipping_street_address1 |
否 |
string |
收件人详细地址: 不超过200个字符 实物商品需传参 |
shipping_street_address2 |
否 |
string |
收件人详细地址: 不超过200个字符 |
shipping_city |
否 |
string |
收件人城市: 顾客地址所在城市 不超过50个字符 实物商品需传参 |
shipping_state |
否 |
string |
收件人州: 顾客地址所在城市 不超过50个字符 |
shipping_country |
是 |
string |
收件人国家: 顾客地址所在城市 不超过50个字符 实物商品需传参 |
shipping_zip |
否 |
string |
收件人邮编: 顾客地址所在城市 不超过50个字符 实物商品需传参 |
card |
是 |
string |
eg. json 对象:{“number”:”4242424242424242”,”cvc”:”123”,”exp_month”:”12”,”exp_year”:”28”} 使用 AES-256-GCM 加密后的字符串 |
返回示例
{
"code": 200,
"msg": "操作成功",
"data": {
"redirect_to_url": "",
"status": "requires_action",
"payment_id": "2511112049447231"
}
}
返回参数说明
| 参数名 |
类型 |
说明 |
<font style="color:rgb(52, 58, 64);background-color:rgb(249, 249, 249);">redirect_to_url</font> |
string |
3D验证URL |
status |
string |
状态: succeeded 成功 requires_action需要跳转3D验证 |
payment_id |
string |
支付单号 |