npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@douyinpay_sdk/douyinpay-nodejs

v1.0.1

Published

Douyin Pay server-side SDK for Node.js

Readme

douyinpay-nodejs

抖音支付 Node.js 服务端 SDK。

本 SDK 使用 TypeScript 实现,HTTP Client 基于 urllib,同时支持 CommonJS 与 ESM 引入方式。

安装

npm install @douyinpay_sdk/douyinpay-nodejs

快速开始

ESM

import { createAutoClientRSA } from '@douyinpay_sdk/douyinpay-nodejs';

const sdk = await createAutoClientRSA({
  mchid: 'your_mchid',
  serial: 'your_merchant_cert_serial',
  privateKey: process.env.DOUYINPAY_PRIVATE_KEY!,
  encryptKey: process.env.DOUYINPAY_API_ENCRYPT_KEY!,
});

CommonJS

const { createClientRSA } = require('@douyinpay_sdk/douyinpay-nodejs');
const { readFileSync } = require('node:fs');

const sdk = createClientRSA({
  mchid: 'your_mchid',
  serial: 'your_merchant_cert_serial',
  privateKey: process.env.DOUYINPAY_PRIVATE_KEY,
  platformCertificate: readFileSync('/path/to/douyinpay_platform_certificate.pem', 'utf8'),
});

核心入口与依赖关系

SDK 对外入口统一从包根导出。业务代码通常只需要关注三类入口:初始化 client、调用 API、处理证书/回调。

| 入口 | 作用 | 依赖 | 说明 | | --- | --- | --- | --- | | createClientRSA(options) | 用本地平台证书/平台公钥初始化 client | mchid、商户证书 serial、商户 privateKeyplatformCertificate | 本地已持有平台证书,或希望自己管理证书文件 | | createAutoClientRSA(options) | 自动下载平台证书后初始化 client,并支持后台刷新 | mchid、商户证书 serial、商户 privateKey、接口加密 encryptKey | 希望 SDK 管理平台证书下载、缓存和刷新 | | sdk.getClient(path) | 获取某个接口路径的请求 client | 已初始化的 sdk | 下单、查单、退款等接口都通过它发起请求 | | downloadPlatformCertificates(options) | 单独下载平台证书 | mchid、商户证书 serial、商户 privateKey、接口加密 encryptKey | 只想下载证书并自行管理时使用 | | parseCallback(...) / CallbackHandler | 回调通知验签与解密 | 平台证书或自动证书管理器、接口加密 encryptKey、原始 headers/body | 支付、退款等异步通知处理 |

依赖关系简述:

商户配置
  ├─ 本地证书模式:createClientRSA
  │    └─ 使用传入的平台证书/公钥做响应验签
  │         └─ sdk.getClient(path) 调用下单、查单、退款等 API
  │
  └─ 自动证书模式:createAutoClientRSA
       └─ AutoCertificateManager
            ├─ downloadPlatformCertificates 下载并解密平台证书
            ├─ 内存缓存平台证书
            └─ sdk.getClient(path) 调用 API 时使用最新证书做响应验签

回调处理
  └─ parseCallback / CallbackHandler
       ├─ 使用平台证书验签回调原始 body
       └─ 使用接口加密密钥 encryptKey 解密 resource

说明:DouyinPaySdk 是底层 SDK 对象,推荐业务代码优先使用 createClientRSAcreateAutoClientRSA 初始化。

Client 初始化方式

SDK 目前提供两种 RSA client 初始化方式。两种方式创建出的 sdk 都是同一个调用入口,后续下单、查单、退款等 API 调用方式完全一致。

1. 本地单证书初始化

适合你已经在本地持有抖音支付平台证书,或希望证书文件完全由业务系统自行管理的场景。

必填项:

  • mchid:商户号
  • serial:商户证书序列号,用于请求签名头
  • privateKey:商户私钥 PEM 内容
  • platformCertificate:抖音支付平台证书 PEM 内容;也支持平台公钥内容

如果 platformCertificate 是完整证书 PEM,SDK 会自动解析平台证书序列号;如果传入的是平台公钥内容,则必须额外传 platformSerial

import { readFileSync } from 'node:fs';
import { createClientRSA } from '@douyinpay_sdk/douyinpay-nodejs';

