API 认证
了解如何安全地认证和授权 API 请求
8 分钟阅读
更新于 2025/8/13
认证JWTAPI密钥
Payve 使用基于 JWT (JSON Web Token) 的认证机制,确保 API 调用的安全性。本文档将指导您完成认证流程的设置。
认证流程概览
认证步骤
- 创建商户账户,获取 API Key 和 Secret
- 使用 API Key 和 Secret 换取 JWT 令牌
- 在请求头中携带 JWT 令牌访问 API
- 令牌过期前刷新或重新获取
获取 API 密钥
方式一:通过商户后台
- 登录商户后台
- 进入「开发者设置」→「API 密钥」
- 点击「创建新密钥」
- 设置密钥名称和权限范围
- 保存生成的 Key ID 和 Secret
API Secret 只会显示一次,请立即保存到安全的地方。如果丢失,需要重新生成。
方式二:通过 API 创建
首次注册商户账户时会自动生成一组 API 密钥:
curl -X POST https://api.payve.io/api/v1/merchant/register \
-H "Content-Type: application/json" \
-d '{
"email": "your-email@example.com",
"companyName": "Your Company",
"password": "secure-password"
}'响应示例:
{
"success": true,
"data": {
"merchantId": "mer_xxxxx",
"apiKey": {
"keyId": "pk_live_xxxxx",
"secret": "sk_live_xxxxx",
"permissions": ["CREATE_PAYMENTS", "READ_PAYMENTS"]
}
}
}JSON
代码已折叠
共 11 行
获取访问令牌
使用 API 密钥换取 JWT 访问令牌:
请求示例
curl -X POST https://api.payve.io/api/v1/auth/token \
-H "Content-Type: application/json" \
-d '{
"keyId": "pk_live_xxxxx",
"secret": "sk_live_xxxxx"
}'响应示例
{
"success": true,
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"tokenType": "Bearer",
"expiresIn": 86400,
"expiresAt": "2024-01-16T12:00:00.000Z",
"permissions": ["CREATE_PAYMENTS", "READ_PAYMENTS"]
}
}令牌说明
| 字段 | 说明 |
|---|---|
accessToken | JWT 访问令牌,用于 API 调用 |
tokenType | 令牌类型,固定为 "Bearer" |
expiresIn | 有效期(秒),默认 24 小时 |
expiresAt | 过期时间(ISO 8601) |
permissions | 令牌权限列表 |
使用访问令牌
在 API 请求的 Authorization 头中携带访问令牌:
curl -X GET https://api.payve.io/api/v1/payments \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."各语言示例
// Node.js 示例
const axios = require('axios');
class PayveClient {
constructor(keyId, secret) {
this.keyId = keyId;
this.secret = secret;
this.token = null;
this.baseURL = 'https://api.payve.io/api/v1';
}
async authenticate() {
const response = await axios.post(`${this.baseURL}/auth/token`, {
keyId: this.keyId,
secret: this.secret
});
this.token = response.data.data.accessToken;
this.tokenExpiry = Date.now() + (response.data.data.expiresIn * 1000);
}
async request(method, path, data) {
// 检查令牌是否过期
if (!this.token || Date.now() >= this.tokenExpiry) {
await this.authenticate();
}
return axios({
method,
url: `${this.baseURL}${path}`,
headers: {
'Authorization': `Bearer ${this.token}`,
'Content-Type': 'application/json'
},
data
});
}
// 使用示例
async createPayment(amount, currency) {
return this.request('POST', '/payments', {
amount,
currency
});
}
}
// 初始化客户端
const client = new PayveClient('pk_live_xxxxx', 'sk_live_xxxxx');
// 创建支付
const payment = await client.createPayment('100.00', 'USDT');JAVASCRIPT
代码已折叠
共 52 行
权限管理
权限列表
API 密钥可以配置不同的权限范围:
| 权限 | 说明 | API 端点 |
|---|---|---|
READ_PAYMENTS | 查询支付订单 | GET /payments |
CREATE_PAYMENTS | 创建支付订单 | POST /payments |
CANCEL_PAYMENTS | 取消支付订单 | DELETE /payments/{id} |
READ_WALLET | 查询钱包余额 | GET /wallet/balance |
WITHDRAW | 发起提现 | POST /wallet/withdraw |
MANAGE_WEBHOOKS | 管理 Webhook | POST /webhooks |
READ_REPORTS | 查看报表 | GET /reports |
MANAGE_SETTINGS | 管理设置 | PUT /merchant/settings |
创建受限密钥
为不同用途创建具有特定权限的密钥:
curl -X POST https://api.payve.io/api/v1/merchant/api-keys \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "只读密钥",
"permissions": ["READ_PAYMENTS", "READ_WALLET"],
"ipWhitelist": ["192.168.1.100", "10.0.0.0/24"]
}'权限检查
API 会自动检查请求的权限:
// 权限不足时的响应
{
"success": false,
"error": {
"code": "1004",
"message": "权限不足:需要 CREATE_PAYMENTS 权限"
}
}安全最佳实践
1. 保护 API Secret
永远不要将 API Secret 提交到代码仓库或暴露在前端代码中!
// ❌ 错误:硬编码密钥
const secret = 'sk_live_xxxxx';
// ✅ 正确:使用环境变量
const secret = process.env.PAYVE_SECRET;2. 使用 IP 白名单
限制 API 密钥只能从特定 IP 地址使用:
curl -X PUT https://api.payve.io/api/v1/merchant/api-keys/{keyId} \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{
"ipWhitelist": ["1.2.3.4", "5.6.7.8"]
}'3. 定期轮换密钥
建议每 90 天更换一次 API 密钥:
// 密钥轮换流程
async function rotateApiKey() {
// 1. 创建新密钥
const newKey = await createNewApiKey();
// 2. 更新应用配置
await updateApplicationConfig(newKey);
// 3. 验证新密钥工作正常
await verifyNewKey(newKey);
// 4. 撤销旧密钥
await revokeOldKey(oldKey);
}JAVASCRIPT
代码已折叠
共 14 行
4. 监控异常活动
定期检查 API 使用日志:
curl -X GET https://api.payve.io/api/v1/merchant/api-logs \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-G -d "startDate=2024-01-01" \
-d "endDate=2024-01-31"5. 使用 HTTPS
始终通过 HTTPS 调用 API:
// ✅ 正确
const apiUrl = 'https://api.payve.io';
// ❌ 错误
const apiUrl = 'http://api.payve.io';令牌刷新
自动刷新
实现令牌自动刷新机制:
class TokenManager {
constructor(keyId, secret) {
this.keyId = keyId;
this.secret = secret;
this.token = null;
this.refreshTimer = null;
}
async getToken() {
if (!this.token || this.isExpired()) {
await this.refresh();
}
return this.token;
}
async refresh() {
const response = await fetch('/api/v1/auth/token', {
method: 'POST',
body: JSON.stringify({
keyId: this.keyId,
secret: this.secret
})
});
const data = await response.json();
this.token = data.data.accessToken;
// 在过期前 5 分钟自动刷新
const refreshIn = (data.data.expiresIn - 300) * 1000;
if (this.refreshTimer) {
clearTimeout(this.refreshTimer);
}
this.refreshTimer = setTimeout(() => {
this.refresh();
}, refreshIn);
}
isExpired() {
// 检查令牌是否过期
if (!this.token) return true;
const payload = JSON.parse(
atob(this.token.split('.')[1])
);
return Date.now() >= payload.exp * 1000;
}
}JAVASCRIPT
代码已折叠
共 50 行
测试环境
沙盒环境
使用测试环境进行开发和调试:
- API 地址:
https://sandbox.payve.io/api/v1 - 测试密钥:以
pk_test_和sk_test_开头 - 测试币种:支持所有币种的测试网
// 切换到测试环境
const client = new PayveClient({
keyId: 'pk_test_xxxxx',
secret: 'sk_test_xxxxx',
environment: 'sandbox' // 或 'production'
});测试数据
沙盒环境提供测试数据:
# 创建测试支付
curl -X POST https://sandbox.payve.io/api/v1/payments \
-H "Authorization: Bearer TEST_TOKEN" \
-d '{
"amount": "100.00",
"currency": "USDT",
"test": true
}'故障排查
常见错误
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 401 Unauthorized | 令牌过期或无效 | 重新获取令牌 |
| 403 Forbidden | 权限不足 | 检查 API 密钥权限 |
| 429 Too Many Requests | 请求过于频繁 | 降低请求频率 |
| 500 Internal Error | 服务器错误 | 稍后重试或联系支持 |
调试技巧
- 检查请求头
curl -v https://api.payve.io/api/v1/payments \
-H "Authorization: Bearer YOUR_TOKEN"- 验证令牌
// 解码 JWT 查看内容
const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...';
const payload = JSON.parse(atob(token.split('.')[1]));
console.log(payload);- 使用请求 ID
每个响应都包含
X-Request-Id,用于追踪问题:
const response = await fetch(url);
const requestId = response.headers.get('X-Request-Id');
console.log('Request ID:', requestId);相关文档
- 快速开始 - 完整的集成指南
- API 参考 - 详细的 API 文档
- 错误处理 - 错误码参考
- Webhook 安全 - 签名验证与安全建议
