@delopay/sdk

中文文档
0.385.0发布于 2026/11/12MITTypeScriptESM + CJS零依赖近 30 天下载 1.5万

官方 Delopay 类型SDK

中文使用文档
文档目录19 节
  1. 安装
  2. 快速启动
  3. 配置
  4. 用法实例
  5. 创建付款
  6. 创建退款
  7. 管理客户
  8. 从目录上出售
  9. 开具发票
  10. 处理争议
  11. 检查付款失败的原因
  12. 管理商店和网关
  13. 订阅
  14. 平台收费规则
  15. Webhook 校验
  16. 处理错误
  17. 类型脚本
  18. 环境
  19. 许可证

@delopay/sdk (英语)

脚本 SDK 类型 德罗帕 支付API. 零依赖性,在Node 18+和浏览器中工作.

安装

pnpm add @delopay/sdk
npm install @delopay/sdk
yarn add @delopay/sdk

快速启动

import { Delopay } from '@delopay/sdk';

const delopay = new Delopay(process.env.DELOPAY_API_KEY!);

const payment = await delopay.payments.create({
  amount: 1000, // in minor units (€10.00)
  currency: 'EUR',
  description: 'Order 1234',
  customer_id: 'cus_abc123',
});

console.log(payment.payment_id, payment.status);

配置

const delopay = new Delopay(apiKey, {
  sandbox: true, // Use https://sandbox.delopay.net (default: false → production)
  baseUrl: 'https://…', // Override base URL entirely
  timeout: 30_000, // Request timeout in ms (default: 30 000)
});

API 密钥 :

  • prd_… 编号 : snd_… ——服务器侧密钥. 完全API访问. 保持这个秘密.
  • pk_prd_… 编号 : pk_snd_… ——客户端可发布密钥. 限于浏览器安全操作.

用法实例

创建付款

永远不要通过SDK发送生卡号码. 德罗帕伊的API不是 生- PAN 端点: 在 Delopay 上收集卡片 主机离职 (或通过支付链接),所以卡片数据从不触及您的服务器并停留 从你的PCI范围。 服务器端您创建付款并交给购买者 关闭; 您只用保存的确认服务器侧 payment_token页:1 mandate_id,或重定向方法(如PayPal钱包)——永远不要卡数据.

// Recommended: hosted checkout via a payment link.
const payment = await delopay.payments.create({
  amount: 2500,
  currency: 'EUR',
  payment_link: true,
  customer_id: 'cus_abc123',
  description: 'Order 1234',
  return_url: 'https://example.com/checkout/complete',
});

// Send the buyer here — they pick a method and enter card details on the
// hosted page. Delopay handles 3-D Secure and redirects.
console.log(payment.payment_link?.link);

// Fulfil on the payment_succeeded webhook, or re-check server-side:
const final = await delopay.payments.retrieve(payment.payment_id);

确认服务器侧 没有卡片数据 ——带有被保存的符号(会外):

const confirmed = await delopay.payments.confirm(pending.payment_id, {
  payment_token: savedPaymentToken, // from paymentMethods.listForCustomer()
  off_session: true,
  return_url: 'https://example.com/checkout/complete',
});

console.log(confirmed.status); // 'succeeded' | 'requires_customer_action' | …

或采用完全没有卡片数据的重定向支付方法:

const paypal = await delopay.payments.create({
  amount: 2500,
  currency: 'EUR',
  confirm: true,
  payment_method: 'wallet',
  payment_method_type: 'paypal',
  payment_method_data: { wallet: { paypal_redirect: {} } },
  return_url: 'https://example.com/checkout/complete',
});
// paypal.next_action?.redirect_to_url → send the buyer there to approve

创建退款

const refund = await delopay.refunds.create({
  payment_id: 'pay_abc123',
  amount: 1000, // partial refund; omit for full refund
  reason: 'Customer request',
});

console.log(refund.refund_id, refund.status);

管理客户

const customer = await delopay.customers.create({
  name: 'Jane Doe',
  email: '[email protected]',
  metadata: { plan: 'pro' },
});

// List saved payment methods
const { customer_payment_methods } = await delopay.paymentMethods.listForCustomer(
  customer.customer_id,
);

// Use a saved method on a new payment
const payment = await delopay.payments.create({
  amount: 1000,
  currency: 'EUR',
  customer_id: customer.customer_id,
  payment_token: customer_payment_methods[0]?.payment_token,
  confirm: true,
});

从目录上出售

// A product belongs to a shop; every call names the shop last.
const product = await delopay.products.create(
  {
    name: 'Annual report',
    kind: 'one_time',
    prices: [{ amount: 2999, currency: 'EUR', is_default: true }],
  },
  'pro_abc123',
);

// Price a payment from the catalog: no amount, no currency — the server
// freezes the product's active default price (or a named `price_id`) onto it.
const payment = await delopay.payments.create({
  product_id: product.id,
  profile_id: 'pro_abc123',
  payment_link: true,
});

// What the payment sold, as it was when it was created — unchanged by later
// catalog edits or deletion.
const sold = await delopay.payments.productLines(payment.payment_id);

开具发票

// Invoices and credit notes in your name, from a paid payment or subscription
// cycle. Amounts always come from the source.
const invoice = await delopay.invoices.create(
  { source: { payment_id: 'pay_abc123' }, finalize: true },
  { headers: { 'Idempotency-Key': 'invoice-order-1001' } },
);
const pdf = await delopay.invoices.downloadPdf(invoice.id);

// How they look and are taxed: the merchant default, or one shop's override.
const current = await delopay.invoiceSettings.retrieveForShop('pro_abc123');
await delopay.invoiceSettings.updateForShop('pro_abc123', { ...current, locale: 'de' });

处理争议

// Disputes for one payment come from the payment object:
const payment = await delopay.payments.retrieve('pay_abc123');

for (const dispute of payment.disputes ?? []) {
  console.log(dispute.dispute_id, dispute.dispute_stage, dispute.dispute_status);
}

// Or list disputes across the account, filtered by status:
const open = await delopay.disputes.list({ dispute_status: 'dispute_opened' });

检查付款失败的原因

// Every attempt on a payment — including retries across connectors — with its
// full failure detail (raw code + Delopay-unified, human-readable reason).
const { size, data } = await delopay.payments.listAttempts('pay_abc123');

for (const attempt of data) {
  // e.g. "stripe failure — Insufficient funds (51)"
  console.log(
    `${attempt.connector ?? 'unknown'} ${attempt.status} — ` +
      `${attempt.unified_message ?? attempt.error_message ?? 'no error'}` +
      `${attempt.error_code ? ` (${attempt.error_code})` : ''}`,
  );
}

管理商店和网关

// Create a shop (business profile)
const shop = await delopay.shops.create(merchantId, {
  shop_name: 'My Online Store',
  webhook_url: 'https://example.com/webhooks/delopay',
  return_url: 'https://example.com/checkout/complete',
});

// Connect Stripe as a payment gateway
const gateway = await delopay.shops.gateways.connect(merchantId, shop.shop_id, {
  connector_type: 'payment_processor',
  connector_name: 'stripe',
  connector_account_details: {
    auth_type: 'HeaderKey',
    api_key: process.env.STRIPE_SECRET_KEY,
  },
  test_mode: true,
});

// List connected gateways
const gateways = await delopay.shops.gateways.list(merchantId, shop.shop_id);

订阅

