
Bnk 类型SDK 文档
1. 安装
先决条件
确保您在您的机器上安装以下设备:
- 夹克 财务报告和审定财务报表 多克编曲 用于本地运行 Blnk 服务器.
- 节点.js (v14或以后)和 无 用于安装 Blnk 类型SDK.
第1步: 克隆 Blnk 仓库
首先,从 GitHub 复制 Blnk 仓库 :
git clone https://github.com/blnkfinance/blnk && cd blnk
步骤2: 安装 Blnk 类型SDK
在您的工程中安装 Blnk 类型SDK :
npm install @blnkfinance/[email protected] --save
v1.6.0 目标 Blink 核心0.15.4。云代理服务器 instanceId 可在1.6.0中查阅。 见 发 言 对于错误目录, Search.multiSearch和列表方法(Ledgers.list, (中文(简体) ), LedgerBalances.list, (中文(简体) ), Transactions.list, (中文(简体) ), BalanceMonitor.listByBalanceId) (中文(简体) ).
步骤3:设置配置
在您的克隆目录中创建名为配置文件 blnk.json 内容如下:
{
"project_name": "Blnk",
"data_source": {
"dns": "postgres://postgres:password@postgres:5432/blnk?sslmode=disable"
},
"redis": {
"dns": "redis:6379"
},
"server": {
"domain": "blnk.io",
"ssl": false,
"ssl_email": "[email protected]",
"port": "5001"
},
"notification": {
"slack": {
"webhook_url": "https://hooks.slack.com"
}
}
}
此配置设置了 PostgreSQL 和 Redis 的连接, 指定您的服务器细节, 并在需要时允许 Slack 通知 .
2. 发射Blnk
通过 Docker 编曲,启动 Blnk 服务器 :
docker compose up
一旦运行,您的服务器将在 http://localhost:5001 (英语)。 。 。 .
健康检查
System.health 检查 Blnk Core 是否运行( GET) /health:
const health = await blnk.System.health();
// health.status === 200
// health.data?.status === 'UP'
3. 使用Blnk CLI
Blnk CLI为管理分类账、余额和交易提供快速访问。 为了验证安装和查看可用的命令,请使用:
blnk --help
4. 创建您的第一版
什么是莱德格?
在Blnk中,分类账用于对余额进行分类,以便有组织地跟踪. 当您首次安装 Blnk 时,默认会创建名为 General Ledger 的内部分类账.
分步前进:创建编辑器
使用 SDK 创建用户账户分类账 :
import { BlnkInit } from '@blnkfinance/blnk-typescript';
const blnk = await BlnkInit('<secret_key_if_set>', { baseUrl: 'http://localhost:5001' });
const { Ledgers } = blnk;
const newLedger = await Ledgers.create({
name: "Customer Savings Account",
meta_data: {
project_owner: "YOUR_APP_NAME"
}
});
console.log("Ledger Created:", newLedger);
这为存储客户余额建立了一个新的分类账.
使用 Blink 云代理服务器
呼叫核心通过 云代理服务器,通过您的 Cloud API 密钥(或 OAuth 访问符) 和 Core instance_id。SDK 保留相同的 Core 请求机构和路径,并用 /proxy发送 instance_id 作为查询参数.
import { BlnkInit, DEFAULT_CLOUD_API_BASE_URL } from '@blnkfinance/blnk-typescript';
const blnk = BlnkInit('<cloud_api_key>', {
baseUrl: DEFAULT_CLOUD_API_BASE_URL, // https://api.cloud.blnkfinance.com
instanceId: 'instance_...',
});
const newLedger = await blnk.Ledgers.create({
name: 'Customer Savings Account',
});
// POST https://api.cloud.blnkfinance.com/proxy/ledgers?instance_id=instance_...
instanceId 以1.6.0形式提供,并且用于代理路由。 直接和Core说话时关闭它(baseUrl 您的核心来源.
更新分类账名称
重新命名现有分类账,同时不改变其编号或影响余额和交易:
const updatedLedger = await Ledgers.update(
'ldg_073f7ffe-9dfd-42ce-aa50-d1dca1788adc',
{ name: 'Updated Customer Savings Account' },
);
console.log('Ledger Updated:', updatedLedger);
清单分类账、余额和交易
Ledgers.list, (中文(简体) ), LedgerBalances.list,以及 Transactions.list 包装核心 GET /ledgers, (中文(简体) ), GET /balances,以及 GET /transactions (自~0.14.x起存在;此SDK与Core 0.15.4. 关闭选项以使用 Core 的默认页面( O)limit=10 编号 : offset=0 分类账和余额, limit=20 交易)。 无效 limit 或者说 offset 用 HTTP 400 拒绝客户端.
const firstPage = await Ledgers.list();
const nextPage = await Ledgers.list({ limit: 10, offset: 10 });
const balances = await LedgerBalances.list({ limit: 50 });
const recentTransactions = await Transactions.list({ limit: 100 });
5. 创造身份
在将客户或组织与余额挂钩之前对其进行登记。 仅 identity_type 需要; 所有其他字段均为可选并匹配 创建身份 API 引用。SDK验证 identity_type 和字段格式(例如 identity_id, (中文(简体) ), dob, (中文(简体) ), gender当你提供它们.
最小创建 :
const { Identity } = blnk;
const minimal = await Identity.create({
identity_type: 'individual',
});
使用可选调用程序提供的全部实例 identity_id (单位:千美元)idt_ +UUID)和 ISO 8601 dob数字 :
const { Identity } = blnk;
const newIdentity = await Identity.create({
identity_id: 'idt_11111111-1111-4111-8111-111111111111',
identity_type: 'individual',
first_name: 'Jane',
last_name: 'Doe',
gender: 'female',
dob: '1990-01-15T00:00:00Z',
email_address: '[email protected]',
phone_number: '+1234567890',
nationality: 'US',
category: 'customer',
street: '123 Main St',
country: 'USA',
state: 'NY',
post_code: '10001',
city: 'New York',
});
console.log('Identity Created:', newIdentity);
隐藏身份字段
| 方法 | 终点 | 使用大小写 |
|---|---|---|
Identity.getTokenizedFields(id) | GET /identities/{identity_id}/tokenized-fields | 列出身份标识的字段 |
Identity.tokenizeField(id, field) | POST /identities/{identity_id}/tokenize/{field} | 将一个 PII 字段切入身份 |
Identity.tokenize(id, data) | POST /identities/{identity_id}/tokenize | 在身份上切换多个 PII 字段 |
Identity.detokenize(id, data) | POST /identities/{identity_id}/detokenize | 删除字段并返回原始值 |
Identity.detokenizeField(id, field) | GET /identities/{identity_id}/detokenize/{field} | 删除一个字段并返回其原值 |
const { Identity } = blnk;
const tokenizedFields = await Identity.getTokenizedFields(identity.data!.identity_id);
// tokenizedFields.data?.tokenized_fields — e.g. ["FirstName", "EmailAddress"]
// Tokenize a single field (PascalCase struct name in the path).
const oneField = await Identity.tokenizeField(identity.data!.identity_id, 'EmailAddress');
// oneField.data?.message — "Field tokenized successfully"
// Use PascalCase struct field names — not the snake_case JSON keys on IdentityData.
const tokenized = await Identity.tokenize(identity.data!.identity_id, {
fields: ['FirstName', 'LastName', 'EmailAddress', 'PhoneNumber'],
});
// tokenized.data?.message — "Fields tokenized successfully"
// Detokenize specific fields, or pass { fields: [] } to detokenize all tokenized fields.
const restored = await Identity.detokenize(identity.data!.identity_id, {
fields: ['FirstName', 'EmailAddress'],
});
// restored.data?.fields — e.g. { FirstName: "Jane", EmailAddress: "[email protected]" }
// Detokenize a single field and read the original value.
const email = await Identity.detokenizeField(identity.data!.identity_id, 'EmailAddress');
// email.data?.value — e.g. "[email protected]"
字段名称必须是核心结构名称( E)
FirstName, (中文(简体) ),EmailAddress通过first_name或者说email_address从IdentityData将被拒绝.
见 获取标识字段引用, (中文(简体) ), 切换字段引用, (中文(简体) ), 隐藏身份参考, (中文(简体) ), 调试字段引用,以及 解密身份参考。 。 。 .
删除身份
| 方法 | 终点 | 使用大小写 |
|---|---|---|
Identity.delete(id) | DELETE /identities/{identity_id} | 删除身份记录( 0. 15. 0+) |
const { Identity } = blnk;
const deleted = await Identity.delete(identity.data!.identity_id);
// deleted.data?.message — "Identity deleted successfully"
见 删除身份引用。 。 。 .
6. 创造平衡
余额代表分类账内的价值存储,如钱包或账户. 每个余额都属于一个分类账.
步入:创造平衡
要建立平衡,请具体说明 ledger_id 其他细节:
const { LedgerBalances } = blnk;
const newBalance = await LedgerBalances.create({
ledger_id: "ldg_073f7ffe-9dfd-42ce-aa50-d1dca1788adc",
currency: "USD",
meta_data: {
first_name: "Alice",
last_name: "Hart",
account_number: "1234567890"
}
});
console.log("Balance Created:", newBalance);
在核心上创建一般编辑器平衡 0.15.3+ (单位:千美元) 与 ledger_id: "general_ledger_id" 还有一个 @ 指标:
const glBalance = await LedgerBalances.create({
ledger_id: "general_ledger_id",
currency: "USD",
indicator: "@WorldUSD",
});
启用了资金分行跟踪(要求) identity_id:
const lineageBalance = await LedgerBalances.create({
ledger_id: "ldg_073f7ffe-9dfd-42ce-aa50-d1dca1788adc",
identity_id: "idt_3b63c8da-af29-4cc3-ad38-df17d87456e6",
currency: "USD",
track_fund_lineage: true,
allocation_strategy: "FIFO", // FIFO | LIFO | PROPORTIONAL
});
获得平衡
LedgerBalances.get 以 ID 检索余额( N)GET /balances/{balance_id}) (中文(简体) ). 过 { from_source: true } 从交易中重建余额而不是快照:
const response = await LedgerBalances.get(
'bln_5ce86029-3c2e-4e2a-aae2-7fb931ca4c4f',
{ from_source: true },
);
// response.data.balance_id
// response.data.balance
按指标取得平衡
LedgerBalances.getByIndicator 根据其指标和货币检索余额(GET /balances/indicator/{indicator}/currency/{currency}:
const response = await LedgerBalances.getByIndicator('@World', 'USD');
// response.data.balance_id
// response.data.indicator
// response.data.currency
更新平衡身份
LedgerBalances.updateIdentity 将平衡与身份联系起来(PUT /balances/{id}/identity:
const response = await LedgerBalances.updateIdentity(
'bln_5ce86029-3c2e-4e2a-aae2-7fb931ca4c4f',
{ identity_id: 'idt_3b63c8da-af29-4cc3-ad38-df17d87456e6' },
);
// response.data.message
创建平衡快照
LedgerBalances.createSnapshot 触发分批进行的每日平衡快照(POST /balances-snapshots) (中文(简体) ). 奥米 batch_size 或通过零来使用服务器默认值(1 000):
const response = await LedgerBalances.createSnapshot({ batch_size: 500 });
// response.data.message
取得历史平衡
LedgerBalances.getAt 在特定时间戳获取余额( q)GET /balances/{balance_id}/at:
const response = await LedgerBalances.getAt(
'bln_5ce86029-3c2e-4e2a-aae2-7fb931ca4c4f',
{ timestamp: '2025-02-24T08:55:26Z', from_source: true },
);
// response.data.balance.balance_id
// response.data.balance.balance
// response.data.timestamp
获得平衡分行
LedgerBalances.getLineage 检索供应商的明细表,以找到已启用的基金细目余额(GET /balances/{balance_id}/lineage:
const response = await LedgerBalances.getLineage(
'bln_5ce86029-3c2e-4e2a-aae2-7fb931ca4c4f',
);
// response.data.balance_id
// response.data.total_with_lineage
// response.data.providers
删除平衡显示器
| 方法 | 终点 | 使用大小写 |
|---|---|---|
BalanceMonitor.list() | GET /balance-monitors | 列出全部平衡显示器 |
BalanceMonitor.listByBalanceId(id) | GET /balance-monitors/balances/{balance_id} | 一个余额的列表显示器 |
BalanceMonitor.delete(id) | DELETE /balance-monitors/{monitor_id} | 删除平衡显示器( 0. 15. 0+) |
const { BalanceMonitor } = blnk;
const forBalance = await BalanceMonitor.listByBalanceId(
'bln_5ce86029-3c2e-4e2a-aae2-7fb931ca4c4f',
);
// forBalance.data — MonitorDataResp[]
const deleted = await BalanceMonitor.delete(monitor.data!.monitor_id);
// deleted.data?.message — "BalanceMonitor deleted successfully"
见 删除平衡显示器引用。 。 。 .
6. 记录交易
交易跟踪您申请中的金融活动。 Blink确保每笔交易既不可改变,又具有一能性.
步入:记录交易
要记录交易,您需要 source 财务报告和审定财务报表 destination 平衡标识 :
const { Transactions } = blnk;
const newTransaction = await Transactions.create({
amount: 750,
reference: "ref_001adcfgf",
currency: "USD",
precision: 100,
source: "bln_28edb3e5-c168-4127-a1c4-16274e7a28d3",
destination: "bln_ebcd230f-6265-4d4a-a4ca-45974c47f746",
description: "Sent from app",
meta_data: {
sender_name: "John Doe",
sender_account: "00000000000"
}
});
console.log("Transaction Recorded:", newTransaction);
运行交易
核心状态 0.15.3+ (单位:千美元)设置 dry_run: true 创建、批量创建、退款、飞行 updateStatus, (中文(简体) ), bulkCommitInflight,或 bulkVoidInflight 预览余额而不写入任何内容。 反应是 HTTP 200 与 would_apply 财务报告和审定财务报表 balances - 不是贴出交易的.
const preview = await Transactions.create({
amount: 120,
precision: 100,
reference: 'ref_card_settle_4821',
description: 'Card settlement preview',
currency: 'USD',
source: '@WorldUSD',
destination: '@MyBalance',
dry_run: true,
});
// preview.status === 200
// preview.data?.dry_run === true
// preview.data?.would_apply
dry_run 被歧视,所以预览从未作为张贴交易键入。 使用普通请求类型输入的请求保留已张贴的响应,所以现有代码不受影响:
const body: CreateTransactions<Meta> = {/* ... */};
const posted = await Transactions.create(body);
posted.data?.transaction_id; // still typed
// Preview: pass the flag inline, or type the body as DryRun<...>
const previewBody: DryRun<CreateTransactions<Meta>> = {...body, dry_run: true};
const preview = await Transactions.create(previewBody);
preview.data?.would_apply; // TransactionPreview — no transaction_id
当国旗只在运行时才为人所知时, 回应会扩展至张贴或审查联盟
const result = await Transactions.create({...body, dry_run: shouldPreview});
if (result.data && 'transaction_id' in result.data) {
console.log('posted', result.data.transaction_id);
} else if (result.data) {
console.log('preview', result.data.would_apply);
}
见 干线交易。 。 。 .
原子分裂交易
设定 atomic: true 当创建分拆交易时( e)destinations 或者说 sources所以所有腿一起成功或失败:
const response = await Transactions.create({
amount: 1000,
precision: 100,
reference: 'atomic_split_ref_001',
description: 'Atomic fee split',
currency: 'USD',
source: '@FundingPool',
destinations: [
{ identifier: 'bln_fee', distribution: '240.23' },
{ identifier: 'bln_recipient', distribution: 'left' },
],
atomic: true,
skip_queue: true,
});
以身份获取交易
Transactions.get 从交易中获取 transaction_id (电话) /transactions/{transaction_id}:
const response = await Transactions.get('txn_04551509-d7d3-4eab-a1fd-2eb12809b5a4');
通过引用获取交易
Transactions.getByReference 从交易中获取 reference (电话) /transactions/reference/{reference}:
const response = await Transactions.getByReference('ref_04551509-d7d3-4eab-a1fd-2eb12809b5a4');
恢复队列交易
Transactions.recoverQueue 手动触发已锁定队列交易的回收( s)POST /transactions/recover) (中文(简体) ). 可选通过 a threshold 持续时间查询(例如). 5m, (中文(简体) ), 1h:
const response = await Transactions.recoverQueue({ threshold: '5m' });
// response.data.recovered, response.data.threshold
获取交易行
Transactions.getLineage 获取交易的资金分配和阴影交易( GET) /transactions/{transaction_id}/lineage:
const response = await Transactions.getLineage('txn_8d2ce2f0-0d75-4a91-9d43-2ad2c2e6b9ad');
// response.data.transaction_id
// response.data.fund_allocation
// response.data.shadow_transactions
更新飞行中的交易状况
核心 0.15.0 (韩语) 队列在飞行中执行并默认无效。 答复包括: queued: true (情况一般是: QUEUED 除非工人处理行动。 发送 skip_queue: true 现时使用 APPLIED 或者说 VOID 反应(之前的同步行为).
Transactions.updateStatus 接受 precise_amount 部分承诺的飞行交易(除 amount) (中文(简体) ). 将剩余飞行量全部放入两地:
// Queued commit (default in Core 0.15.0)
const queued = await Transactions.updateStatus(transactionId, { status: 'commit' });
// queued.data?.queued === true
// Synchronous commit
await Transactions.updateStatus(transactionId, {
status: 'commit',
skip_queue: true,
});
// Partial commit in minor units
await Transactions.updateStatus(transactionId, {
status: 'commit',
precise_amount: 50000,
skip_queue: true,
});
大量从事飞行交易
Transactions.bulkCommitInflight 在一个请求中进行多个独立创建的飞行交易(POST /transactions/inflight/bulk/commit) (中文(简体) ). 默认情况下,每个项目都会被排队(status: 'queued' (见E/CN.4/Sub.2/2003/L.10)。 过 skip_queue: true 用于同步处理。 奥米 amount 财务报告和审定财务报表 precise_amount 将剩余飞行量全额承付的物品:
const response = await Transactions.bulkCommitInflight({
skip_queue: true,
transactions: [
{ transaction_id: 'txn_11111111-1111-4111-8111-111111111111' },
{ transaction_id: 'txn_22222222-2222-4222-8222-222222222222', amount: 40 },
{
transaction_id: 'txn_33333333-3333-4333-8333-333333333333',
precise_amount: 125034,
},
],
});
// response.data.succeeded, response.data.failed, response.data.results
const commitPreview = await Transactions.bulkCommitInflight({
dry_run: true,
transactions: [
{ transaction_id: 'txn_11111111-1111-4111-8111-111111111111' },
],
});
// commitPreview.data?.dry_run === true
// commitPreview.data?.would_apply
空飞机交易
Transactions.bulkVoidInflight 在一个请求中取消多个独立创建的飞行交易(POST /transactions/inflight/bulk/void) (中文(简体) ). 默认情况下,每个项目都会被排入队列. 过 skip_queue: true 用于同步空格 :
const response = await Transactions.bulkVoidInflight({
skip_queue: true,
transaction_ids: [
'txn_11111111-1111-4111-8111-111111111111',
'txn_22222222-2222-4222-8222-222222222222',
],
});
// response.data.succeeded, response.data.failed, response.data.results
const voidPreview = await Transactions.bulkVoidInflight({
dry_run: true,
transaction_ids: ['txn_11111111-1111-4111-8111-111111111111'],
});
退款交易
Transactions.refund 接受可选机构 skip_queue 以同步处理退款。 核心状态 0.15.3+ (单位:千美元) 您也可以设置 description, (中文(简体) ), meta_data,以及 dry_run。将身体排队退款(默认) :
// Queued refund (default)
await Transactions.refund(transactionId);
// Synchronous refund
await Transactions.refund(transactionId, { skip_queue: true });
// Refund with description and metadata
await Transactions.refund(transactionId, {
description: 'Card reversal',
meta_data: { type: 'refund' },
});
// Preview without writing
await Transactions.refund(transactionId, { dry_run: true });
创建交易响应
Transactions.create 决定: CreateTransactionResponse 匹配核心 API 引用,包括 hash, (中文(简体) ), parent_transaction, (中文(简体) ), allow_overdraft,和飞行日期字段(scheduled_for, (中文(简体) ), inflight_expiry_date, (中文(简体) ), inflight_commit_date:
interface CreateTransactionResponse<T extends Record<string, unknown>> {
transaction_id: string;
amount: number;
precision: number;
precise_amount: number | string;
reference: string;
description: string;
rate?: number;
currency: string;
status: StatusType;
hash: string;
parent_transaction: string; // empty string when none
allow_overdraft: boolean;
inflight: boolean;
created_at: Date | string;
scheduled_for: Date | string;
inflight_expiry_date: Date | string;
inflight_commit_date: Date | string;
effective_date?: Date | string;
source?: string;
destination?: string;
meta_data?: T;
}
7. 大宗交易
Blnk JavaScript SDK支持批量交易,允许您在一次请求中提交多个交易记录,以改善性能和原子交易处理.
概览
散装交易API提供以下好处:
- 业绩: 在一个API呼叫中提交多个交易
- 原子:确保所有交易一起成败(当
atomic: true(中文(简体) ) - 同步处理: 同步处理大批量
- 飞行支助: 创建多种飞行交易,这些交易可在以后实施或作废
方法 签署
async createBulk<T extends Record<string, unknown>>(data: BulkTransactions<T>)
参数
大块交易接口
interface BulkTransactions<T extends Record<string, unknown>> {
atomic?: boolean; // Optional: All transactions succeed or fail together
inflight?: boolean; // Optional: Create transactions as inflight
run_async?: boolean; // Optional: Process transactions asynchronously
skip_queue?: boolean; // Optional: Process without queuing
transactions: CreateTransactions<T>[]; // Required: Array of transaction objects
}
用法实例
基本批量交易
const { Transactions } = blnk;
// Basic bulk transactions without additional options
const basicBulkData = {
transactions: [
{
amount: 1000,
precision: 100,
reference: 'bulk_txn_001',
description: 'Payment 1',
currency: 'USD',
source: '@source_account_1',
destination: '@destination_account_1',
},
{
amount: 2000,
precision: 100,
reference: 'bulk_txn_002',
description: 'Payment 2',
currency: 'USD',
source: '@source_account_2',
destination: '@destination_account_2',
},
],
};
const response = await Transactions.createBulk(basicBulkData);
console.log('Bulk transaction response:', response);
原子散装交易
// Atomic transactions - all succeed or all fail
const atomicBulkData = {
atomic: true,
transactions: [
{
amount: 5000,
precision: 100,
reference: 'atomic_txn_001',
description: 'Atomic payment 1',
currency: 'USD',
source: '@source_account_1',
destination: '@destination_account_1',
},
{
amount: 3000,
precision: 100,
reference: 'atomic_txn_002',
description: 'Atomic payment 2',
currency: 'USD',
source: '@source_account_2',
destination: '@destination_account_2',
},
],
};
const atomicResponse = await Transactions.createBulk(atomicBulkData);
带有所有选项的 Async 散装交易
// Process transactions asynchronously with atomic and inflight options
const asyncBulkData = {
atomic: true,
inflight: true,
run_async: true,
transactions: [
{
amount: 12000,
precision: 100,
reference: 'async_txn_001',
description: 'Async atomic inflight payment 1',
currency: 'USD',
source: '@source_account_1',
destination: '@destination_account_1',
allow_overdraft: true,
inflight_expiry_date: new Date(Date.now() + 48 * 60 * 60 * 1000), // 48 hours
meta_data: {
department: 'sales',
project: 'Q4_campaign',
},
},
{
amount: 8500,
precision: 100,
reference: 'async_txn_002',
description: 'Async atomic inflight payment 2',
currency: 'USD',
source: '@source_account_2',
destination: '@destination_account_2',
allow_overdraft: true,
inflight_expiry_date: new Date(Date.now() + 48 * 60 * 60 * 1000), // 48 hours
meta_data: {
department: 'marketing',
project: 'Q4_campaign',
},
},
],
};
const asyncResponse = await Transactions.createBulk(asyncBulkData);
批量交易响应
Transactions.createBulk 决定: BulkTransactionResponse 符合核心 API 引用(batch_id, (中文(简体) ), status, (中文(简体) ), transaction_count选择 message 用于合成批次:
interface BulkTransactionResponse {
batch_id: string;
status: 'applied' | 'inflight' | 'queued' | string;
transaction_count?: number; // present on synchronous success
message?: string; // present when run_async is true
}
响应格式
批量 API 返回批量元数据( 不嵌入交易对象) 。 见 批量交易响应 上方的键入形状.
审定规则
批量交易 API 验证如下:
- 所需字段数字 :
transactions数组必须提供,不能为空 - 最大大小数字 :
transactions数组不能超过 1万个 项目 - 交易验证: 阵列中的每一项交易都必须通过标准交易验证
- 独一无二的参考文献: 所有交易参考资料必须在批量请求中独有
- 布尔旗数字 :
atomic, (中文(简体) ),inflight, (中文(简体) ),run_async,以及skip_queue如果提供了布尔值, 则必须是布尔值 - 标准交易规则: 所有现行交易验证规则适用于每项交易
处理错误
比较 response.error?.code 相对于常数 BlnkErrorCode,它反映了完整的0.15.4核心目录(TXN_ALREADY_REFUNDED, (中文(简体) ), BAL_NOT_FOUND, (中文(简体) ), TXN_INSUFFICIENT_FUNDS, (中文(简体) ), TXN_DUPLICATE_REFERENCE, (中文(简体) ), LGR_NOT_FOUND,等等):
import {BlnkErrorCode} from '@blnkfinance/blnk-typescript';
const refund = await Transactions.refund(transactionId);
if (refund.error?.code === BlnkErrorCode.TXN_ALREADY_REFUNDED) {
// 409: already refunded, or this id is itself a refund — nothing to do
}
try {
const response = await Transactions.createBulk(bulkData);
if (response.status === 201) {
console.log('Bulk transactions created successfully:', response.data);
} else {
console.error('Bulk transaction error:', response.message);
}
} catch (error) {
console.error('Network or system error:', error);
}
单一交易的迁移
从单一交易转变为批量交易是直接的:
前 (单笔交易)
const tx1 = await Transactions.create(transactionData1);
const tx2 = await Transactions.create(transactionData2);
在( Bulk 交易) 之后
const bulkResponse = await Transactions.createBulk({
transactions: [transactionData1, transactionData2]
});
这种迁移提供了更好的性能和原子处理的选择.
8. 查看客户、余额和交易
Blnk CLI 允许您快速列出所有分类账,余额和交易:
- 列表调试器 :
blnk ledgers list - 列表余额 :
blnk balances list - 列表交易 :
blnk transactions list
搜索
默认搜索 APIs Search 服务 :
| 方法 | 终点 | 使用大小写 |
|---|---|---|
Search.search(params, collection) | POST /search/{collection} | 通过类型搜索全文 |
Search.multiSearch(params) | POST /multi-search | 在一个请求中进行若干类型搜索(Core 0.0.0+) |
Search.filter(params, collection) | POST /{collection}/filter | 结构化DB过滤器(Core 01.3.2+) |
Search.startReindex(options?) | POST /search/reindex | 从 DB 重建类型索引 |
Search.getReindexStatus() | GET /search/reindex | Poll重新索引进度 |
收藏: ledgers, (中文(简体) ), balances, (中文(简体) ), transactions, (中文(简体) ), identities。 。 。 .
类型搜索
const { Search } = blnk;
const results = await Search.search(
{ q: 'payment', per_page: 10 },
'transactions',
);
在一个请求中搜索多个收藏( E)POST /multi-search; 结果回来
与搜索顺序相同:
const { Search } = blnk;
const multi = await Search.multiSearch({
searches: [
{ collection: 'transactions', q: 'ref_001', query_by: 'reference' },
{ collection: 'balances', q: '*', filter_by: 'currency:USD' },
{ collection: 'ledgers', q: 'savings', query_by: 'name' },
],
});
const transactionHits = multi.data?.results[0]?.hits;
要求 Blnk 核心 v0.1.0+ (router.POST("/multi-search", a.MultiSearch) 内
api/api.go) (中文(简体) ). 这个
SDK与Core 0.15.4对齐.
DB 过滤器
const { Search } = blnk;
const filtered = await Search.filter(
{
filters: [{ field: 'status', operator: 'eq', value: 'APPLIED' }],
logical_operator: 'and',
sort_by: 'created_at',
sort_order: 'desc',
include_count: true,
limit: 20,
offset: 0,
},
'transactions',
);
// filtered.data?.data — matching transaction records
// filtered.data?.total_count — present when include_count is true
见 通过 DB 引用搜索 用于支持的运算符和字段.
类型调整索引
const { Search } = blnk;
const reindex = await Search.startReindex({ batch_size: 1000 });
// reindex.data?.message — "Reindex operation started"
// reindex.data?.progress.status — "pending" | "in_progress" | "completed" | "failed"
见 开始重新索引引用。 。 。 .
启动再索引后打入进度 :
const status = await Search.getReindexStatus();
// status.data?.status — "in_progress" | "completed" | "failed"
// status.data?.phase — e.g. "indexing_transactions" or "done"
见 获取再索引状态参考。 。 。 .
和解
| 方法 | 终点 | 使用大小写 |
|---|---|---|
Reconciliation.upload(file, source) | POST /reconciliation/upload | 上传外部数据文件 |
Reconciliation.createMatchingRule(data) | POST /reconciliation/matching-rules | 定义匹配标准 |
Reconciliation.updateMatchingRule(id, data) | PUT /reconciliation/matching-rules/{rule_id} | 更新现有的匹配规则 |
Reconciliation.deleteMatchingRule(id) | DELETE /reconciliation/matching-rules/{rule_id} | 删除匹配规则 |
Reconciliation.run(data) | POST /reconciliation/start | 从上传开始批量调节 |
Reconciliation.runInstant(data) | POST /reconciliation/start-instant | 内部外部交易的调节 |
Reconciliation.get(id) | GET /reconciliation/{reconciliation_id} | 查看对账状态和计数 |
更新匹配规则
const { Reconciliation } = blnk;
const updated = await Reconciliation.updateMatchingRule('rule_abc123', {
name: 'Updated matcher',
description: 'Amount with 2% drift matcher',
criteria: [
{ field: 'amount', operator: 'equals', allowable_drift: 0.02 },
{ field: 'currency', operator: 'equals' },
],
});
// updated.data?.rule_id, updated.data?.updated_at
见 更新匹配规则参考。 。 。 .
删除匹配规则
const { Reconciliation } = blnk;
const deleted = await Reconciliation.deleteMatchingRule('rule_abc123');
// deleted.data?.message — "Matching rule deleted successfully"
见 删除匹配的规则引用。 。 。 .
获得调节状态
const { Reconciliation } = blnk;
const status = await Reconciliation.get('recon_3803ea0d-28b4-4c73-a36b-5a9eb7a3edfd');
// status.data?.status — e.g. started, in_progress, completed, failed
// status.data?.matched_transactions, unmatched_transactions
见 查看调节详情。 。 。 .
开始批量调节
Reconciliation.run 从上传开始调和( e)POST /reconciliation/start0.15.0 核心只返回和解身份证——民意调查 Reconciliation.get(id) 或者听着 reconciliation.completed 编号 : reconciliation.failed 网络呼求结果.
const { Reconciliation } = blnk;
const started = await Reconciliation.run({
upload_id: upload.data!.upload_id,
strategy: 'one_to_one',
dry_run: true,
grouping_criteria: 'amount',
matching_rule_ids: [rule.data!.rule_id],
});
// started.data?.reconciliation_id — use with Reconciliation.get() or webhooks
见 启动对账引用。 。 。 .
即时对账
const { Reconciliation } = blnk;
const instant = await Reconciliation.runInstant({
external_transactions: [
{
id: 'txn_1',
amount: 5.49,
reference: 'INV-2023-002',
currency: 'GBP',
description: 'Card payment',
date: '2024-11-15T14:25:30Z',
source: 'bank-api',
},
],
strategy: 'one_to_one',
dry_run: true,
matching_rule_ids: ['rule_abc123'],
});
// instant.data?.reconciliation_id — reconciliation run ID
见 即时对账参考。 。 。 .
元数据
| 方法 | 终点 | 使用大小写 |
|---|---|---|
Metadata.update(id, data) | POST /{id}/metadata | 在分类账、交易、余额或身份上添加或更新元数据 |
更新元数据
const { Metadata } = blnk;
const updated = await Metadata.update('ldg_073f7ffe-9dfd-42ce-aa50-d1dca1788adc', {
meta_data: {
project_owner: 'Acme LLC',
update_status: 'Approved',
},
});
// updated.data?.meta_data — merged metadata from Core
见 更新元数据参考。 。 。 .
钩子
| 方法 | 终点 | 使用大小写 |
|---|---|---|
Hooks.create(data) | POST /hooks | 注册交易前或交易后网页 |
Hooks.list(options?) | GET /hooks | 列表钩子,可选用 type 查询 |
Hooks.get(id) | GET /hooks/{id} | 查看钩状细节 |
Hooks.update(id, data) | PUT /hooks/{id} | 更新已有的 Webhook |
Hooks.delete(id) | DELETE /hooks/{id} | 删除网点 |
虎克管理要求 主密钥 (单位:千美元)
server.secret_key(单位:千美元)X-Blnk-Key返回常规 API 密钥403。 。 。 .
注册钩
const { Hooks } = blnk;
const hook = await Hooks.create({
name: 'Pre-transaction validation',
url: 'https://api.example.com/validate',
type: 'PRE_TRANSACTION',
active: true,
timeout: 30,
retry_count: 3,
});
// hook.data?.id — registered hook ID
见 注册钩子引用。 。 。 .
列表钩子
const allHooks = await Hooks.list();
const preTxnHooks = await Hooks.list({ type: 'PRE_TRANSACTION' });
见 按类型参考列出钩子。 。 。 .
查看钩子
const hookDetails = await Hooks.get(hook.data!.id);
// hookDetails.data?.name, hookDetails.data?.active, etc.
见 查看钩子引用。 。 。 .
更新钩子
const updated = await Hooks.update(hook.data!.id, {
name: 'Pre-transaction validation (updated)',
url: 'https://api.example.com/validate-v2',
type: 'PRE_TRANSACTION',
active: false,
timeout: 45,
retry_count: 5,
});
见 更新钩子引用。 。 。 .
删除钩子
const deleted = await Hooks.delete(hook.data!.id);
// deleted.data?.message — "hook deleted successfully"
见 删除钩子引用。 。 。 .
API 密钥
| 方法 | 终点 | 使用大小写 |
|---|---|---|
ApiKeys.create(data) | POST /api-keys | 创建范围化 API 密钥 |
ApiKeys.list(options?) | GET /api-keys | 列出所有者的 API 密钥 |
ApiKeys.delete(id, options?) | DELETE /api-keys/{id} | 撤销 API 密钥 |
API 密钥管理要求 主密钥 或扩大范围许可(
api-keys:write创建,api-keys:read到列表中,api-keys:delete)). 生下来的key值只在创建时返回一次.
创建 API 密钥
const { ApiKeys } = blnk;
const apiKey = await ApiKeys.create({
name: 'Service Account',
owner: 'merchant_a',
scopes: ['ledgers:read', 'balances:write'],
expires_at: '2026-03-11T00:00:00Z',
});
// apiKey.data?.key — store securely; shown only once
见 创建 API 密钥引用。 。 。 .
列出 API 密钥
const keys = await ApiKeys.list({ owner: 'merchant_a' });
// keys.data?.[0]?.api_key_id, keys.data?.[0]?.scopes, etc.
见 列出 API 密钥引用。 。 。 .
撤销 API 密钥
await ApiKeys.delete('api_key_abc123', { owner: 'merchant_a' });
// 204 No Content on success; response.data is null
见 撤销 API 关键引用。 。 。 .
额外资源
关于更多实例和先进的使用案例,请参见: 示例代码。 。 。 .
问题报告
如果你遇到任何问题,请 在 GitHub 上报告。 。 。 .