跳到主要内容

你的首笔支付

逐步引导你创建并处理首笔 Pelago 支付。

实现目标

一个完整的支付流程,涵盖:

  1. 创建支付请求
  2. 向客户展示二维码
  3. 处理支付 Webhook
  4. 确认支付成功

前提条件

  • 已完成 SDK 安装(快速上手
  • 已配置沙盒环境(沙盒设置
  • 拥有一个基础 Web 服务器(以下为 Node.js/Express 示例)

完整示例:Express.js 支付服务器

import express from 'express';
import { PelagoClient } from '@pelago/sdk';

const app = express();
app.use(express.json());

// 初始化 Pelago 客户端
const pelago = new PelagoClient({
apiKey: process.env.PELAGO_API_KEY!,
apiSecret: process.env.PELAGO_API_SECRET!,
environment: 'sandbox'
});

// 存储待处理订单(生产环境请使用数据库)
const orders = new Map<string, { status: string; amount: number }>();

// 1. 创建新订单和支付
app.post('/api/checkout', async (req, res) => {
const { productId, email } = req.body;

// 创建订单
const orderId = `order_${Date.now()}`;
const amount = 25.00; // 商品价格

orders.set(orderId, { status: 'pending', amount });

try {
// 创建 Pelago 支付
const payment = await pelago.payments.create({
amount,
currency: 'USD',
cryptocurrency: 'USDC',
network: 'stellar-testnet',
merchantWallet: process.env.MERCHANT_WALLET!,
redirectUrl: `${process.env.APP_URL}/order/${orderId}/success`,
webhookUrl: `${process.env.APP_URL}/api/webhook`,
metadata: {
orderId,
customerEmail: email,
productId
}
});

res.json({
orderId,
paymentId: payment.id,
paymentUrl: payment.url,
qrCode: payment.qrCode,
expiresAt: payment.expiresAt
});

} catch (error) {
console.error('支付创建失败:', error);
res.status(500).json({ error: 'Failed to create payment' });
}
});

// 2. 查询支付/订单状态
app.get('/api/orders/:orderId', (req, res) => {
const order = orders.get(req.params.orderId);

if (!order) {
return res.status(404).json({ error: 'Order not found' });
}

res.json(order);
});

// 3. 处理 Pelago Webhook
app.post('/api/webhook', async (req, res) => {
const signature = req.headers['x-pelago-signature'] as string;

// 验证 Webhook 签名
if (!pelago.webhooks.verify(req.body, signature)) {
console.warn('无效的 Webhook 签名');
return res.status(401).json({ error: 'Invalid signature' });
}

const event = req.body;
const { orderId } = event.data.metadata;

console.log(`收到 Webhook: ${event.type},订单 ${orderId}`);

switch (event.type) {
case 'payment.completed':
// 更新订单状态
const order = orders.get(orderId);
if (order) {
order.status = 'paid';
orders.set(orderId, order);
}

// 触发履约(发送邮件、发货等)
console.log(`✅ 订单 ${orderId} 支付成功!`);
break;

case 'payment.failed':
const failedOrder = orders.get(orderId);
if (failedOrder) {
failedOrder.status = 'failed';
orders.set(orderId, failedOrder);
}
console.log(`❌ 订单 ${orderId} 支付失败`);
break;

case 'payment.expired':
const expiredOrder = orders.get(orderId);
if (expiredOrder) {
expiredOrder.status = 'expired';
orders.set(orderId, expiredOrder);
}
console.log(`⏱️ 订单 ${orderId} 支付已过期`);
break;
}

// 始终返回 200 以确认收到
res.status(200).json({ received: true });
});

// 启动服务器
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`服务器运行在端口 ${PORT}`);
});

测试你的集成

1. 启动服务器

# 设置环境变量
export PELAGO_API_KEY=test_pk_xxxxx
export PELAGO_API_SECRET=test_sk_xxxxx
export MERCHANT_WALLET=GXXXXX...
export APP_URL=https://your-ngrok-url.ngrok.io

# 启动服务器
npx ts-node server.ts

2. 使用 ngrok 暴露 Webhook

ngrok http 3000
# 复制生成的 https:// URL

3. 创建测试订单

curl -X POST http://localhost:3000/api/checkout \
-H "Content-Type: application/json" \
-d '{"productId": "prod_123", "email": "[email protected]"}'

响应:

{
"orderId": "order_1707401234567",
"paymentId": "pay_abc123",
"paymentUrl": "https://pay.sandbox.pelago.tech/pay_abc123",
"qrCode": "data:image/png;base64,...",
"expiresAt": "2025-02-08T22:30:00Z"
}

4. 完成支付

  1. 在浏览器中打开 paymentUrl
  2. 连接你的测试钱包
  3. 批准测试 USDC 转账
  4. 观察 Webhook 接收到 payment.completed 事件

5. 验证订单状态

curl http://localhost:3000/api/orders/order_1707401234567
{
"status": "paid",
"amount": 25.00
}

支付流程可视化

常见问题

Webhook 未收到

  1. 确保 Webhook URL 可被公网访问
  2. 检查 ngrok 日志中的传入请求
  3. 验证 Webhook URL 没有拼写错误

支付创建失败

  1. 检查 API 密钥环境变量
  2. 验证钱包地址格式
  3. 确保使用了正确的网络

签名验证失败

  1. 使用原始请求体(未解析的)
  2. 确保 x-pelago-signature 请求头存在
  3. 向验证函数传入正确的 API Secret

下一步

完成首笔支付后: