创建支付订单
学习如何创建支付订单并处理支付流程
5 分钟阅读
更新于 2025/8/13
支付API示例
本示例展示如何创建支付订单并处理完整的支付流程。
前置要求
在开始之前,请确保您已经:
- 注册了 Payve 商户账号
- 获取了 API 密钥
- 配置了 Webhook 接收地址(可选)
基础示例
1. 创建支付订单
使用 Payve API 创建支付订单的最简单方式:
// 初始化 API 配置
const PAYVE_API_URL = 'https://api.payve.io';
const API_KEY = 'your-api-key';
const API_SECRET = 'your-api-secret';
// 生成 JWT Token
async function generateToken() {
const header = {
alg: 'HS256',
typ: 'JWT'
};
const payload = {
merchantId: 'your-merchant-id',
iat: Math.floor(Date.now() / 1000),
exp: Math.floor(Date.now() / 1000) + 3600 // 1小时后过期
};
// 使用您喜欢的 JWT 库生成 token
// 示例使用 jose 库
const jwt = await new jose.SignJWT(payload)
.setProtectedHeader(header)
.sign(new TextEncoder().encode(API_SECRET));
return jwt;
}
// 创建支付订单
async function createPayment(amount, currency = 'USDT') {
const token = await generateToken();
const response = await fetch(`${PAYVE_API_URL}/api/v1/payments`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
amount: amount,
currency: currency,
description: '订单支付',
callbackUrl: 'https://your-domain.com/webhook/payve',
returnUrl: 'https://your-domain.com/payment/success',
metadata: {
orderId: 'ORDER-12345',
userId: 'USER-789'
}
})
});
if (!response.ok) {
throw new Error(`创建支付失败: ${response.status}`);
}
return await response.json();
}
// 使用示例
async function main() {
try {
const payment = await createPayment(100, 'USDT');
console.log('支付订单创建成功:', payment);
console.log('支付地址:', payment.address);
console.log('应付金额:', payment.amount, payment.currency);
console.log('订单ID:', payment.orderId);
} catch (error) {
console.error('创建支付失败:', error);
}
}JAVASCRIPT
代码已折叠
共 69 行
2. 响应数据结构
成功创建支付订单后,API 将返回以下数据:
{
"orderId": "pay_1234567890abcdef",
"status": "PENDING",
"amount": "100.00",
"currency": "USDT",
"network": "TRC20",
"address": "TRX1234567890abcdefghijklmnop",
"qrCode": "data:image/png;base64,iVBORw0KGgoAAAANS...",
"expiresAt": "2024-01-15T12:30:00Z",
"createdAt": "2024-01-15T11:30:00Z",
"metadata": {
"orderId": "ORDER-12345",
"userId": "USER-789"
}
}JSON
代码已折叠
共 15 行
进阶功能
多币种支付
支持用户选择不同的加密货币进行支付:
async function createMultiCurrencyPayment(amount, acceptedCurrencies) {
const token = await generateToken();
const response = await fetch(`${PAYVE_API_URL}/api/v1/payments`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
amount: amount,
// 允许用户选择支付币种
acceptedCurrencies: acceptedCurrencies || [
'USDT',
'USDC',
'BTC',
'ETH',
'BNB',
'SOL'
],
// 可选:指定优先显示的币种
preferredCurrency: 'USDT',
description: '多币种支付订单',
callbackUrl: 'https://your-domain.com/webhook/payve'
})
});
return await response.json();
}
// 使用示例
const payment = await createMultiCurrencyPayment(100, ['USDT', 'USDC', 'BTC']);JAVASCRIPT
代码已折叠
共 32 行
指定区块链网络
为特定币种指定区块链网络:
async function createPaymentWithNetwork(amount, currency, network) {
const token = await generateToken();
const response = await fetch(`${PAYVE_API_URL}/api/v1/payments`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
amount: amount,
currency: currency,
network: network, // 例如: 'ERC20', 'TRC20', 'BEP20'
description: '指定网络的支付订单'
})
});
return await response.json();
}
// 使用示例 - USDT 通过 TRC20 网络
const payment = await createPaymentWithNetwork(100, 'USDT', 'TRC20');JAVASCRIPT
代码已折叠
共 22 行
设置订单过期时间
自定义支付订单的有效期:
async function createPaymentWithExpiry(amount, expiryMinutes = 30) {
const token = await generateToken();
const expiresAt = new Date();
expiresAt.setMinutes(expiresAt.getMinutes() + expiryMinutes);
const response = await fetch(`${PAYVE_API_URL}/api/v1/payments`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
amount: amount,
currency: 'USDT',
expiresAt: expiresAt.toISOString(), // ISO 8601 格式
description: '限时支付订单'
})
});
return await response.json();
}JAVASCRIPT
代码已折叠
共 22 行
查询支付状态
创建订单后,您可以通过订单ID查询支付状态:
async function getPaymentStatus(orderId) {
const token = await generateToken();
const response = await fetch(`${PAYVE_API_URL}/api/v1/payments/${orderId}`, {
headers: {
'Authorization': `Bearer ${token}`
}
});
if (!response.ok) {
throw new Error(`查询失败: ${response.status}`);
}
return await response.json();
}
// 轮询支付状态
async function waitForPayment(orderId, maxAttempts = 60) {
for (let i = 0; i < maxAttempts; i++) {
const payment = await getPaymentStatus(orderId);
console.log(`支付状态: ${payment.status}`);
if (payment.status === 'COMPLETED') {
console.log('支付成功!');
console.log('交易哈希:', payment.txHash);
return payment;
}
if (payment.status === 'FAILED' || payment.status === 'EXPIRED') {
console.log('支付失败或已过期');
return payment;
}
// 等待5秒后再次查询
await new Promise(resolve => setTimeout(resolve, 5000));
}
throw new Error('支付超时');
}JAVASCRIPT
代码已折叠
共 40 行
错误处理
正确处理各种错误情况:
async function createPaymentWithErrorHandling(amount, currency) {
try {
const payment = await createPayment(amount, currency);
return { success: true, data: payment };
} catch (error) {
// 处理不同类型的错误
if (error.message.includes('401')) {
return {
success: false,
error: 'API密钥无效或已过期',
code: 'AUTH_FAILED'
};
}
if (error.message.includes('400')) {
return {
success: false,
error: '请求参数错误',
code: 'INVALID_REQUEST'
};
}
if (error.message.includes('429')) {
return {
success: false,
error: '请求过于频繁,请稍后重试',
code: 'RATE_LIMITED'
};
}
// 其他错误
return {
success: false,
error: '创建支付失败,请稍后重试',
code: 'UNKNOWN_ERROR'
};
}
}JAVASCRIPT
代码已折叠
共 38 行
完整示例
将所有功能整合到一起的完整示例:
class PayvePaymentService {
constructor(apiKey, apiSecret, merchantId) {
this.apiKey = apiKey;
this.apiSecret = apiSecret;
this.merchantId = merchantId;
this.apiUrl = 'https://api.payve.io';
}
async generateToken() {
// JWT 生成逻辑
const payload = {
merchantId: this.merchantId,
iat: Math.floor(Date.now() / 1000),
exp: Math.floor(Date.now() / 1000) + 3600
};
// 使用 jose 或其他 JWT 库
return await generateJWT(payload, this.apiSecret);
}
async createPayment(options) {
const {
amount,
currency = 'USDT',
description,
callbackUrl,
returnUrl,
metadata = {},
expiryMinutes = 30
} = options;
const token = await this.generateToken();
const expiresAt = new Date();
expiresAt.setMinutes(expiresAt.getMinutes() + expiryMinutes);
const response = await fetch(`${this.apiUrl}/api/v1/payments`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
amount,
currency,
description,
callbackUrl,
returnUrl,
metadata,
expiresAt: expiresAt.toISOString()
})
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.message || `HTTP ${response.status}`);
}
return await response.json();
}
async getPaymentStatus(orderId) {
const token = await this.generateToken();
const response = await fetch(`${this.apiUrl}/api/v1/payments/${orderId}`, {
headers: {
'Authorization': `Bearer ${token}`
}
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return await response.json();
}
async waitForPaymentCompletion(orderId, options = {}) {
const {
pollingInterval = 5000,
timeout = 300000
} = options;
const startTime = Date.now();
while (Date.now() - startTime < timeout) {
const payment = await this.getPaymentStatus(orderId);
if (payment.status === 'COMPLETED') {
return { success: true, payment };
}
if (payment.status === 'FAILED' || payment.status === 'EXPIRED') {
return { success: false, payment };
}
await new Promise(resolve => setTimeout(resolve, pollingInterval));
}
throw new Error('Payment timeout');
}
}
// 使用示例
const paymentService = new PayvePaymentService(
'your-api-key',
'your-api-secret',
'your-merchant-id'
);
// 创建支付
const payment = await paymentService.createPayment({
amount: 100,
currency: 'USDT',
description: '商品购买',
callbackUrl: 'https://your-domain.com/webhook',
metadata: {
orderId: 'ORDER-123',
productId: 'PROD-456'
}
});
console.log('支付链接:', payment.paymentUrl);
console.log('二维码:', payment.qrCode);
// 等待支付完成
const result = await paymentService.waitForPaymentCompletion(payment.orderId);
if (result.success) {
console.log('支付成功!');
} else {
console.log('支付失败');
}JAVASCRIPT
代码已折叠
共 132 行
最佳实践
-
安全性
- 永远不要在前端暴露 API Secret
- 使用 HTTPS 传输所有数据
- 验证 Webhook 签名确保请求来源可信
-
用户体验
- 显示清晰的支付倒计时
- 提供多种支付币种选择
- 实时更新支付状态
-
错误处理
- 实现重试机制处理网络错误
- 记录所有支付相关的日志
- 为用户提供清晰的错误提示
-
性能优化
- 缓存 JWT Token 避免频繁生成
- 使用 WebSocket 替代轮询获取实时状态
- 批量查询多个订单状态
下一步
- 查看 Webhook 处理 了解如何接收支付通知
- 阅读 React 集成 学习在 React 应用中使用
- 参考 完整示例 查看端到端的实现