const sdk = createClientRSA({
  mchid: 'your_mchid',
  serial: 'your_merchant_cert_serial',
  privateKey: readFileSync('/path/to/merchant_private_key.pem', 'utf8'),
  platformCertificate: readFileSync('/path/to/douyinpay_platform_certificate.pem', 'utf8'),
});

如果只传平台公钥,需要同时指定平台证书序列号:

const sdk = createClientRSA({
  mchid: 'your_mchid',
  serial: 'your_merchant_cert_serial',
  privateKey: process.env.DOUYINPAY_PRIVATE_KEY!,
  platformCertificate: process.env.DOUYINPAY_PLATFORM_PUBLIC_KEY!,
  platformSerial: 'your_platform_cert_serial',
});

这种方式不会自动下载平台证书;响应验签使用初始化时传入的证书或公钥。

2. 自动下载平台证书初始化

适合服务端长期运行使用。初始化时不需要传平台证书,SDK 会调用平台证书下载接口,用接口加密密钥解密平台证书,并按配置定时刷新证书。响应验签失败时会直接抛错,不会在验签链路中触发证书下载补偿。

必填项:

  • mchid:商户号
  • serial:商户证书序列号,用于请求签名头
  • privateKey:商户私钥 PEM 内容
  • encryptKey:接口加密密钥,用于解密平台证书下载接口返回的证书内容
import { readFileSync } from 'node:fs';
import { createAutoClientRSA } from '@douyinpay_sdk/douyinpay-nodejs';

const sdk = await createAutoClientRSA({
  mchid: 'your_mchid',
  serial: 'your_merchant_cert_serial',
  privateKey: readFileSync('/path/to/merchant_private_key.pem', 'utf8'),
  encryptKey: 'your_api_encrypt_key',
  // 可选:默认 24 小时后台刷新一次;传 0 可关闭定时刷新。
  refreshIntervalMs: 24 * 60 * 60 * 1000,
});

自动下载的证书会缓存在当前进程内存中,不会由 SDK 自动写入本地文件。

两种初始化方式创建出的 sdk 调用 API 的方式完全一致:

const response = await sdk
  .getClient('/v1/trade/transactions/native')
  .post(requestBody);

API 调用

SDK 的接口调用方式与常见 Node.js 支付 SDK 类似:先创建 client,然后通过 getClient(path) 获取指定接口客户端。

const client = sdk.getClient('/your/api/path');

await client.get(options);
await client.post(data, options);
await client.put(data, options);
await client.patch(data, options);
await client.delete(options);

SDK 会自动完成:

  • 请求签名
  • Authorization 头生成
  • Douyinpay-Sdk-Agent 客户端版本上报
  • HTTP 请求发送
  • 抖音支付响应验签

回调通知验签与解密

收到抖音支付回调后,应先使用平台证书对原始请求体进行验签,验签通过后再解密 resource。SDK 提供 parseCallbackCallbackHandler 两种入口。

使用本地平台证书

import { parseCallback } from '@douyinpay_sdk/douyinpay-nodejs';

const notify = await parseCallback(
  request.headers,
  rawBody,
  {
    encryptKey: 'your_api_encrypt_key',
    certs: {
      your_platform_cert_serial: platformCertificatePem,
    },
  },
);

console.log(notify.event_type);
console.log(notify.content); // resource 解密后的业务内容

使用自动证书管理器

如果传入 certificateProvider,SDK 会使用其中当前已缓存的平台证书参与回调验签;回调验签失败会直接抛错,不会触发证书下载补偿。

import { CallbackHandler, createAutoClientRSAWithManager } from '@douyinpay_sdk/douyinpay-nodejs';

const { sdk, certificateManager } = await createAutoClientRSAWithManager({
  mchid: 'your_mchid',
  serial: 'your_merchant_cert_serial',
  privateKey: merchantPrivateKeyPem,
  encryptKey: 'your_api_encrypt_key',
});

const handler = new CallbackHandler({
  encryptKey: 'your_api_encrypt_key',
  certificateProvider: certificateManager,
});

const notify = await handler.parse(request.headers, rawBody);