连通商店的帐单处理器( Stripe) 开出账单或付账。 每个订阅电话都是 配置范围 - 通过 店铺 X-Profile-Id 因此后端可以解决计费处理器(您得到 IR_04 否则:

const opts = { headers: { 'X-Profile-Id': profileId } };

浏览计划和估计费用 在创建任何内容之前 :

// List plans (or addons) with their prices. An item the processor lists but
// cannot sell right now comes back with `available: false` and no prices;
// skip it rather than offering it.
const plans = await delopay.subscriptions.getItems({ item_type: 'plan' }, opts);
const priceId = plans.find((item) => item.available)?.price_id[0]?.price_id;
if (!priceId) {
  throw new Error('No purchasable plan on this shop');
}

// Preview what the customer will be charged
const estimate = await delopay.subscriptions.getEstimate({ item_price_id: priceId }, opts);
console.log(estimate.amount, estimate.currency, estimate.interval); // 1500 'EUR' 'Month'

从不发送生卡号码. 订阅 API 拒绝 payment_method_data.card 用生的PAN来做 卡片由客户端收集 连接器的主机字段( Stripe Elements) , 所以卡片从不触及您 服务器,将原始卡数据保留在 PCI 范围之外。 以主机确认 退出会话或先前保存的代号,如下所示 .

建议:主机离职. 创建订阅服务器侧, 然后发送 delopay的买方与退货人一起办理了离职手续 client_secret编辑 买方在连接器iframe中输入他们的卡片;你从不处理 PAN:

const pending = await delopay.subscriptions.create(
  {
    item_price_id: priceId,
    customer_id: 'cus_abc123',
    payment_details: { return_url: 'https://example.com/subscription/complete' },
  },
  opts,
);

// Redirect the buyer to the hosted checkout to enter their card.
const checkoutUrl =
  `https://checkout.delopay.net/pay/${merchantId}/${pending.id}` +
  `?cs=${encodeURIComponent(pending.client_secret ?? '')}`;
// → res.redirect(checkoutUrl)

// Activation arrives via the subscription/invoice webhooks; never trust the
// client. Reconcile with subscriptions.retrieve(pending.id, opts).

节省的支付方法(课外). 如果客户已经存了钱, 象征性的支付方法, 用符号确认服务器侧- 仍然没有 PAN :

const sub = await delopay.subscriptions.createAndConfirm(
  {
    item_price_id: priceId,
    customer_id: 'cus_abc123',
    payment_details: {
      payment_method: 'card',
      payment_method_id: savedPaymentMethodId, // token, not a card number
      setup_future_usage: 'off_session',
      return_url: 'https://example.com/subscription/complete',
    },
  },
  opts,
);

if (sub.redirect_url) {
  // Some processors (e.g. PayPal) still need buyer approval — redirect there.
} else {
  console.log(sub.status); // 'active'
}

您也可以分割创建和确认 – 呼叫 subscriptions.confirm(id, …) 与 页:1 client_secret (单位:千美元) payment_token 一旦买主有了信物 同样的规则: (单位:千美元) payment_token 编号 : payment_method_id从来没有生牌.

管理寿命周期. 暂停、恢复和取消可选择的时间和 按比例控制;在没有机构的情况下,它们立即采取行动:

await delopay.subscriptions.pause(sub.id, { pause_option: 'end_of_term' }, opts);
await delopay.subscriptions.resume(sub.id, undefined, opts);
await delopay.subscriptions.cancel(
  sub.id,
  { cancel_option: 'immediately', credit_option_for_current_term_charges: 'prorate' },
  opts,
);

// Retrieve one, or list for the profile
const current = await delopay.subscriptions.retrieve(sub.id, opts);
const all = await delopay.subscriptions.list({ limit: 20 }, opts);

每个计费周期都开具发票(sub.invoice拥有自己的付款段 (单位:千美元)sub.payment);通过订阅/发票网络呼号跟踪周期结果.

关于目录产品的法案. 而不是处理器 item_price_id名称a 商店的经常性产品(以及可选择的价格之一)。 服务器 解决了账单账户的引用问题,拒绝了请求 当处理器的价格不再匹配时, 任何物品都会被收取。 检查 第一个价格可以开始订阅 :

const { prices } = await delopay.products.billingReadiness(['prd_pro'], profileId);
// state: 'ready' | 'unverified' | 'other_environment' | 'needs_reference'

await delopay.subscriptions.createAndConfirm(
  { product_id: 'prd_pro', customer_id: 'cus_abc123', payment_details: { payment_method_id: pm } },
  opts,
);
await delopay.subscriptions.update(sub.id, { product_id: 'prd_pro', price_id: 'prc_yearly' }, opts);

镜像处理器. subscriptions.sync({ subscription_ids }) (1至50个)和 subscriptions.syncOne(id) 从处理器和镜像中读取订阅 它所报道的,没有记载.

取消已有的处理器订阅 . subscriptions.importPreview 列出记账账户的持有情况,并对每行进行分类; importApply 通过 最多25个 单词 capabilities.reason_code 每个行的 note_code 自己; 英语 reason 编号 : note 旁边是API的电话.

const preview = await delopay.subscriptions.importPreview({ merchant_connector_id: mca }, opts);

if (!preview.capabilities.listing || !preview.capabilities.adoption) {
  // PayPal cannot be listed (`reason_code: 'listing_unsupported'`); an
  // account may list without allowing adoption. Say why, and stop.
  showUnavailable(preview.capabilities.reason_code);
} else {
  // Rows whose buyer is already a DeloPay customer can be taken over as they
  // are; `needs_customer` rows need a customer named first.
  const picks = preview.items.flatMap((row) =>
    row.classification === 'new' && row.customer_id
      ? [{ external_subscription_id: row.external_subscription_id, customer_id: row.customer_id }]
      : [],
  );
  // The route takes 1 to 25 selections: send nothing when there is nothing
  // to take over, and batch anything larger.
  for (let i = 0; i < picks.length; i += 25) {
    const { results } = await delopay.subscriptions.importApply(
      { merchant_connector_id: mca, items: picks.slice(i, i + 25) },
      opts,
    );
    // One result per selection: `adopted`, `already_held`, or `failed` with a `reason_code`.
  }
}

一个买家从处理器的结账中回来 可以读取订阅的 带有返回符号的状态( e)rt从浏览器运回的 URL :

const session = new CheckoutSession({ merchantId, paymentId: subscriptionId });
const { status, awaiting_processor } = await session.subscriptionReturnStatus(rt);

平台收费规则

按支付方法、连接器、金额、货币或卡对平台收费定价 腾讯网. 构建规则程序 feeProgram() 规则是按顺序进行的, 第一次比赛获胜,否则默认适用:

import { Delopay, feeProgram } from '@delopay/sdk';

const delopay = new Delopay(process.env.DELOPAY_API_KEY ?? '');

const algorithm = feeProgram()
  .rule({ name: 'crypto', when: { paymentMethod: 'crypto' }, fee: { percentage: 1.0 } })
  .rule({
    name: 'card_on_cryptomus',
    when: { paymentMethod: 'card', connector: 'cryptomus' },
    fee: { percentage: 2.0 },
  })
  .otherwise({ percentage: 3.0 })
  .build();

await delopay.fees.rules.upsert({ algorithm }, 'merchant_abc123');

const program = await delopay.fees.rules.retrieve('merchant_abc123'); // or null
await delopay.fees.rules.delete('merchant_abc123'); // revert to flat schedules

没有规则程序的商人保留现有的统一收费表/音量 等级不变.

Webhook 校验

Delopay在原始请求体上用 HMAC-SHA512 标记每个出局的网页,并在 X-Webhook-Signature-512 头曰. 使用 express.raw() (无) express.json()),所以字节到达验证符不变.

