@gpmpay/sdk
Version:
Official Node.js SDK for GPM Pay — VietQR codes, transaction webhooks, and payment reconciliation.
1 lines • 113 kB
Source Map (JSON)
{"version":3,"sources":["../src/resources/api-tokens.ts","../src/resources/bank-accounts.ts","../src/resources/banks.ts","../src/core/errors.ts","../src/types/common.ts","../src/core/query.ts","../src/resources/simulator.ts","../src/resources/transactions.ts","../src/resources/webhook-histories.ts","../src/resources/webhook-settings.ts","../src/core/token.ts","../src/core/config.ts","../src/version.ts","../src/core/envelope.ts","../src/core/retry.ts","../src/core/signal.ts","../src/core/http.ts","../src/core/client.ts","../src/webhooks/verify.ts","../src/vietqr/crc16.ts","../src/vietqr/vietqr.ts","../src/types/enums.ts"],"names":["serialized","randomBytes","headerValue","randomUUID","createHmac","timingSafeEqual"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { HttpClient } from '../core/http.js';\nimport type { RequestOptions } from '../types/common.js';\n\n/**\n * The one API-token route an API token may call.\n *\n * @remarks\n * This class looks incomplete on purpose. `ApiTokenGuard` is fail-closed: a\n * route that declares no `@ApiScopes()` rejects API tokens outright with\n * `403 \"This endpoint is not available to API tokens\"`. Listing, creating,\n * regenerating and status changes are all dashboard-session routes, so\n * modelling them here would only ship methods that can never succeed.\n *\n * `DELETE /api-tokens/:id` is the documented exception — it carries\n * `@AllowAnyApiToken()` so an integration can revoke its own token when the\n * merchant disconnects. Ownership is still enforced server-side.\n *\n * Manage tokens at https://app.gpmpay.com/api-tokens.\n */\nexport class ApiTokensResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Permanently delete a token. Any valid token may call this; the backend\n * still requires the token being deleted to belong to the caller.\n */\n remove(id: string, options: RequestOptions = {}): Promise<unknown> {\n return this.http.request<unknown>(\n 'DELETE',\n `/api-tokens/${encodeURIComponent(id)}`,\n options,\n );\n }\n}\n","import type { HttpClient } from '../core/http.js';\nimport type { Page, RequestOptions } from '../types/common.js';\nimport type { BankAccount, ListBankAccountsParams } from '../types/bank.js';\n\n/**\n * Read-only access to your bank accounts. Scope: `bank-accounts:read`.\n *\n * @remarks\n * Write operations (`create`, `update`, `remove`, `rotate-ingest-secret`,\n * `subscribe`) are intentionally **not** exposed. There is no\n * `bank-accounts:write` scope, `rotate-ingest-secret` returns a plaintext\n * secret, and `subscribe` spends money — none of which belongs behind a\n * read-scoped token. Use the dashboard for those.\n */\nexport class BankAccountsResource {\n constructor(private readonly http: HttpClient) {}\n\n list(\n params: ListBankAccountsParams = {},\n options: RequestOptions = {},\n ): Promise<Page<BankAccount>> {\n return this.http.requestList<BankAccount>('GET', '/bank-accounts', {\n ...options,\n query: params as Record<string, unknown>,\n });\n }\n\n retrieve(id: string, options: RequestOptions = {}): Promise<BankAccount> {\n return this.http.request<BankAccount>(\n 'GET',\n `/bank-accounts/${encodeURIComponent(id)}`,\n options,\n );\n }\n}\n","import type { HttpClient } from '../core/http.js';\nimport type { RequestOptions } from '../types/common.js';\nimport type { Bank } from '../types/bank.js';\n\n/**\n * The catalogue of banks GPM Pay supports.\n *\n * @remarks\n * Scope: `bank-accounts:read`.\n *\n * You only need this when you want a bank *you have no account at* — to render\n * a bank picker, or to build a VietQR for an external account. For your own\n * accounts the NAPAS `bin` already rides along on the `bank` relation of\n * `bankAccounts.list()` / `bankAccounts.retrieve()`, so no extra call is needed.\n */\nexport class BanksResource {\n constructor(private readonly http: HttpClient) {}\n\n /** List active banks. The endpoint returns a flat array, not a page. */\n async list(options: RequestOptions = {}): Promise<Bank[]> {\n const page = await this.http.requestList<Bank>('GET', '/banks', options);\n return page.data;\n }\n}\n","import type { ApiTokenScope } from '../types/enums.js';\n\n/**\n * Reason an API token was rejected. Derived from the exact messages the backend\n * emits in `api-tokens.service.ts` / `guards/api-token.guard.ts`.\n */\nexport type AuthFailureReason =\n | 'missing_bearer'\n | 'invalid_format'\n | 'invalid_token'\n | 'token_inactive'\n | 'token_expired'\n | 'user_inactive'\n | 'unknown';\n\n/** Why a 403 came back. See {@link GpmPayPermissionError}. */\nexport type PermissionFailureReason = 'scope' | 'endpoint' | 'ownership';\n\nexport type ConfigErrorCode =\n | 'missing_api_token'\n | 'invalid_api_token'\n | 'invalid_api_token_format'\n | 'invalid_base_url'\n | 'invalid_argument';\n\nexport type WebhookSignatureFailureReason =\n | 'missing_secret'\n | 'malformed_header'\n | 'timestamp_skew'\n | 'mismatch';\n\nconst BRAND = Symbol.for('gpmpay.sdk.error');\n\n/**\n * Base class for everything this SDK throws.\n *\n * Generic over `code` so subclasses can narrow it (and give consumers\n * autocomplete on `error.code`) without redeclaring the field.\n */\nexport class GpmPayError<TCode extends string = string> extends Error {\n readonly code: TCode;\n /** @internal Cross-realm brand — `instanceof` breaks across CJS/ESM copies. */\n readonly [BRAND] = true as const;\n\n constructor(message: string, code: TCode) {\n super(message);\n this.name = new.target.name;\n this.code = code;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n /**\n * Prefer this over `instanceof` when a dual CJS/ESM install could put two\n * copies of the class in one process.\n */\n static isGpmPayError(value: unknown): value is GpmPayError {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as Record<symbol, unknown>)[BRAND] === true\n );\n }\n}\n\n/** Bad SDK usage — thrown before any network call happens. */\nexport class GpmPayConfigError extends GpmPayError<ConfigErrorCode> {\n constructor(message: string, code: ConfigErrorCode = 'invalid_argument') {\n super(message, code);\n }\n}\n\n/** DNS/TCP/TLS failure. `cause` holds the original error. */\nexport class GpmPayConnectionError extends GpmPayError {\n /** Overrides the standard `Error.cause` so it is always populated here. */\n override readonly cause: unknown;\n /** Node's `err.cause.code`, e.g. `ECONNREFUSED`, `ENOTFOUND`. */\n readonly syscallCode: string | undefined;\n\n constructor(message: string, cause: unknown, syscallCode?: string) {\n super(message, 'connection_error');\n this.cause = cause;\n this.syscallCode = syscallCode;\n }\n}\n\nexport class GpmPayTimeoutError extends GpmPayError {\n readonly timeoutMs: number;\n\n constructor(message: string, timeoutMs: number) {\n super(message, 'timeout');\n this.timeoutMs = timeoutMs;\n }\n}\n\nexport class GpmPayWebhookSignatureError extends GpmPayError {\n readonly reason: WebhookSignatureFailureReason;\n\n constructor(message: string, reason: WebhookSignatureFailureReason) {\n super(message, 'webhook_signature');\n this.reason = reason;\n }\n}\n\nexport interface ApiErrorContext {\n status: number;\n requestId: string;\n rawBody: unknown;\n rawMessage: string | string[];\n}\n\n/** Any non-2xx HTTP response. */\nexport class GpmPayAPIError extends GpmPayError {\n readonly status: number;\n /** Correlation id sent as `X-GPMPay-Request-Id`. Quote it to support. */\n readonly requestId: string;\n readonly rawBody: unknown;\n readonly rawMessage: string | string[];\n\n constructor(message: string, ctx: ApiErrorContext, code = 'api_error') {\n super(message, code);\n this.status = ctx.status;\n this.requestId = ctx.requestId;\n this.rawBody = ctx.rawBody;\n this.rawMessage = ctx.rawMessage;\n }\n}\n\n/** 400 — request body failed validation. */\nexport class GpmPayBadRequestError extends GpmPayAPIError {\n /** One entry per failed constraint, as produced by Nest's ValidationPipe. */\n readonly validationMessages: string[];\n\n constructor(\n message: string,\n ctx: ApiErrorContext & { validationMessages: string[] },\n ) {\n super(message, ctx, 'bad_request');\n this.validationMessages = ctx.validationMessages;\n }\n}\n\n/** 401 — the API token was rejected. */\nexport class GpmPayAuthenticationError extends GpmPayAPIError {\n readonly reason: AuthFailureReason;\n\n constructor(message: string, ctx: ApiErrorContext & { reason: AuthFailureReason }) {\n super(message, ctx, 'authentication_error');\n this.reason = ctx.reason;\n }\n}\n\n/**\n * 403 — one of three things:\n *\n * - `scope` — the token exists but lacks the scope this route requires.\n * - `endpoint` — the route accepts no API token at all (dashboard-only).\n * - `ownership` — the resource exists but belongs to another account.\n */\nexport class GpmPayPermissionError extends GpmPayAPIError {\n readonly missingScope: ApiTokenScope | undefined;\n readonly reason: PermissionFailureReason;\n\n constructor(\n message: string,\n ctx: ApiErrorContext & {\n missingScope?: ApiTokenScope;\n reason: PermissionFailureReason;\n },\n ) {\n super(message, ctx, 'permission_error');\n this.missingScope = ctx.missingScope;\n this.reason = ctx.reason;\n }\n}\n\nexport class GpmPayNotFoundError extends GpmPayAPIError {\n /** Resource name parsed out of e.g. `\"Order not found\"`. */\n readonly resource: string | undefined;\n\n constructor(message: string, ctx: ApiErrorContext & { resource?: string }) {\n super(message, ctx, 'not_found');\n this.resource = ctx.resource;\n }\n}\n\nexport class GpmPayRateLimitError extends GpmPayAPIError {\n readonly retryAfterSeconds: number | undefined;\n\n constructor(\n message: string,\n ctx: ApiErrorContext & { retryAfterSeconds?: number },\n ) {\n super(message, ctx, 'rate_limit');\n this.retryAfterSeconds = ctx.retryAfterSeconds;\n }\n}\n\nexport class GpmPayServerError extends GpmPayAPIError {\n constructor(message: string, ctx: ApiErrorContext) {\n super(message, ctx, 'server_error');\n }\n}\n\n/** Ordered most-specific first — `Invalid token` must lose to `Invalid token format`. */\nconst AUTH_REASONS: [RegExp, AuthFailureReason][] = [\n [/missing bearer token/i, 'missing_bearer'],\n [/invalid token format/i, 'invalid_format'],\n [/token is not active/i, 'token_inactive'],\n [/token[_ ]expired/i, 'token_expired'],\n [/user inactive/i, 'user_inactive'],\n [/invalid token/i, 'invalid_token'],\n];\n\nfunction extractMessage(body: unknown): string | string[] {\n if (typeof body === 'string' && body.trim() !== '') return body;\n if (body !== null && typeof body === 'object') {\n const b = body as { message?: unknown; error?: unknown };\n if (Array.isArray(b.message) || typeof b.message === 'string') {\n return b.message as string | string[];\n }\n if (typeof b.error === 'string') return b.error;\n }\n return '';\n}\n\n/**\n * Map an HTTP error response onto the typed error hierarchy.\n *\n * @remarks\n * The backend registers no global exception filter, so error bodies use Nest's\n * default shape (`{ statusCode, message, error }`) and are NOT wrapped in the\n * `{ statusCode, message, data }` success envelope.\n */\nexport function errorFromResponse(\n status: number,\n body: unknown,\n requestId: string,\n extra: { retryAfterSeconds?: number } = {},\n): GpmPayAPIError {\n const raw = extractMessage(body);\n const msg =\n (Array.isArray(raw) ? raw.join('; ') : raw) || `HTTP ${String(status)}`;\n const ctx: ApiErrorContext = {\n status,\n requestId,\n rawBody: body,\n rawMessage: raw === '' ? msg : raw,\n };\n\n switch (status) {\n case 400:\n return new GpmPayBadRequestError(msg, {\n ...ctx,\n validationMessages: Array.isArray(raw) ? raw : [msg],\n });\n\n case 401: {\n const reason =\n AUTH_REASONS.find(([re]) => re.test(msg))?.[1] ?? 'unknown';\n return new GpmPayAuthenticationError(\n `${msg} — check your API token is correct, ACTIVE and not expired.`,\n { ...ctx, reason },\n );\n }\n\n case 403: {\n const scope = /missing scope:\\s*(\\S+)/i.exec(msg)?.[1];\n if (scope) {\n return new GpmPayPermissionError(\n `API token is missing the \"${scope}\" scope. Regenerate the token with that scope enabled.`,\n { ...ctx, missingScope: scope as ApiTokenScope, reason: 'scope' },\n );\n }\n // `ApiTokenGuard` is fail-closed: a route that declares no `@ApiScopes()`\n // rejects API tokens outright, whoever owns the resource. Reporting that\n // as an ownership problem sends people hunting for the wrong bug.\n if (/not available to api tokens/i.test(msg)) {\n return new GpmPayPermissionError(\n `${msg} — this endpoint is dashboard-only and no API token scope grants it.`,\n { ...ctx, reason: 'endpoint' },\n );\n }\n return new GpmPayPermissionError(\n `${msg} — the resource exists but belongs to another account.`,\n { ...ctx, reason: 'ownership' },\n );\n }\n\n case 404: {\n const resource = /^(.*?)\\s+not found/i.exec(msg)?.[1];\n return new GpmPayNotFoundError(\n msg,\n resource === undefined ? ctx : { ...ctx, resource },\n );\n }\n\n // No 409 case: every route this SDK can reach is either a read or a write\n // with no uniqueness constraint, so a conflict has no source. A 409 from\n // `client.request()` falls through to the generic GpmPayAPIError below.\n\n case 429:\n return new GpmPayRateLimitError(\n msg,\n extra.retryAfterSeconds === undefined\n ? ctx\n : { ...ctx, retryAfterSeconds: extra.retryAfterSeconds },\n );\n\n default:\n return status >= 500\n ? new GpmPayServerError(msg, ctx)\n : new GpmPayAPIError(msg, ctx);\n }\n}\n","/** Pagination envelope returned inside `data` by list endpoints. */\nexport interface PageMeta {\n page: number;\n limit: number;\n totalItems: number;\n totalPages: number;\n}\n\nexport interface Page<T> {\n data: T[];\n meta: PageMeta;\n}\n\nexport type SortOrder = 'asc' | 'desc';\n\n/**\n * Query parameters shared by every paginated list endpoint.\n *\n * @remarks\n * `limit` is capped at 50 server-side. The SDK clamps it client-side and warns\n * once so the truncation is never silent.\n *\n * `startDate`/`endDate` filter on `transactionTime` for transactions and on\n * `createdAt` for every other resource.\n */\nexport interface ListParams {\n page?: number;\n limit?: number;\n sortBy?: string;\n sortOrder?: SortOrder;\n search?: string;\n startDate?: string | Date;\n endDate?: string | Date;\n /** Serialized to a JSON string — the backend runs `JSON.parse` on it. */\n filters?: Record<string, unknown>;\n}\n\n/** Maximum page size the backend will honour (`BaseService.DEFAULT_LIMIT`). */\nexport const MAX_PAGE_SIZE = 50;\n\nexport interface RequestOptions {\n signal?: AbortSignal;\n timeoutMs?: number;\n headers?: Record<string, string>;\n}\n","import { MAX_PAGE_SIZE } from '../types/common.js';\n\nexport type QueryInput = Record<string, unknown> | undefined;\n\nlet warnedAboutLimit = false;\n\n/** @internal Test seam. */\nexport function __resetQueryWarnings(): void {\n warnedAboutLimit = false;\n}\n\nfunction serializeValue(value: unknown): string | null {\n if (value === undefined || value === null || value === '') return null;\n if (value instanceof Date) return value.toISOString();\n if (typeof value === 'boolean') return value ? 'true' : 'false';\n if (typeof value === 'number') {\n return Number.isFinite(value) ? String(value) : null;\n }\n if (typeof value === 'string') return value;\n return JSON.stringify(value);\n}\n\n/**\n * Build a query string from a params object.\n *\n * - drops `undefined` / `null` / `''`\n * - `Date` values become ISO strings\n * - arrays repeat the key\n * - `filters` is JSON-stringified — the backend runs `JSON.parse` on it\n * - `limit` is clamped to 50, because the backend caps it silently and a\n * silently truncated page is the single most confusing SDK behaviour\n */\nexport function buildQuery(params: QueryInput): string {\n if (!params) return '';\n\n const search = new URLSearchParams();\n\n for (const [key, rawValue] of Object.entries(params)) {\n if (rawValue === undefined || rawValue === null) continue;\n\n if (key === 'limit') {\n const limit = Number(rawValue);\n if (!Number.isFinite(limit)) continue;\n if (limit > MAX_PAGE_SIZE) {\n if (!warnedAboutLimit) {\n warnedAboutLimit = true;\n console.warn(\n `[@gpmpay/sdk] limit=${String(limit)} exceeds the API maximum of ${String(MAX_PAGE_SIZE)}; ` +\n `requesting ${String(MAX_PAGE_SIZE)} instead. Paginate with \\`page\\`, or use listAll().`,\n );\n }\n search.append('limit', String(MAX_PAGE_SIZE));\n } else {\n search.append('limit', String(limit));\n }\n continue;\n }\n\n if (key === 'filters' && typeof rawValue === 'object') {\n search.append('filters', JSON.stringify(rawValue));\n continue;\n }\n\n if (Array.isArray(rawValue)) {\n for (const item of rawValue) {\n const serialized = serializeValue(item);\n if (serialized !== null) search.append(key, serialized);\n }\n continue;\n }\n\n const serialized = serializeValue(rawValue);\n if (serialized !== null) search.append(key, serialized);\n }\n\n const qs = search.toString();\n return qs === '' ? '' : `?${qs}`;\n}\n\n/** Normalize `string | Date` inputs for request bodies. */\nexport function toIsoString(value: string | Date | null | undefined): string | undefined {\n if (value === undefined || value === null) return undefined;\n return value instanceof Date ? value.toISOString() : value;\n}\n","import { GpmPayConfigError } from '../core/errors.js';\nimport type { HttpClient } from '../core/http.js';\nimport { toIsoString } from '../core/query.js';\nimport type { RequestOptions } from '../types/common.js';\nimport type {\n SimulatedTransactionResult,\n SimulateTransactionParams,\n} from '../types/transaction.js';\n\nexport interface SimulatorOptions extends RequestOptions {\n /**\n * Simulated transactions are a development tool. The SDK refuses to call\n * this against a production base URL unless you opt in explicitly.\n */\n allowOnProduction?: boolean;\n}\n\nfunction isNonProductionBaseUrl(baseUrl: string): boolean {\n return /localhost|127\\.0\\.0\\.1|sandbox|\\.local(?::|\\/|$)/i.test(baseUrl);\n}\n\n/**\n * Generate fake inbound transfers for local development and integration tests.\n *\n * Scope: `transactions:read`. That reads oddly for a route that *creates* a\n * transaction — it is a deliberate backend trade-off to avoid minting a new\n * scope. Simulated transactions always carry `source: 'SIMULATED'` and only\n * fan out to endpoints with `fireOnSimulated` enabled.\n */\nexport class SimulatorResource {\n constructor(private readonly http: HttpClient) {}\n\n private assertSafeEnvironment(options: SimulatorOptions): void {\n if (options.allowOnProduction === true) return;\n if (isNonProductionBaseUrl(this.http.baseUrl)) return;\n\n throw new GpmPayConfigError(\n `simulator: refusing to create a simulated transaction against ${this.http.baseUrl}. ` +\n 'Point the client at localhost or the sandbox (`new GpmPay({ sandbox: true })`), ' +\n 'or pass { allowOnProduction: true } if you really mean it.',\n );\n }\n\n /**\n * Create a simulated bank transaction.\n *\n * Returns the envelope the route actually sends — `{ transaction,\n * historyIds }`, not a bare `Transaction`. Read `result.transaction` for the\n * ledger row and `result.historyIds.length` to confirm a webhook was queued.\n *\n * `async` so guard failures reject rather than throwing synchronously.\n */\n async createTransaction(\n params: SimulateTransactionParams,\n options: SimulatorOptions = {},\n ): Promise<SimulatedTransactionResult> {\n this.assertSafeEnvironment(options);\n\n if (!Number.isInteger(params.amount) || params.amount < 1) {\n throw new GpmPayConfigError(\n `simulator: amount must be an integer number of VND >= 1, received ${String(params.amount)}.`,\n );\n }\n\n const body: Record<string, unknown> = {\n bankAccountId: params.bankAccountId,\n amount: params.amount,\n transferContent: params.transferContent,\n };\n if (params.type !== undefined) body.type = params.type;\n if (params.referenceCode !== undefined) {\n body.referenceCode = params.referenceCode;\n }\n if (params.counterAccount !== undefined) {\n body.counterAccount = params.counterAccount;\n }\n if (params.counterName !== undefined) body.counterName = params.counterName;\n const transactionTime = toIsoString(params.transactionTime);\n if (transactionTime !== undefined) body.transactionTime = transactionTime;\n\n const { allowOnProduction: _ignored, ...requestOptions } = options;\n return await this.http.request<SimulatedTransactionResult>(\n 'POST',\n '/simulator/transactions',\n { ...requestOptions, body },\n );\n }\n}\n","import type { HttpClient } from '../core/http.js';\nimport type { Page, RequestOptions } from '../types/common.js';\nimport type {\n ListTransactionsParams,\n Transaction,\n TransactionDetail,\n} from '../types/transaction.js';\n\nexport class TransactionsResource {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * List transactions across your bank accounts. Scope: `transactions:read`.\n *\n * @remarks\n * `limit` is capped at 50 server-side. `search` matches `referenceCode` and\n * `transferContent`; `startDate`/`endDate` filter on `transactionTime`.\n */\n list(\n params: ListTransactionsParams = {},\n options: RequestOptions = {},\n ): Promise<Page<Transaction>> {\n return this.http.requestList<Transaction>('GET', '/transactions', {\n ...options,\n query: params as Record<string, unknown>,\n });\n }\n\n /**\n * Iterate every matching transaction, fetching pages as needed.\n *\n * @example\n * for await (const txn of client.transactions.listAll({ type: 'IN' })) {\n * console.log(txn.referenceCode);\n * }\n */\n async *listAll(\n params: Omit<ListTransactionsParams, 'page'> = {},\n options: RequestOptions = {},\n ): AsyncGenerator<Transaction, void, undefined> {\n let page = 1;\n for (;;) {\n const result = await this.list({ ...params, page }, options);\n for (const txn of result.data) yield txn;\n\n if (result.data.length === 0) return;\n if (page >= result.meta.totalPages) return;\n page++;\n }\n }\n\n /** Fetch one transaction. Scope: `transactions:read`. */\n retrieve(\n id: string,\n options: RequestOptions = {},\n ): Promise<TransactionDetail> {\n return this.http.request<TransactionDetail>(\n 'GET',\n `/transactions/${encodeURIComponent(id)}`,\n options,\n );\n }\n}\n","import type { HttpClient } from '../core/http.js';\nimport type { Page, RequestOptions } from '../types/common.js';\nimport type {\n ListWebhookHistoriesParams,\n WebhookHistory,\n} from '../types/webhook.js';\n\n/** Inspect and replay webhook deliveries. Scope: `webhooks:manage`. */\nexport class WebhookHistoriesResource {\n constructor(private readonly http: HttpClient) {}\n\n list(\n params: ListWebhookHistoriesParams = {},\n options: RequestOptions = {},\n ): Promise<Page<WebhookHistory>> {\n return this.http.requestList<WebhookHistory>('GET', '/webhook-histories', {\n ...options,\n query: params as Record<string, unknown>,\n });\n }\n\n retrieve(id: string, options: RequestOptions = {}): Promise<WebhookHistory> {\n return this.http.request<WebhookHistory>(\n 'GET',\n `/webhook-histories/${encodeURIComponent(id)}`,\n options,\n );\n }\n\n /** Re-enqueue a failed delivery. */\n retry(id: string, options: RequestOptions = {}): Promise<WebhookHistory> {\n return this.http.request<WebhookHistory>(\n 'POST',\n `/webhook-histories/${encodeURIComponent(id)}/retry`,\n options,\n );\n }\n}\n","import { randomBytes } from 'node:crypto';\n\nimport type { HttpClient } from '../core/http.js';\nimport type { Page, RequestOptions } from '../types/common.js';\nimport type {\n CreateWebhookSettingParams,\n ListWebhookSettingsParams,\n UpdateWebhookSettingParams,\n WebhookSetting,\n} from '../types/webhook.js';\n\nexport interface CreateHmacEndpointParams {\n /** Where GPM Pay should POST transaction events. */\n url: string;\n name?: string;\n scope?: 'ALL' | 'SPECIFIC';\n bankAccountIds?: string[];\n /** Provide your own, or let the SDK generate a 256-bit hex secret. */\n secret?: string;\n}\n\nexport interface CreateHmacEndpointResult {\n setting: WebhookSetting;\n /**\n * The signing secret, in plaintext.\n *\n * @remarks\n * Returned **once**. The API stores it encrypted and never gives it back —\n * persist it now, e.g. as `GPMPAY_WEBHOOK_SECRET`.\n */\n secret: string;\n}\n\n/** Manage webhook endpoints. Scope: `webhooks:manage`. */\nexport class WebhookSettingsResource {\n constructor(private readonly http: HttpClient) {}\n\n list(\n params: ListWebhookSettingsParams = {},\n options: RequestOptions = {},\n ): Promise<Page<WebhookSetting>> {\n return this.http.requestList<WebhookSetting>('GET', '/webhook-settings', {\n ...options,\n query: params as Record<string, unknown>,\n });\n }\n\n retrieve(id: string, options: RequestOptions = {}): Promise<WebhookSetting> {\n return this.http.request<WebhookSetting>(\n 'GET',\n `/webhook-settings/${encodeURIComponent(id)}`,\n options,\n );\n }\n\n create(\n params: CreateWebhookSettingParams,\n options: RequestOptions = {},\n ): Promise<WebhookSetting> {\n return this.http.request<WebhookSetting>('POST', '/webhook-settings', {\n ...options,\n body: params,\n });\n }\n\n update(\n id: string,\n params: UpdateWebhookSettingParams,\n options: RequestOptions = {},\n ): Promise<WebhookSetting> {\n return this.http.request<WebhookSetting>(\n 'PATCH',\n `/webhook-settings/${encodeURIComponent(id)}`,\n { ...options, body: params },\n );\n }\n\n remove(id: string, options: RequestOptions = {}): Promise<unknown> {\n return this.http.request<unknown>(\n 'DELETE',\n `/webhook-settings/${encodeURIComponent(id)}`,\n options,\n );\n }\n\n /**\n * Register an HTTP endpoint with HMAC signing and hand back the secret.\n *\n * Pair the returned secret with `verifyWebhookSignature` from\n * `@gpmpay/sdk/webhooks`.\n */\n async createHmacEndpoint(\n params: CreateHmacEndpointParams,\n options: RequestOptions = {},\n ): Promise<CreateHmacEndpointResult> {\n const secret = params.secret ?? randomBytes(32).toString('hex');\n\n const base = {\n driver: 'HTTP' as const,\n url: params.url,\n authorizationType: 'HMAC' as const,\n authorizationSecret: secret,\n ...(params.name === undefined ? {} : { name: params.name }),\n };\n\n const body: CreateWebhookSettingParams =\n params.scope === 'SPECIFIC'\n ? {\n ...base,\n scope: 'SPECIFIC',\n bankAccountIds: (params.bankAccountIds ?? []) as [\n string,\n ...string[],\n ],\n }\n : { ...base, scope: 'ALL' };\n\n const setting = await this.create(body, options);\n return { setting, secret };\n }\n}\n","import { GpmPayConfigError } from './errors.js';\n\n/** Mirrors `API_TOKEN_PREFIX` in `apps/backend/src/modules/api-tokens/api-tokens.service.ts`. */\nexport const API_TOKEN_PREFIX = 'gpm_';\n\n/**\n * `gpm_` (4) + base64url public part (8) + `_` + base64url secret (24) = 37 chars.\n *\n * The width is fixed, so the separating `_` is unambiguous even though base64url\n * itself may contain `_`.\n */\nexport const API_TOKEN_RE = /^gpm_[A-Za-z0-9_-]{8}_[A-Za-z0-9_-]{24}$/;\n\nexport const API_TOKEN_LENGTH = 37;\n\n/** Length of the public prefix stored as `ApiToken.tokenPrefix` in the database. */\nconst PREFIX_LENGTH = 12;\n\nconst CREATE_TOKEN_URL = 'https://app.gpmpay.com/api-tokens';\n\nconst MSG_MISSING =\n 'apiToken is required — the GPM Pay SDK cannot be used without one.\\n' +\n ` 1. Create a token at ${CREATE_TOKEN_URL}\\n` +\n ' 2. Pass it explicitly: new GpmPay({ apiToken: \"gpm_...\" })\\n' +\n ' or set the GPMPAY_API_TOKEN environment variable and use GpmPay.fromEnv().';\n\n/**\n * Validate an API token locally so a misconfiguration fails immediately with an\n * actionable message instead of a 401 on the first request.\n *\n * The presence check is unconditional. Only the *format* check can be skipped,\n * via `strictTokenFormat: false`, so a future server-side token format cannot\n * brick already-deployed SDK versions.\n *\n * @throws {GpmPayConfigError}\n */\nexport function assertApiToken(raw: unknown, strict = true): string {\n if (raw === undefined || raw === null) {\n throw new GpmPayConfigError(MSG_MISSING, 'missing_api_token');\n }\n if (typeof raw !== 'string') {\n throw new GpmPayConfigError(\n `apiToken must be a string, received ${typeof raw}.\\n\\n${MSG_MISSING}`,\n 'invalid_api_token',\n );\n }\n\n const token = raw.trim();\n if (token === '') {\n throw new GpmPayConfigError(MSG_MISSING, 'missing_api_token');\n }\n if (token.startsWith('Bearer ')) {\n throw new GpmPayConfigError(\n 'apiToken must not include the \"Bearer \" prefix — pass the raw gpm_… token; ' +\n 'the SDK adds the Authorization header itself.',\n 'invalid_api_token',\n );\n }\n if (strict && !API_TOKEN_RE.test(token)) {\n throw new GpmPayConfigError(\n `apiToken has an unexpected format (got \"${maskToken(token)}\", ${String(token.length)} chars). ` +\n `Expected gpm_XXXXXXXX_… (${String(API_TOKEN_LENGTH)} chars).\\n` +\n `Create a fresh token at ${CREATE_TOKEN_URL}. ` +\n 'If you are using a newer token format, pass { strictTokenFormat: false }.',\n 'invalid_api_token_format',\n );\n }\n\n return token;\n}\n\n/**\n * The token's public prefix — the first 12 chars, matching `ApiToken.tokenPrefix`\n * in the database. Safe to log and to display in support tickets.\n */\nexport function tokenPrefix(token: string): string {\n return token.slice(0, PREFIX_LENGTH);\n}\n\n/** Redacted form for logs and error messages. Never reveals the secret part. */\nexport function maskToken(token: string): string {\n if (token.length <= PREFIX_LENGTH) return 'gpm_***';\n return `${token.slice(0, PREFIX_LENGTH)}${'•'.repeat(8)}`;\n}\n","import { GpmPayConfigError } from './errors.js';\nimport { assertApiToken } from './token.js';\n\nexport const DEFAULT_BASE_URL = 'https://api.gpmpay.com';\nexport const SANDBOX_BASE_URL = 'https://sandbox-api.gpmpay.com';\nexport const DEFAULT_TIMEOUT_MS = 30_000;\nexport const DEFAULT_MAX_RETRIES = 2;\nexport const DEFAULT_RETRY_BASE_DELAY_MS = 500;\n\nexport interface RequestLogEvent {\n method: string;\n url: string;\n requestId: string;\n attempt: number;\n}\n\nexport interface ResponseLogEvent {\n requestId: string;\n status: number;\n durationMs: number;\n attempt: number;\n}\n\nexport interface GpmPayOptions {\n /**\n * **Required.** Your GPM Pay API token (`gpm_…`).\n *\n * Create one at https://app.gpmpay.com/api-tokens. This is a\n * server-side secret — never ship it to a browser or mobile client.\n */\n apiToken: string;\n\n /**\n * API base URL. Accepts a bare host, `host/api`, or `host/api/v1` — the SDK\n * normalizes all of them. Defaults to `https://api.gpmpay.com`.\n */\n baseUrl?: string;\n\n /** Shorthand for the sandbox host. Ignored when `baseUrl` is set. */\n sandbox?: boolean;\n\n /** Per-request timeout in ms. Default 30000. */\n timeoutMs?: number;\n\n /** Retries for retryable failures. Default 2. Set 0 to disable. */\n maxRetries?: number;\n\n /** Base backoff in ms; full-jitter exponential capped at 8s. Default 500. */\n retryBaseDelayMs?: number;\n\n /** Inject a fetch implementation (tests, proxy agents, instrumentation). */\n fetch?: typeof globalThis.fetch;\n\n /** Appended to the SDK's own User-Agent. */\n userAgent?: string;\n\n /** Merged into every request. Cannot override `Authorization`. */\n defaultHeaders?: Record<string, string>;\n\n /**\n * Reject tokens that don't match the documented `gpm_…` shape. Default true.\n * The presence check always applies regardless of this flag.\n */\n strictTokenFormat?: boolean;\n\n /** Observability hooks. Never receive the token. */\n onRequest?: (event: RequestLogEvent) => void;\n onResponse?: (event: ResponseLogEvent) => void;\n}\n\nexport interface ResolvedConfig {\n apiToken: string;\n baseUrl: string;\n timeoutMs: number;\n maxRetries: number;\n retryBaseDelayMs: number;\n fetchImpl: typeof globalThis.fetch;\n userAgent: string | undefined;\n defaultHeaders: Record<string, string>;\n onRequest: ((event: RequestLogEvent) => void) | undefined;\n onResponse: ((event: ResponseLogEvent) => void) | undefined;\n}\n\n/**\n * Normalize any reasonable spelling of the API host into a full versioned base.\n *\n * Mirrors the WooCommerce plugin's normalization so merchants can paste\n * whatever they have. `http://` is preserved — localhost must not be forced\n * to https.\n *\n * @example\n * normalizeBaseUrl('api.gpmpay.com') // https://api.gpmpay.com/api/v1\n * normalizeBaseUrl('https://api.gpmpay.com/') // https://api.gpmpay.com/api/v1\n * normalizeBaseUrl('https://api.gpmpay.com/api') // https://api.gpmpay.com/api/v1\n * normalizeBaseUrl('http://localhost:4000') // http://localhost:4000/api/v1\n */\nexport function normalizeBaseUrl(input: string): string {\n if (typeof input !== 'string') {\n throw new GpmPayConfigError('baseUrl must be a string.', 'invalid_base_url');\n }\n\n let base = input.trim().replace(/\\/+$/, '');\n if (base === '') {\n throw new GpmPayConfigError('baseUrl is empty.', 'invalid_base_url');\n }\n if (!/^[a-z][a-z0-9+.-]*:\\/\\//i.test(base)) {\n base = `https://${base}`;\n }\n\n let parsed: URL;\n try {\n parsed = new URL(base);\n } catch {\n throw new GpmPayConfigError(\n `baseUrl is not a valid URL: ${input}`,\n 'invalid_base_url',\n );\n }\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n throw new GpmPayConfigError(\n `baseUrl must use http or https, got \"${parsed.protocol}\".`,\n 'invalid_base_url',\n );\n }\n\n if (/\\/api\\/v\\d+$/.test(base)) return base;\n if (/\\/api$/.test(base)) return `${base}/v1`;\n return `${base}/api/v1`;\n}\n\nfunction resolveFetch(injected?: typeof globalThis.fetch): typeof globalThis.fetch {\n if (injected) return injected;\n if (typeof globalThis.fetch === 'function') {\n return globalThis.fetch.bind(globalThis);\n }\n throw new GpmPayConfigError(\n 'global fetch is unavailable. @gpmpay/sdk requires Node 18.17+, ' +\n 'or pass a fetch implementation via { fetch }.',\n 'invalid_argument',\n );\n}\n\nexport function resolveConfig(options: GpmPayOptions): ResolvedConfig {\n if (options === undefined || options === null) {\n // Reaching assertApiToken with `undefined` produces the actionable message.\n return resolveConfig({ apiToken: undefined as unknown as string });\n }\n\n const apiToken = assertApiToken(\n options.apiToken,\n options.strictTokenFormat ?? true,\n );\n\n const rawBase =\n options.baseUrl ?? (options.sandbox === true ? SANDBOX_BASE_URL : DEFAULT_BASE_URL);\n\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {\n throw new GpmPayConfigError(\n `timeoutMs must be a positive number, got ${String(options.timeoutMs)}.`,\n 'invalid_argument',\n );\n }\n\n const maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES;\n if (!Number.isInteger(maxRetries) || maxRetries < 0) {\n throw new GpmPayConfigError(\n `maxRetries must be a non-negative integer, got ${String(options.maxRetries)}.`,\n 'invalid_argument',\n );\n }\n\n // Authorization is applied after these, so it can never be overridden here.\n const defaultHeaders: Record<string, string> = {};\n for (const [key, value] of Object.entries(options.defaultHeaders ?? {})) {\n if (key.toLowerCase() === 'authorization') continue;\n defaultHeaders[key] = value;\n }\n\n return {\n apiToken,\n baseUrl: normalizeBaseUrl(rawBase),\n timeoutMs,\n maxRetries,\n retryBaseDelayMs: options.retryBaseDelayMs ?? DEFAULT_RETRY_BASE_DELAY_MS,\n fetchImpl: resolveFetch(options.fetch),\n userAgent: options.userAgent,\n defaultHeaders,\n onRequest: options.onRequest,\n onResponse: options.onResponse,\n };\n}\n","/**\n * Package version, surfaced in the User-Agent.\n *\n * Kept as a literal rather than importing package.json so the published bundle\n * has no JSON import; `version.test.ts` asserts the two stay in sync.\n */\nexport const VERSION = '0.4.0';\n","import type { Page, PageMeta } from '../types/common.js';\n\n/**\n * Unwrap the global success envelope applied by the backend's\n * `TransformInterceptor`: `{ statusCode, message, data }`.\n *\n * Falls through unchanged for anything that isn't shaped like the envelope, so\n * a future un-enveloped endpoint keeps working.\n */\nexport function unwrapEnvelope<T>(body: unknown): T {\n if (\n body !== null &&\n typeof body === 'object' &&\n !Array.isArray(body) &&\n 'statusCode' in body &&\n 'data' in body\n ) {\n return (body as { data: T }).data;\n }\n return body as T;\n}\n\nfunction syntheticMeta(count: number): PageMeta {\n return { page: 1, limit: count, totalItems: count, totalPages: count > 0 ? 1 : 0 };\n}\n\n/**\n * Normalize the three list shapes the API returns into a single `Page<T>`.\n *\n * - `{ data: T[], meta }` — the standard paginated response\n * - `T[]` — `GET /orders` (capped at 100) and `GET /banks`\n * - `{ items: T[] }` — legacy shape the PHP client also tolerates\n */\nexport function unwrapList<T>(data: unknown): Page<T> {\n if (Array.isArray(data)) {\n return { data: data as T[], meta: syntheticMeta(data.length) };\n }\n\n if (data !== null && typeof data === 'object') {\n const obj = data as Record<string, unknown>;\n const items = Array.isArray(obj.data)\n ? obj.data\n : Array.isArray(obj.items)\n ? obj.items\n : null;\n\n if (items) {\n const meta = obj.meta as Partial<PageMeta> | undefined;\n const fallback = syntheticMeta(items.length);\n return {\n data: items as T[],\n meta: {\n page: meta?.page ?? fallback.page,\n limit: meta?.limit ?? fallback.limit,\n totalItems: meta?.totalItems ?? fallback.totalItems,\n totalPages: meta?.totalPages ?? fallback.totalPages,\n },\n };\n }\n }\n\n return { data: [], meta: { page: 1, limit: 0, totalItems: 0, totalPages: 0 } };\n}\n\n/**\n * Convert a money field to a number of VND.\n *\n * Amounts are read back as strings (Prisma `Decimal`) but written as integers.\n * The SDK never coerces silently — call this when you need arithmetic.\n */\nexport function toVnd(amount: string | number | null | undefined): number {\n if (amount === null || amount === undefined) return 0;\n const n = typeof amount === 'number' ? amount : Number(amount);\n return Number.isFinite(n) ? n : 0;\n}\n\n/** Format a money field as Vietnamese currency, e.g. `100.000 ₫`. */\nexport function formatVnd(amount: string | number | null | undefined): string {\n return new Intl.NumberFormat('vi-VN', {\n style: 'currency',\n currency: 'VND',\n maximumFractionDigits: 0,\n }).format(toVnd(amount));\n}\n","export type HttpMethod = 'GET' | 'HEAD' | 'POST' | 'PATCH' | 'PUT' | 'DELETE';\n\nconst RETRYABLE_STATUSES = new Set([408, 425, 429, 500, 502, 503, 504]);\n\n/** Methods safe to replay: no side effect if the first attempt did land. */\nconst IDEMPOTENT_METHODS = new Set<HttpMethod>(['GET', 'HEAD', 'DELETE']);\n\nexport const MAX_BACKOFF_MS = 8_000;\n\n/**\n * Decide whether to retry.\n *\n * Non-idempotent methods retry **only** on 429: a throttled request was never\n * processed, so replaying it cannot duplicate an order. Any other failure on a\n * POST could mean \"the order was created but the response was lost\", so we\n * surface it instead of risking a double charge.\n */\nexport function shouldRetry(params: {\n method: HttpMethod;\n status?: number;\n isConnectionError?: boolean;\n attempt: number;\n maxRetries: number;\n}): boolean {\n const { method, status, isConnectionError, attempt, maxRetries } = params;\n if (attempt >= maxRetries) return false;\n\n const idempotent = IDEMPOTENT_METHODS.has(method);\n\n if (isConnectionError === true) return idempotent;\n if (status === undefined) return false;\n if (status === 429) return true;\n if (!RETRYABLE_STATUSES.has(status)) return false;\n\n return idempotent;\n}\n\n/**\n * Parse a `Retry-After` header. Supports both delta-seconds and an HTTP-date.\n * Returns seconds, or undefined when absent/unparseable.\n */\nexport function parseRetryAfter(\n headerValue: string | null | undefined,\n now: number = Date.now(),\n): number | undefined {\n if (headerValue === null || headerValue === undefined) return undefined;\n const trimmed = headerValue.trim();\n if (trimmed === '') return undefined;\n\n if (/^\\d+$/.test(trimmed)) {\n return Number(trimmed);\n }\n\n const asDate = Date.parse(trimmed);\n if (Number.isNaN(asDate)) return undefined;\n return Math.max(0, Math.ceil((asDate - now) / 1000));\n}\n\n/**\n * Full-jitter exponential backoff: `random(0, min(base * 2^attempt, cap))`.\n * A `Retry-After` hint always wins.\n */\nexport function backoffDelayMs(params: {\n attempt: number;\n baseDelayMs: number;\n retryAfterSeconds?: number | undefined;\n random?: () => number;\n}): number {\n const { attempt, baseDelayMs, retryAfterSeconds, random = Math.random } = params;\n\n if (retryAfterSeconds !== undefined) {\n return Math.max(0, retryAfterSeconds * 1000);\n }\n\n const ceiling = Math.min(baseDelayMs * Math.pow(2, attempt), MAX_BACKOFF_MS);\n return Math.floor(random() * ceiling);\n}\n","export type AbortReason = 'timeout' | 'external';\n\nexport interface LinkedSignal {\n signal: AbortSignal;\n /** Which side aborted, or null if neither did. */\n getReason: () => AbortReason | null;\n dispose: () => void;\n}\n\n/**\n * Combine a caller-supplied signal with a timeout into one signal, while\n * remembering *which* one fired so a timeout can be reported as\n * `GpmPayTimeoutError` rather than a bare `AbortError`.\n *\n * Hand-rolled rather than using `AbortSignal.any`, which needs Node >= 20.3.\n */\nexport function linkSignals(\n external: AbortSignal | undefined,\n timeoutMs: number,\n): LinkedSignal {\n const controller = new AbortController();\n let reason: AbortReason | null = null;\n\n const onExternal = () => {\n if (reason === null) reason = 'external';\n controller.abort();\n };\n\n if (external?.aborted === true) {\n onExternal();\n } else if (external) {\n external.addEventListener('abort', onExternal, { once: true });\n }\n\n const timer = setTimeout(() => {\n if (reason === null) reason = 'timeout';\n controller.abort();\n }, timeoutMs);\n // Don't hold the event loop open just for a pending request timeout.\n (timer as unknown as { unref?: () => void }).unref?.();\n\n return {\n signal: controller.signal,\n getReason: () => reason,\n dispose: () => {\n clearTimeout(timer);\n external?.removeEventListener('abort', onExternal);\n },\n };\n}\n\nexport class AbortError extends Error {\n override readonly name = 'AbortError';\n constructor(message = 'The operation was aborted.') {\n super(message);\n }\n}\n\n/** `setTimeout` as a promise that rejects with `AbortError` if the signal fires. */\nexport function abortableSleep(\n ms: number,\n signal?: AbortSignal,\n): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted === true) {\n reject(new AbortError());\n return;\n }\n\n const timer = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort);\n resolve();\n }, ms);\n\n function onAbort() {\n clearTimeout(timer);\n reject(new AbortError());\n }\n\n signal?.addEventListener('abort', onAbort, { once: true });\n });\n}\n","import { randomUUID } from 'node:crypto';\n\nimport type { Page, RequestOptions } from '../types/common.js';\nimport { VERSION } from '../version.js';\nimport type { ResolvedConfig } from './config.js';\nimport { unwrapEnvelope, unwrapList } from './envelope.js';\nimport {\n GpmPayConnectionError,\n GpmPayTimeoutError,\n errorFromResponse,\n} from './errors.js';\nimport { buildQuery, type QueryInput } from './query.js';\nimport {\n backoffDelayMs,\n parseRetryAfter,\n shouldRetry,\n type HttpMethod,\n} from './retry.js';\nimport { AbortError, abortableSleep, linkSignals } from './signal.js';\n\nexport const REQUEST_ID_HEADER = 'X-GPMPay-Request-Id';\n\nexport interface HttpRequestOptions extends RequestOptions {\n query?: QueryInput;\n body?: unknown;\n}\n\nfunction buildUserAgent(suffix: string | undefined): string {\n const base = `@gpmpay/sdk/${VERSION} (node/${process.version}; ${process.platform})`;\n return suffix === undefined || suffix === '' ? base : `${base} ${suffix}`;\n}\n\nfunction syscallCodeOf(error: unknown): string | undefined {\n const cause = (error as { cause?: unknown } | null)?.cause;\n const code = (cause as { code?: unknown } | null)?.code;\n return typeof code === 'string' ? code : undefined;\n}\n\nexport class HttpClient {\n private readonly config: ResolvedConfig;\n private readonly userAgent: string;\n\n constructor(config: ResolvedConfig) {\n this.config = config;\n this.userAgent = buildUserAgent(config.userAgent);\n }\n\n get baseUrl(): string {\n return this.config.baseUrl;\n }\n\n /** Issue a request and return the unwrapped `data` payload. */\n async request<T>(\n method: HttpMethod,\n path: string,\n options: HttpRequestOptions = {},\n ): Promise<T> {\n const raw = await this.send(method, path, options);\n return unwrapEnvelope<T>(raw);\n }\n\n /** Issue a list request and normalize it into a `Page<T>`. */\n async requestList<T>(\n method: HttpMethod,\n path: string,\n options: HttpRequestOptions = {},\n ): Promise<Page<T>> {\n const raw = await this.send(method, path, options);\n return unwrapList<T>(unwrapEnvelope<unknown>(raw));\n }\n\n private async send(\n method: HttpMethod,\n path: string,\n options: HttpRequestOptions,\n ): Promise<unknown> {\n const url = `${this.config.baseUrl}${path}${buildQuery(options.query)}`;\n const requestId = randomUUID();\n const timeoutMs = options.timeoutMs ?? this.config.timeoutMs;\n const hasBody = options.body !== undefined;\n\n const headers: Record<string, string> = {\n ...this.config.defaultHeaders,\n Accept: 'application/json',\n 'User-Agent': this.userAgent,\n [REQUEST_ID_HEADER]: requestId,\n ...options.headers,\n // Applied last: Authorization is not user-overridable.\n Authorization: `Bearer ${this.config.apiToken}`,\n };\n if (hasBody) headers['Content-Type'] = 'application/json';\n\n const init: RequestInit = { method, headers };\n if (hasBody) init.body = JSON.stringify(options.body);\n\n for (let attempt = 0; ; attempt++) {\n const link = linkSignals(options.signal, timeoutMs);\n const startedAt = Date.now();\n this.config.onRequest?.({ method, url, requestId, attempt });\n\n let response: Response;\n try {\n response = await this.config.fetchImpl(url, {\n ...init,\n signal: link.signal,\n });\n } catch (error) {\n link.dispose();\n\n if (link.getReason() === 'timeout') {\n if (\n shouldRetry({\n method,\n isConnectionError: true,\n attempt,\n maxRetries: this.config.maxRetries,\n })\n ) {\n await this.waitBeforeRetry(attempt, undefined, options.signal);\n continue;\n }\n throw new GpmPayTimeoutError(\n `Request timed out after ${String(timeoutMs)}ms: ${method} ${path}`,\n timeoutMs,\n );\n }\n if (link.getReason() === 'external') {\n throw new AbortError(`Request aborted by caller: ${method} ${path}`);\n }\n\n if (\n shouldRetry({\n method,\n isConnectionError: true,\n attempt,\n maxRetries: this.config.maxRetries,\n })\n ) {\n await this.waitBeforeRetry(attempt, undefined, options.signal);\n continue;\n }\n const syscall = syscallCodeOf(error);\n throw new GpmPayConnectionError(\n `Could not reach the GPM Pay API at ${this.config.baseUrl}` +\n (syscall === undefined ? '' : ` (${syscall})`) +\n '. Check the baseUrl and your network connection.',\n error,\n syscall,\n );\n }\n\n link.dispose();\n this.config.onResponse?.({\n requestId,\n status: response.status,\n durationMs: Date.now() - startedAt,\n attempt,\n });\n\n if (response.ok) {\n return await parseBody(response);\n }\n\n const retryAfterSeconds = parseRetryAfter(\n response.headers.get('retry-after'),\n );\n\n if (\n shouldRetry({\n method,\n status: response.status,\n attempt,\n maxRetries: this.config.maxRetries,\n })\n ) {\n await this.waitBeforeRetry(attempt, retryAfterSeconds, options.signal);\n continue;\n }\n\n const errorBody = await parseBody(response).catch(() => undefined);\n throw errorFromResponse(\n response.status,\n errorBody,\n requestId,\n retryAfterSeconds === undefined ? {} : { retryAfterSeconds },\n );\n }\n }\n\n private async waitBeforeRetry(\n attempt: number,\n retryAfterSeconds: number | undefined,\n signal: AbortSignal | undefined,\n ): Promise<void> {\n const delay = backoffDelayMs({\n attempt,\n baseDelayMs: this.config.retryBaseDelayMs,\n retryAfterSeconds,\n });\n if (delay > 0) await abortableSleep(delay, signal);\n }\n}\n\nasync function parseBody(response: Response): Promise<unknown> {\n if (response.status === 204 || response.status === 205) return undefined;\n if (response.headers.get('content-length') === '0') return undefined;\n\n const contentType = response.headers.get('content-type') ?? '';\n const text = await response.text();\n if (text === '') return undefined;\n\n if (contentType.includes('json')) {\n return JSON.parse(text);\n }\n\n // Not JSON: try anyway (some proxies omit the header), else hand back the raw\n // text so the error mapper can surface e.g. an HTML 502 page usefully.\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n","import { ApiTokensResource } from '../resources/api-tokens.js';\nimport { BankAccountsResource } from '../resources/bank-accounts.js';\nimport { BanksResource } from '../resources/banks.js';\nimport { SimulatorResource } from '../resources/simulator.js';\nimport { TransactionsResource } from '../resources/transactions.js';\nimport { WebhookHistoriesResource } from '../resources/webhook-histories.js';\nimport { WebhookSettingsResource } from '../resources/webhook-settings.js';\nimport type { RequestOptions } from '../types/common.js';\nimport type { ApiTokenScope } from '../types/enums.js';\nimport { resolveConfig, type GpmPayOptions } from './config.js';\nimport { GpmPayPermissionError } from './errors.js';\nimport { HttpClient } from './http.js';\nimport type { HttpMethod } from './retry.js';\nimport { maskToken, tokenPrefix } from './token.js';\n\nexport interface PingResult {\n ok: true;\n baseUrl: string;\n /** The token's public prefix — safe to print. */\n tokenPrefix: string;\n latencyMs: number;\n /**\n * Which scopes the token actually carries, determined by probing one cheap\n * read per scope. A scope lands in `denied` only on a genuine 403; any other\n * failure (network, 5xx) propagates instead of being reported as missing.\n */\n scopes: { granted: ApiTokenScope[]; denied: ApiTokenScope[] };\n}\n\n/** One cheap read per scope, used by {@link GpmPay.ping} to detect grants. */\nconst SCOPE_PROBES: ReadonlyArray<{ scope: ApiTokenScope; path: string }> = [\n { scope: 'transactions:read', path: '/transactions' },\n { scope: 'bank-accounts:read', path: '/bank-accounts' },\n { scope: 'webhooks:manage', path: '/webhook-settings' },\n];\n\n/**\n * GPM Pay API client.\n *\n * An API token is **required** — the constructor throws immediately if one is\n * missing or malformed, rather than deferring to a 401 on the first call.\n *\n * @example\n * import { GpmPay } from '@gpmpay/sdk';\n *\n * const client = new GpmPay({ apiToken: process.env.GPMPAY_API_TOKEN! });\n * const page = await client.transactions.list({ limit: 10 });\n * console.log(page.data[0]?.transferContent);\n */\nexport class GpmPay {\n readonly transactions: TransactionsResource;\n readonly bankAccounts: BankAccountsResource;\n readonly banks: BanksResource;\n readonly webhookSettings: WebhookSettingsResource;\n readonly webhookHistories: WebhookHistoriesResource;\n readonly apiTokens: ApiTokensResource;\n readonly simulator: SimulatorResource;\n\n private readonly http: HttpClient;\n private readonly token: string;\n\n /** @throws {GpmPayConfigError} when `apiToken` is missing or malformed. */\n constructor(options: GpmPayOptions) {\n const config = resolveConfig(options);\n this.token = config.apiToken;\n this.http = new HttpClient(config);\n\n this.transactions = new TransactionsResource(this.http);\n this.bankAccounts = new BankAccountsResource(this.http);\n this.banks = new BanksResource(this.http);\n this.webhookSettings = new WebhookSettingsResource(this.http);\n this.webhookHistories = new WebhookHistoriesResource(this.http);\n this.apiTokens = new ApiTokensResource(this.http);\n this.simulator = new SimulatorResource(this.http);\n }\n\n /**\n * Build a client from `GPMPAY_API_TOKEN` and `GPMPAY_API_URL`.\n *\n * @throws {GpmPayConfigError} when `GPMPAY_API_TOKEN` is not set.\n */\n static fromEnv(overrides: Partial<GpmPayOptions> = {}): GpmPay {\n const envToken = process.env.GPMPAY_API_TOKEN;\n const envUrl = process.env.GPMPAY_API_URL;\n\n const options: GpmPayOptions = {\n ...overrides,\n apiToken: overrides.apiToken ?? (envToken as string),\n };\n const baseUrl = overrides.baseUrl ?? envUrl;\n if (baseUrl !== undefined) options.baseUrl = baseUrl;\n\n return new GpmPay(options);\n }\n\n /** Fully normalized API base, e.g. `https://api.gpmpay.com/api/v1`. */\n get baseUrl(): string {\n return this.http.baseUrl;\n }\n\n /** First 12 chars of the token. Safe to log and quote in support tickets. */\n get tokenPrefix(): string {\n return tokenPrefix(this.token);\n }\n\n toString(): string {\n return `GpmPay(${this.baseUrl}, ${maskToken(this.token)})`;\n }\n\n /** Ensures `console.log(client)` can never dump the token. */\n [Symbol.for('nodejs.util.inspect.custom')](): string {\n return this.toString();\n }\n\n /**\n * Verify connectivity and authentication, and report the token's real scopes.\n *\n * Issues one minimal read per scope in parallel and infers the grant from the\n * outcome. The token's own record cannot be used for this: `GET /api-tokens`\n * declares no `@ApiScopes()`, so the fail-closed guard rejects every API\n * token that asks for it.\n *\n * A 401 from the first probe to complete propagates — an invalid token is a\n * hard failure, not \"no scopes\".\n */\n async ping(options: RequestOptions = {}): Promise<PingResult> {\n const startedAt = Date.now();\n\n const results = await Promise.all(\n SCOPE_PROBES.map(async ({ scope, path }) => {\n try {\n await this.http.requestList<unknown>('GET', path, {\n ...options,\n query: { limit: 1 },\n });\n return { scope, granted: true };\n } catch (error) {\n if (error instanceof GpmPayPermissionError) {\n return { scope, granted: false };\n }\n throw error;\n }\n }),\n );\n\n const latencyMs = Date.now() - startedAt;\n\n return {\n ok: true,\n baseUrl: this.baseUrl,\n tokenPrefix: this.tokenPrefix,\n latencyMs,\n scopes: {\n granted: results.filter((r) => r.granted).map((r) => r.scope),\n denied: results.filter((r) => !r.granted).map((r) => r.scope),\n },\n };\n }\n\n /**\n * Escape hatch for endpoints this SDK does not model yet.\n *\n * @example\n * await client.request('GET', '/some/new/endpoint');\n */\n request<T = unknown>(\n method: HttpMethod,\n path: string,\n options: RequestOptions & { query?: Record<string, unknown>; body?: unknown } = {},\n ): Promise<T> {\n return this.http.request<T>(method, path, options);\n }\n}\n","import { createHmac, timingSafeEqual } from 'node:crypto';\n\nimport { GpmPayWebhookSignatureError } from '../core/errors.js';\nimport type { WebhookPayload } from '../types/webhook.js';\n\n/** Header carrying the signature. Overridable per webhook setting. */\nexport const SIGNATURE_HEADER = 'X-GPMPay-Signature';\n\n/** Header carrying the event name (WordPress driver). */\nexport const EVENT_HEADER = 'X-GPMPay-Event';\n\n/** Clock-skew window the backend also enforces. */\nexport const DEFAULT_TOLERANCE_SECONDS = 300;\n\nexport interface VerifyWebhookInput {\n /**\n * The **exact bytes** of the request body.\n *\n * Never `JSON.stringify(req.body)` — re-serializing a parsed body changes\n * whitespace and key order, and the signature will never match.\n */\n rawBody: string | Buffer | Uint8Array;\n /** Value of `X-GPMPay-Signature`: `t=<unix_seconds>,v1=<hex_sha256>`. */\n signature: string;\n /**\n * `authorizationSecret` for an HTTP+HMAC webhook, or `wpSecret` for the\n * WordPress driver.\n */\n secret: string;\n /** Skew window in seconds. Default 300. Pass 0 to disable (tests only). */\n toleranceSeconds?: number;\n /** @internal Test seam. */\n now?: () => number;\n}\n\nfunction toBuffer(input: string | Buffer | Uint8Array): Buffer {\n if (Buffer.isBuffer(input)) return input;\n if (typeof input === 'string') return Buffer.from(input, 'utf8');\n return Buffer.from(input);\n}\n\n/**\n * Parse `t=…,v1=…`, splitting each pair on its **first** `=` only — hex and\n * base64 values may legitimately contain `=`.\n */\nfunction parseSignatureHeader(signature: string): Record<string, string> {\n const parts: Record<string, string> = {};\n for (const segment of signature.split(',')) {\n const index = segment.indexOf('=');\n if (index > 0) {\n parts[segment.slice(0, index).trim()] = segment.slice(index + 1).trim();\n }\n }\n return parts;\n}\n\n/**\n * Verify a webhook signature, throwing a typed error explaining exactly why it\n * failed.\n *\n * Matches `apps/backend/src/modules/webhook-delivery/hmac.util.ts`: the signed\n * string is `` `${t}.${rawBody}` ``, hashed with HMAC-SHA256 and compared in\n * constant time.\n *\n * @throws {GpmPayWebhookSignatureError}\n */\nexport function assertWebhookSignature(input: VerifyWebhookInput): {\n timestamp: number;\n} {\n const { signature, secret, now = Date.now } = input;\n const tolerance = input.toleranceSeconds ?? DEFAULT_TOLERANCE_SECONDS;\n\n if (typeof secret !== 'string' || secret === '') {\n throw new GpmPayWebhookSignatureError(\n 'Webhook secret is empty. Pass the secret you configured on the webhook ' +\n 'setting (e.g. process.env.GPMPAY_WEBHOOK_SECRET).',\n 'missing_secret',\n );\n }\n\n if (typeof signature !== 'string' || signature.trim() === '') {\n throw new GpmPayWebhookSignatureError(\n `Missing ${SIGNATURE_HEADER} header.`,\n 'malformed_header',\n );\n }\n\n const parts = parseSignatureHeader(signature);\n const timestamp = Number(parts.t);\n const v1 = parts.v1;\n\n if (!Number.isFinite(timestamp) || timestamp <= 0 || !v1) {\n throw new GpmPayWebhookSignatureError(\n `Malformed ${SIGNATURE_HEADER}: \"${signature}\". Expected \"t=<unix_seconds>,v1=<hex>\".`,\n 'malformed_header',\n );\n }\n\n if (tolerance > 0 && Math.abs(now() / 1000 - timestamp) > tolerance) {\n throw new GpmPayWebhookSignatureError(\n `Webhook timestamp is outside the ${String(tolerance)}s tolerance (t=${String(timestamp)}). ` +\n 'Check for clock skew between your server and GPM Pay.',\n 'timestamp_skew',\n );\n }\n\n // Hash over bytes, not characters: Vietnamese transfer contents are\n // multi-byte, and hashing the string length would silently diverge.\n const raw = toBuffer(input.rawBody);\n const expected = createHmac('sha256', secret)\n .update(Buffer.concat([Buffer.from(`${String(timestamp)}.`, 'utf8'), raw]))\n .digest();\n\n const provided = Buffer.from(v1, 'hex');\n if (\n expected.length !== provided.length ||\n !timingSafeEqual(expected, provided)\n ) {\n throw new GpmPayWebhookSignatureError(\n 'Webhook signature mismatch — wrong secret, or the body was modified in transit. ' +\n 'Make sure you are verifying the raw request body, not a re-serialized object.',\n 'mismatch',\n );\n }\n\n return { timestamp };\n}\n\n/** Boolean form of {@link assertWebhookSignature}. */\nexport function verifyWebhookSignature(input: VerifyWebhookInput): boolean {\n try {\n assertWebhookSignature(input);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Produce a signature header. Useful for testing your own handler and for\n * generating fixtures; GPM Pay signs real deliveries itself.\n */\nexport function signWebhookPayload(params: {\n rawBody: string | Buffer | Uint8Array;\n secret: string;\n /** Unix seconds. Defaults to now. */\n timestamp?: number;\n}): string {\n const timestamp = params.timestamp ?? Math.floor(Date.now() / 1000);\n const raw = toBuffer(params.rawBody);\n const digest = createHmac('sha256', params.secret)\n .update(Buffer.concat([Buffer.from(`${String(timestamp)}.`, 'utf8'), raw]))\n .digest('hex');\n return `t=${String(timestamp)},v1=${digest}`;\n}\n\nexport interface GpmPayWebhookEvent {\n /** From `X-GPMPay-Event`; defaults to `transaction.created`. */\n type: string;\n /** Unix seconds the delivery was signed at. */\n timestamp: number;\n payload: WebhookPayload;\n /** The raw body, for logging or re-verification. */\n rawBody: string;\n}\n\nfunction headerValue(\n headers: Record<string, string | string[] | undefined> | undefined,\n name: string,\n): string | undefined {\n if (!headers) return undefined;\n const target = name.toLowerCase();\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() !== target) continue;\n return Array.isArray(value) ? value[0] : value;\n }\n return undefined;\n}\n\n/**\n * Verify a delivery and parse it into a typed event.\n *\n * @throws {GpmPayWebhookSignatureError} when verification fails.\n */\nexport function constructWebhookEvent(\n input: VerifyWebhookInput & {\n headers?: Record<string, string | string[] | undefined>;\n },\n): GpmPayWebhookEvent {\n const { timestamp } = assertWebhookSignature(input);\n const rawBody = toBuffer(input.rawBody).toString('utf8');\n\n return {\n type: headerValue(input.headers, EVENT_HEADER) ?? 'transaction.created',\n timestamp,\n payload: JSON.parse(rawBody) as WebhookPayload,\n rawBody,\n };\n}\n\n/**\n * Constant-time comparison for webhooks configured with\n * `authorizationType: 'API_KEY'`, where the raw secret is sent in a header\n * instead of being used to sign the body.\n */\nexport function verifyApiKeyHeader(\n received: string | undefined,\n expected: string,\n): boolean {\n if (typeof received !== 'string' || expected === '') return false;\n const a = Buffer.from(received, 'utf8');\n const b = Buffer.from(expected, 'utf8');\n if (a.length !== b.length) return false;\n return timingSafeEqual(a, b);\n}\n","/**\n * CRC-16/CCITT-FALSE, as required by the EMVCo QR spec (tag 63).\n *\n * Byte-for-byte port of `apps/backend/src/modules/vietqr/crc16.util.ts`;\n * `vietqr.test.ts` asserts both stay in agreement via shared fixtures.\n */\nexport function crc16ccitt(input: string): string {\n let crc = 0xffff;\n for (let i = 0; i < input.length; i++) {\n crc ^= input.charCodeAt(i) << 8;\n for (let j = 0; j < 8; j++) {\n crc = crc & 0x8000 ? (crc << 1) ^ 0x1021 : crc << 1;\n crc &= 0xffff;\n }\n }\n return crc.toString(16).toUpperCase().padStart(4, '0');\n}\n","import { GpmPayConfigError } from '../core/errors.js';\nimport type { BankAccount, Bank } from '../types/bank.js';\nimport { crc16ccitt } from './crc16.js';\n\n/** VietQR truncates the addendum field; the backend applies the same limit. */\nconst DESCRIPTION_MAX_LENGTH = 25;\n\nexport interface VietQrInput {\n /** NAPAS BIN of the beneficiary bank (`bank.bin`). */\n bankBin: string;\n accountNumber: string;\n /** Omit for a static QR the payer fills in themselves. */\n amount?: number | string;\n /** Truncated to 25 chars, matching the server. */\n description?: string;\n serviceCode?: 'QRIBFTTA' | 'QRIBFTTC';\n}\n\nexport interface VietQrImageInput extends VietQrInput {\n template?: 'compact' | 'compact2' | 'qr_only' | 'print';\n accountName?: string;\n}\n\nconst tlv = (id: string, value: string): string =>\n id + value.length.toString().padStart(2, '0') + value;\n\nfunction isDynamic(amount: number | string | undefined): boolean {\n return amount !== undefined && amount !== null && amount !== '';\n}\n\nfunction trimDescription(description: string | undefined): string | undefined {\n return description === undefined\n ? undefined\n : description.slice(0, DESCRIPTION_MAX_LENGTH);\n}\n\n/**\n * Build an EMVCo/VietQR payload string.\n *\n * @remarks\n * This is the main entry point when you handle reconciliation yourself — the\n * common case. Put your own order code in `description`; it becomes the\n * transfer content, and you match it against `event.payload.content` when the\n * webhook arrives.\n *\n * ```ts\n * const payload = buildVietQrPayload({\n * bankBin: '970422', // account.bank.bin\n * accountNumber: '1234567890',\n * amount: 50_000,\n * description: 'DH123', // your own code — keep it <= 25 chars\n * });\n * ```\n *\n * Also fine for a static account QR: omit `amount` and the payer fills it in.\n *\n * `description` is what the payer ends up transferring, so it carries your\n * reconciliation code. VietQR truncates it to 25 characters and banks may\n * prepend their own prefix — keep the code short and at the front. For the\n * common case, {@link buildPaymentInstructions} wraps this up from a bank\n * account object.\n *\n * Byte-for-byte port of `apps/backend/src/modules/vietqr/vietqr.util.ts`.\n */\nexport function buildVietQrPayload(input: VietQrInput): string {\n const {\n bankBin,\n accountNumber,\n amount,\n description,\n serviceCode = 'QRIBFTTA',\n } = input;\n\n const beneficiaryOrg = tlv('00', bankBin) + tlv('01', accountNumber);\n const merchantAccountInfo =\n tlv('00', 'A000000727') + tlv('01', beneficiaryOrg) + tlv('02', serviceCode);\n\n const dynamic = isDynamic(amount);\n const trimmedDesc = trimDescription(description);\n const additionalData = trimmedDesc ? tlv('08', trimmedDesc) : '';\n\n const parts = [\n tlv('00', '01'),\n tlv('01', dynamic ? '12' : '11'),\n tlv('38', merchantAccountInfo),\n tlv('53', '704'),\n ...(dynamic ? [tlv('54', String(amount))] : []),\n tlv('58', 'VN'),\n ...(additionalData ? [tlv('62', additionalData)] : []),\n ];\n\n const base = parts.join('') + '6304';\n return base + crc16ccitt(base);\n}\n\n/**\n * Build an `img.vietqr.io` image URL.\n *\n * The server always emits the `compact` template; pass `template` to pick a\n * different one for your own checkout page.\n */\nexport function buildVietQrImageUrl(input: VietQrImageInput): string {\n const { bankBin, accountNumber, amount, template = 'compact' } = input;\n const trimmedDesc = trimDescription(input.description);\n\n const url = new URL(\n `https://img.vietqr.io/image/${bankBin}-${accountNumber}-${template}.png`,\n );\n if (isDynamic(amount)) url.searchParams.set('amount', String(amount));\n if (trimmedDesc) url.searchParams.set('addInfo', trimmedDesc);\n if (input.accountName !== undefined) {\n url.searchParams.set('accountName', input.accountName);\n }\n\n return url.toString();\n}\n\nexport interface PaymentRequest {\n /**\n * The destination account, as returned by\n * `client.bankAccounts.retrieve(id)`. Must carry its `bank` relation — the\n * NAPAS BIN lives there.\n */\n bankAccount: BankAccount & { bank?: Bank };\n /** VND. A number, or the string form the API returns for `Decimal`. */\n amount: number | string;\n /**\n * The transfer content you will look for later. Put **your own** order\n * reference in here — GPM Pay mints nothing and matches nothing. Truncated\n * to 25 chars inside the QR, so keep the code short and near the front.\n */\n transferContent: string;\n serviceCode?: 'QRIBFTTA' | 'QRIBFTTC';\n template?: VietQrImageInput['template'];\n}\n\nexport interface PaymentInstructions {\n /** EMVCo payload. Render this as the QR. */\n qrPayload: string;\n qrImageUrl: string;\n amount: number;\n /** What the payer MUST put in the transfer content. */\n transferContent: string;\n bankName: string | undefined;\n bankBin: string | undefined;\n accountNumber: string;\n accountName: string;\n}\n\n/**\n * Everything a checkout page needs, built entirely client-side.\n *\n * @remarks\n * There is no server-side order to read this from — GPM Pay has no\n * order/QR-minting endpoint. You choose the reference code, you render the QR,\n * and you reconcile it yourself when the transaction webhook arrives by looking\n * for that code in `payload.content`.\n *\n * @throws {GpmPayConfigError} when `bankAccount.bank.bin` is missing — without\n * the BIN there is no valid VietQR payload to build.\n *\n * @example\n * const account = await client.bankAccounts.retrieve(bankAccountId);\n * const ref = `SHOP${orderId}`;\n * const instructions = buildPaymentInstructions({\n * bankAccount: account,\n * amount: 250_000,\n * transferContent: ref,\n * });\n */\nexport function buildPaymentInstructions(\n request: PaymentRequest,\n): PaymentInstructions {\n const account = request.bankAccount;\n const bank = account.bank;\n\n if (bank === undefined || bank.bin === '') {\n throw new GpmPayConfigError(\n 'buildPaymentInstructions: bankAccount.bank.bin is required to build a ' +\n 'VietQR payload. Fetch the account with its `bank` relation, e.g. ' +\n '`await client.bankAccounts.retrieve(id)`.',\n );\n }\n const bankBin = bank.bin;\n\n const base: VietQrInput = {\n bankBin,\n accountNumber: account.accountNumber,\n amount: request.amount,\n description: request.transferContent,\n };\n if (request.serviceCode !== undefined) base.serviceCode = request.serviceCode;\n\n const imageInput: VietQrImageInput = {\n ...base,\n accountName: account.ownerName,\n };\n if (request.template !== undefined) imageInput.template = request.template;\n\n return {\n qrPayload: buildVietQrPayload(base),\n qrImageUrl: buildVietQrImageUrl(imageInput),\n amount: Number(request.amount),\n transferContent: request.transferContent,\n bankName: bank.shortName === '' ? bank.name : bank.shortName,\n bankBin,\n accountNumber: account.accountNumber,\n accountName: account.ownerName,\n };\n}\n","/**\n * String-literal unions mirroring the backend's Prisma enums and\n * `apps/backend/src/modules/api-tokens/api-token.types.ts`.\n *\n * These are deliberately vendored rather than imported from `@repo/shared-types`\n * (that package is unpublishable). `src/types/__compat__.ts` asserts they stay\n * in sync at compile time.\n */\n\n/** Scopes an API token can carry. */\nexport type ApiTokenScope =\n | 'transactions:read'\n | 'bank-accounts:read'\n | 'webhooks:manage';\n\nexport const ALL_API_SCOPES: readonly ApiTokenScope[] = [\n 'transactions:read',\n 'bank-accounts:read',\n 'webhooks:manage',\n] as const;\n\n/** `ACTIVE` = usable. `PENDING` = temporarily blocked by the owner. */\nexport type ApiTokenStatus = 'ACTIVE' | 'PENDING';\n\nexport type TransactionType = 'IN' | 'OUT';\n\nexport type TransactionSource = 'REAL' | 'SIMULATED';\n\nexport type BankAccountStatus =\n | 'ACTIVE'\n | 'SUSPENDED'\n | 'DELETED'\n | 'PENDING_VERIFICATION';\n\nexport type WebhookDriver = 'HTTP' | 'TELEGRAM' | 'WORDPRESS' | 'GOOGLE_SHEETS';\n\nexport type WebhookAuthType = 'NONE' | 'API_KEY' | 'HMAC';\n\nexport type WebhookScope = 'ALL' | 'SPECIFIC';\n\nexport type WebhookDeliveryStatus =\n | 'PENDING'\n | 'DELIVERED'\n | 'RETRYING'\n | 'FAILED';\n\n/**\n * Delivery retry backoff used by the GPM Pay webhook dispatcher, in seconds.\n * Mirrors `apps/backend/src/modules/webhook-delivery/backoff.util.ts`.\n *\n * Your endpoint will be called up to {@link WEBHOOK_MAX_ATTEMPTS} times for the\n * same transaction — make it idempotent on `payload.id`.\n */\nexport const WEBHOOK_RETRY_SCHEDULE_SECONDS: readonly number[] = [\n 10, 30, 120, 600, 3600, 21600,\n] as const;\n\nexport const WEBHOOK_MAX_ATTEMPTS = 6;\n\n/**\n * The HTTP delivery driver aborts after this long. Respond within it or the\n * delivery is recorded as failed and retried.\n */\nexport const WEBHOOK_DELIVERY_TIMEOUT_MS = 5000;\n"]}