createAutoClientRSAWithManagercreateAutoClientRSA 使用同一套 AutoClient 初始化逻辑,只是额外返回 certificateManager,便于回调验签复用已初始化并定时刷新的平台证书。 sdk 可继续用于下单、查单、退款等 API 调用。

验签使用的原文格式为:

timestamp + "\n" + nonce + "\n" + body + "\n"

当前 Node.js SDK 支持 AEAD_AES_256_GCM 回调资源解密。

1. 下单

当前示例使用 Native 下单接口:

POST /v1/trade/transactions/native
const outTradeNo = `ORDER_${Date.now()}`;

const response = await sdk
  .getClient('/v1/trade/transactions/native')
  .post({
    mchid: 'your_mchid',
    appid: 'your_appid',
    description: '抖音支付测试订单',
    out_trade_no: outTradeNo,
    time_expire: new Date(Date.now() + 10 * 60 * 1000).toISOString(),
    notify_url: 'https://www.example.com/douyinpay/notify',
    attach: '',
    amount: {
      currency: 'CNY',
      total: 1,
    },
    ip: '127.0.0.1',
  });

console.log(response.status);
console.log(response.data);

返回示例:

{
  "code_url": "https://qr.douyinpay.com/xxxxx"
}

2. 查单

通过商户订单号查询订单:

GET /v1/trade/transactions/out-trade-no/{out_trade_no}?mchid={mchid}
const response = await sdk
  .getClient(`/v1/trade/transactions/out-trade-no/${encodeURIComponent(outTradeNo)}`)
  .get({
    query: {
      mchid: 'your_mchid',
    },
  });

console.log(response.status);
console.log(response.data);

返回示例:

{
  "mchid": "your_mchid",
  "appid": "your_appid",
  "out_trade_no": "ORDER_123456",
  "trade_state": "NOTPAY",
  "trade_state_desc": "未支付"
}

3. 平台证书下载

平台证书用于校验抖音支付响应签名。证书下载接口本身也需要商户私钥签名,请求成功后返回加密证书,SDK 会使用接口加密密钥进行 AES-256-GCM 解密。

import { readFileSync } from 'node:fs';
import { downloadPlatformCertificates } from '@douyinpay_sdk/douyinpay-nodejs';

const certificates = await downloadPlatformCertificates({
  mchid: 'your_mchid',
  serial: 'your_merchant_cert_serial',
  privateKey: readFileSync('/path/to/merchant_private_key.pem', 'utf8'),
  // 首次下载证书时还没有可信平台证书,可传 bootstrap 占位,并显式关闭本次下载响应验签。
  // 后续已有平台证书后,请传入实际 certs 并保持 verifyResponse 为默认 true。
  certs: { bootstrap: '' },
  verifyResponse: false,
  encryptKey: 'your_api_encrypt_key',
});

console.log(certificates);

返回结构:

[
  {
    serialNo: 'platform_cert_serial',
    certificate: '-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----',
    effectiveTime: '2026-01-01T00:00:00+08:00',
    expireTime: '2031-01-01T00:00:00+08:00'
  }
]

下载完成后,SDK 只返回证书内容,不会自动落盘。你可以自行保存,或将平台证书配置到 createClientRSA 中使用;如果使用 createAutoClientRSA,通常不需要手动调用本接口。

TypeScript 支持

SDK 内置 TypeScript 类型声明,无需额外安装 @types/*

import type { DouYinPayConfig, DouYinPayResponse } from '@douyinpay_sdk/douyinpay-nodejs';

错误处理

try {
  const response = await sdk
    .getClient('/v1/trade/transactions/native')
    .post(requestBody);

  console.log(response.data);
} catch (error) {
  console.error('DouyinPay request failed:', error);
}

常见错误包括:

  • 商户号、证书序列号、私钥或平台证书缺失
  • 请求签名失败
  • HTTP 请求失败
  • 响应缺少验签头
  • 平台证书序列号不匹配
  • 响应签名验签失败
  • 回调验签失败或 resource 解密失败

安全建议

  • 不要把商户私钥、接口加密密钥、平台证书本地配置提交到 GitHub
  • 不要在日志中打印商户私钥和接口加密密钥
  • 回调处理必须先验签,再解密和处理业务
  • 平台证书可能轮换,建议使用自动下载证书模式或定期更新本地证书

License

MIT