经核实的事件与线体相符: { merchant_id, event_id, event_type, content: { type, object }, timestamp }。 。 。 . event_type 说明发生了什么(例如:. 'payment_succeeded'(三); content.type 标记有效载荷类型(例如:. 'payment_details')——收缩取出打字 content.object (付款/退款/争议 payment_id 页:1.

import express from 'express';
import { Delopay } from '@delopay/sdk';

app.post('/webhooks/delopay', express.raw({ type: 'application/json' }), async (req, res) => {
  const signature = req.header('x-webhook-signature-512') ?? '';
  const secret = process.env.DELOPAY_WEBHOOK_SECRET!;

  let event;
  try {
    event = await Delopay.webhooks.verify(req.body, signature, secret);
  } catch {
    return res.status(400).send('Invalid signature');
  }

  if (event.content.type === 'payment_details') {
    const payment = event.content.object; // typed: PaymentResponse
    switch (event.event_type) {
      case 'payment_succeeded':
        // fulfil order — payment.payment_id, payment.amount, payment.currency
        break;
      case 'payment_failed':
        // notify customer — payment.error_message
        break;
    }
  }

  res.json({ received: true });
});

处理错误

所有错误都是 DelopayError数字 :

import { Delopay, DelopayError, DelopayAuthenticationError } from '@delopay/sdk';

try {
  const payment = await delopay.payments.retrieve('pay_does_not_exist');
} catch (err) {
  if (err instanceof DelopayAuthenticationError) {
    // status: 401 — invalid or missing API key
    console.error('Check your API key');
  } else if (err instanceof DelopayError) {
    console.error(err.message); // human-readable message
    console.error(err.status); // HTTP status code
    console.error(err.code); // machine-readable error code
    console.error(err.type); // error category (e.g. 'not_found')
    console.error(err.data); // structured context for select codes (see below)
  }
}

错误类别 :

类何时
DelopayError所有 API 错误的基准类
DelopayAuthenticationError401 — 无效或缺失的 API 密钥

网络超时 DelopayError 与 code: 'TIMEOUT'。网络失败 code: 'NETWORK'。 。 。 .

导出( E)delopay.export.*, (中文(简体) ), disputes.workspaceExport) 保存到服务器宣布的数 X-Delopay-Record-Count: 带有不同数量记录——或者通过一行或JSON文件以分道扬镳的方式结束——到达的文件 code: 'EXPORT_INCOMPLETE' (单位:千美元)err.data 实值 { expected_records, received_records })而不是解析到缺少行的文件。 过 onProgress 在导出选项中跟踪下载,以及 signal 用于取消.

