Appearance
Node.js SDK
@smartpay/node-sdk 是智收通支付开放接口的官方 TypeScript/Node.js 客户端。当前 SDK 源码已完成并通过自动化测试;正式安装坐标将在版本通过发布治理后显示于商户工作台开发者中心。
当前支持范围
| 方法 | 用途 | 对应接口 |
|---|---|---|
createCheckoutSession | 创建托管收银台会话 | POST /open/v1/checkout-sessions |
getCheckoutSession | 查询收银台会话 | GET /open/v1/checkout-sessions/{sessionId} |
createTerminalBarcodePayment | 门店终端微信付款码支付 | POST /open/v1/terminal-payments |
createRefund | 发起退款 | POST /open/v1/refunds |
getRefund | 查询退款 | GET /open/v1/refunds/{refundId} |
SDK 不提供银行账户操作、提现、储值钱包、分账写入或供应商 Capability API;这些能力与支付开放接口保持隔离。
初始化
ts
import { SmartPayClient } from '@smartpay/node-sdk';
const client = new SmartPayClient({
baseUrl: process.env.SMARTPAY_BASE_URL!,
appId: process.env.SMARTPAY_APP_ID!,
keyId: process.env.SMARTPAY_KEY_ID!,
secret: process.env.SMARTPAY_APP_SECRET!,
timeoutMs: 10_000,
});凭据只应保存在服务端密钥管理系统或受控环境变量中,不得写入前端、小程序、APP、日志或代码仓库。生产地址必须使用 HTTPS;HTTP 仅允许本机联调。
创建支付会话
ts
const session = await client.createCheckoutSession(
{
outTradeNo: 'ORDER_20260918_0001',
merchantId: 'mch_example',
amountFen: 100,
currency: 'CNY',
subject: '测试订单',
scene: 'H5',
paymentProductCodes: ['JEEPAY_AGGREGATE', 'TENCENT_BUSINESS_PAY'],
returnUrl: 'https://merchant.example.com/payment-result',
},
{ idempotencyKey: 'checkout_ORDER_20260918_0001' },
);写操作会自动生成幂等键,也可由业务系统传入稳定的 idempotencyKey。同一业务请求重试时必须复用原键,不应为每次重试生成新键。
指定 paymentProductCodes 后,SDK 返回的会话可能处于 CREATED,并包含付款人可见的 paymentMethods。商户只需把付款人导向 /checkout/{sessionId};托管页负责提交不透明 optionId,内部渠道选择完全由 SmartPay 服务端完成。
门店终端付款码
ts
const payment = await client.createTerminalBarcodePayment(
{
outTradeNo: 'POS_20260920_0001',
merchantId: 'mch_example',
storeId: 'store_example',
terminalId: 'terminal_example',
amountFen: 1288,
currency: 'CNY',
subject: '门店收银',
authCode: scannedWechatPayerCode,
},
{ idempotencyKey: 'terminal_POS_20260920_0001' },
);authCode 只能来自收银终端当次扫码,不得记录、持久化或传入异步任务。SDK 只把它放在签名的 HTTPS 请求体中,不加入 URL、请求头或错误对象。返回 UNKNOWN 时查询原订单,不要换单号重试。
错误处理
ts
import { SmartPayApiError, SmartPayTransportError } from '@smartpay/node-sdk';
try {
await client.getCheckoutSession('cso_example');
} catch (error) {
if (error instanceof SmartPayApiError) {
console.error(error.code, error.status, error.traceId);
} else if (error instanceof SmartPayTransportError) {
console.error(error.code);
}
}SmartPayApiError表示平台已返回标准业务错误,可记录错误码和traceId后按错误码处理。SmartPayTransportError表示超时、网络失败、配置错误或响应格式异常。- SDK 不在错误对象中返回应用密钥,也不自动重试写操作;调用方应结合幂等键实施有界重试。
Webhook 验签
ts
import { verifyWebhookSignature } from '@smartpay/node-sdk';
const rawBody = new Uint8Array(await request.arrayBuffer());
const valid = verifyWebhookSignature({
secret: process.env.SMARTPAY_WEBHOOK_SECRET!,
timestamp: request.headers.get('x-webhook-timestamp') ?? '',
signature: request.headers.get('x-webhook-signature') ?? '',
rawBody,
});
if (!valid) {
// 返回非 2xx,且不要更新订单或退款状态
}rawBody 必须是 Web 框架读取到的原始 UTF-8 字节,不能先解析 JSON 再序列化。验签器使用恒定时间比较,默认只接受服务器当前时间前后 300 秒内的通知。验签通过后仍须以 eventId 建立唯一约束,处理重复投递和乱序事件。
完整字段、状态和错误码以 OpenAPI 接口定义 为准。