一条活溪道( A)delopay.live.stream(),仪表板 JWT) 相投 code: 'NOT_EVENT_STREAM' 当服务器以其它方式回答 2xx时 text/event-stream,并与 code: 'TIMEOUT' 当它保持沉默过去 idleTimeoutMs (违约45 s). 它从未被SDK重新连接:参见整合指南 仪表板实时更新。 。 。 .

结构错误上下文( E)err.data: 用于一小组从机器可读提示中受益的代码. 目前:

err.codeerr.data 形状含义
UR_48{ retry_after_secs: number }TOTP尝试计数器被锁出——等待这几秒钟再重试.
UR_63{ retry_after_secs: number }Auth-endpoint 速率限制被绊倒了——在重试前等待这多秒.

类型脚本

SDK是用严格的TypeScript书写的. 所有请求和响应形状全部打入. 需要时直接导入类型 :

import type { PaymentResponse, PaymentCreateRequest, Currency } from '@delopay/sdk';

环境

环境基础 URLAPI 密钥前缀
生产https://api.delopay.netprd_… 编号 : pk_prd_…
沙盒https://sandbox.delopay.netsnd_… 编号 : pk_snd_…
// Sandbox
const delopay = new Delopay(process.env.DELOPAY_API_KEY!, { sandbox: true });

许可证

麻省理工学院

版本与发布记录

@delopay/sdk 共发布 314 个版本,首次发布于 2026/04/15;过去 12 个月发布了 314 个版本。

版本发布日期距今
0.385.0latest2026/11/12今天
0.384.02026/11/12今天
0.383.02026/11/11今天
0.380.02026/11/101 天前
0.379.02026/11/092 天前
0.378.02026/11/092 天前

其他发布通道:backfill → 0.169.0。

关于 @delopay/sdk 的常见问题

@delopay/sdk 是什么?

官方 Delopay 类型SDK

如何安装 @delopay/sdk?

在项目目录运行 npm install @delopay/sdk,或使用 pnpm add / yarn add / bun add。

@delopay/sdk 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@delopay/sdk 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@delopay/sdk 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@delopay/sdk 可以商用吗?

@delopay/sdk 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@delopay/sdk 的下载量有多少?

根据 npm 官方下载统计,@delopay/sdk 在 2026/10/12 – 2026/11/10 这 30 天内被下载 15,497 次,日均约 517 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@delopay/sdk 还在维护吗?

最新版本 0.385.0 发布于 2026/11/12(今天);至今共发布 314 个版本,其中过去 12 个月发布了 314 个;首次发布于 2026/04/15。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。