import { R as RequestOptions, P as Page, L as ListParams, a as ListWebhookHistoriesParams, W as WebhookHistory, b as WebhookSetting, c as ListWebhookSettingsParams, C as CreateWebhookSettingParams, U as UpdateWebhookSettingParams } from './verify-DVgS9Vh1.cjs';
export { A as AuthFailureReason, d as ConfigErrorCode, E as EVENT_HEADER, G as GpmPayAPIError, e as GpmPayAuthenticationError, f as GpmPayBadRequestError, g as GpmPayConfigError, h as GpmPayConnectionError, i as GpmPayError, j as GpmPayNotFoundError, k as GpmPayPermissionError, l as GpmPayRateLimitError, m as GpmPayServerError, n as GpmPayTimeoutError, o as GpmPayWebhookEvent, p as GpmPayWebhookSignatureError, M as MAX_PAGE_SIZE, q as PageMeta, r as PermissionFailureReason, S as SIGNATURE_HEADER, s as SortOrder, V as VerifyWebhookInput, t as WebhookPayload, u as WebhookSignatureFailureReason, v as assertWebhookSignature, w as constructWebhookEvent, x as signWebhookPayload, y as verifyWebhookSignature } from './verify-DVgS9Vh1.cjs';
import { L as ListBankAccountsParams, B as BankAccount, a as Bank, T as TransactionType, b as TransactionSource, A as ApiTokenScope } from './bank-SVz37Xt1.cjs';
export { c as ALL_API_SCOPES, d as ApiTokenStatus, e as BankAccountStatus, W as WEBHOOK_DELIVERY_TIMEOUT_MS, f as WEBHOOK_MAX_ATTEMPTS, g as WEBHOOK_RETRY_SCHEDULE_SECONDS, h as WebhookAuthType, i as WebhookDeliveryStatus, j as WebhookDriver, k as WebhookScope } from './bank-SVz37Xt1.cjs';
export { P as PaymentInstructions, a as PaymentRequest, V as VietQrImageInput, b as VietQrInput, c as buildPaymentInstructions, d as buildVietQrImageUrl, e as buildVietQrPayload } from './vietqr-FG15aLPN.cjs';

declare const DEFAULT_BASE_URL = "https://api.gpmpay.com";
declare const SANDBOX_BASE_URL = "https://sandbox-api.gpmpay.com";
interface RequestLogEvent {
    method: string;
    url: string;
    requestId: string;
    attempt: number;
}
interface ResponseLogEvent {
    requestId: string;
    status: number;
    durationMs: number;
    attempt: number;
}
interface GpmPayOptions {
    /**
     * **Required.** Your GPM Pay API token (`gpm_…`).
     *
     * Create one at https://app.gpmpay.com/api-tokens. This is a
     * server-side secret — never ship it to a browser or mobile client.
     */
    apiToken: string;
    /**
     * API base URL. Accepts a bare host, `host/api`, or `host/api/v1` — the SDK
     * normalizes all of them. Defaults to `https://api.gpmpay.com`.
     */
    baseUrl?: string;
    /** Shorthand for the sandbox host. Ignored when `baseUrl` is set. */
    sandbox?: boolean;
    /** Per-request timeout in ms. Default 30000. */
    timeoutMs?: number;
    /** Retries for retryable failures. Default 2. Set 0 to disable. */
    maxRetries?: number;
    /** Base backoff in ms; full-jitter exponential capped at 8s. Default 500. */
    retryBaseDelayMs?: number;
    /** Inject a fetch implementation (tests, proxy agents, instrumentation). */
    fetch?: typeof globalThis.fetch;
    /** Appended to the SDK's own User-Agent. */
    userAgent?: string;
    /** Merged into every request. Cannot override `Authorization`. */
    defaultHeaders?: Record<string, string>;
    /**
     * Reject tokens that don't match the documented `gpm_…` shape. Default true.
     * The presence check always applies regardless of this flag.
     */
    strictTokenFormat?: boolean;
    /** Observability hooks. Never receive the token. */
    onRequest?: (event: RequestLogEvent) => void;
    onResponse?: (event: ResponseLogEvent) => void;
}
interface ResolvedConfig {
    apiToken: string;
    baseUrl: string;
    timeoutMs: number;
    maxRetries: number;
    retryBaseDelayMs: number;
    fetchImpl: typeof globalThis.fetch;
    userAgent: string | undefined;
    defaultHeaders: Record<string, string>;
    onRequest: ((event: RequestLogEvent) => void) | undefined;
    onResponse: ((event: ResponseLogEvent) => void) | undefined;
}
/**
 * Normalize any reasonable spelling of the API host into a full versioned base.
 *
 * Mirrors the WooCommerce plugin's normalization so merchants can paste
 * whatever they have. `http://` is preserved — localhost must not be forced
 * to https.
 *
 * @example
 * normalizeBaseUrl('api.gpmpay.com')              // https://api.gpmpay.com/api/v1
 * normalizeBaseUrl('https://api.gpmpay.com/')     // https://api.gpmpay.com/api/v1
 * normalizeBaseUrl('https://api.gpmpay.com/api')  // https://api.gpmpay.com/api/v1
 * normalizeBaseUrl('http://localhost:4000')       // http://localhost:4000/api/v1
 */
declare function normalizeBaseUrl(input: string): string;

type QueryInput = Record<string, unknown> | undefined;

type HttpMethod = 'GET' | 'HEAD' | 'POST' | 'PATCH' | 'PUT' | 'DELETE';

interface HttpRequestOptions extends RequestOptions {
    query?: QueryInput;
    body?: unknown;
}
declare class HttpClient {
    private readonly config;
    private readonly userAgent;
    constructor(config: ResolvedConfig);
    get baseUrl(): string;
    /** Issue a request and return the unwrapped `data` payload. */
    request<T>(method: HttpMethod, path: string, options?: HttpRequestOptions): Promise<T>;
    /** Issue a list request and normalize it into a `Page<T>`. */
    requestList<T>(method: HttpMethod, path: string, options?: HttpRequestOptions): Promise<Page<T>>;
    private send;
    private waitBeforeRetry;
}

/**
 * The one API-token route an API token may call.
 *
 * @remarks
 * This class looks incomplete on purpose. `ApiTokenGuard` is fail-closed: a
 * route that declares no `@ApiScopes()` rejects API tokens outright with
 * `403 "This endpoint is not available to API tokens"`. Listing, creating,
 * regenerating and status changes are all dashboard-session routes, so
 * modelling them here would only ship methods that can never succeed.
 *
 * `DELETE /api-tokens/:id` is the documented exception — it carries
 * `@AllowAnyApiToken()` so an integration can revoke its own token when the
 * merchant disconnects. Ownership is still enforced server-side.
 *
 * Manage tokens at https://app.gpmpay.com/api-tokens.
 */
declare class ApiTokensResource {
    private readonly http;
    constructor(http: HttpClient);
    /**
     * Permanently delete a token. Any valid token may call this; the backend
     * still requires the token being deleted to belong to the caller.
     */
    remove(id: string, options?: RequestOptions): Promise<unknown>;
}

/**
 * Read-only access to your bank accounts. Scope: `bank-accounts:read`.
 *
 * @remarks
 * Write operations (`create`, `update`, `remove`, `rotate-ingest-secret`,
 * `subscribe`) are intentionally **not** exposed. There is no
 * `bank-accounts:write` scope, `rotate-ingest-secret` returns a plaintext
 * secret, and `subscribe` spends money — none of which belongs behind a
 * read-scoped token. Use the dashboard for those.
 */
declare class BankAccountsResource {
    private readonly http;
    constructor(http: HttpClient);
    list(params?: ListBankAccountsParams, options?: RequestOptions): Promise<Page<BankAccount>>;
    retrieve(id: string, options?: RequestOptions): Promise<BankAccount>;
}

/**
 * The catalogue of banks GPM Pay supports.
 *
 * @remarks
 * Scope: `bank-accounts:read`.
 *
 * You only need this when you want a bank *you have no account at* — to render
 * a bank picker, or to build a VietQR for an external account. For your own
 * accounts the NAPAS `bin` already rides along on the `bank` relation of
 * `bankAccounts.list()` / `bankAccounts.retrieve()`, so no extra call is needed.
 */
declare class BanksResource {
    private readonly http;
    constructor(http: HttpClient);
    /** List active banks. The endpoint returns a flat array, not a page. */
    list(options?: RequestOptions): Promise<Bank[]>;
}

interface Transaction {
    id: string;
    bankAccountId: string;
    type: TransactionType;
    source: TransactionSource;
    /** VND, serialized as a string (Prisma `Decimal`). Use `toVnd()`. */
    amount: string;
    /** Running balance after the transaction, when the bank reports it. */
    balanceAfter: string | null;
    referenceCode: string;
    transferContent: string;
    counterAccount: string | null;
    counterName: string | null;
    transactionTime: string;
    createdAt: string;
    bankAccount?: BankAccount;
}
interface TransactionDetail extends Transaction {
    webhookHistories?: unknown[];
}
interface ListTransactionsParams extends ListParams {
    bankAccountId?: string;
    type?: TransactionType;
    source?: TransactionSource;
}
/**
 * What `POST /simulator/transactions` actually returns — the transaction plus
 * the webhook deliveries it queued. The route does not return a bare
 * `Transaction`; it never has.
 */
interface SimulatedTransactionResult {
    transaction: Transaction;
    /**
     * One id per queued webhook delivery. Empty when no endpoint has
     * `fireOnSimulated` enabled — the fastest way to tell a silent simulation
     * from a broken one.
     */
    historyIds: string[];
}
interface SimulateTransactionParams {
    bankAccountId: string;
    /** VND, integer, >= 1. */
    amount: number;
    /**
     * <= 100 chars. Put your own reconciliation code in here — this is the field
     * you parse back out of the webhook payload's `content`.
     */
    transferContent: string;
    type?: TransactionType;
    /** <= 64 chars. */
    referenceCode?: string;
    /** <= 64 chars. */
    counterAccount?: string;
    /** <= 255 chars. */
    counterName?: string;
    transactionTime?: string | Date;
}

interface SimulatorOptions extends RequestOptions {
    /**
     * Simulated transactions are a development tool. The SDK refuses to call
     * this against a production base URL unless you opt in explicitly.
     */
    allowOnProduction?: boolean;
}
/**
 * Generate fake inbound transfers for local development and integration tests.
 *
 * Scope: `transactions:read`. That reads oddly for a route that *creates* a
 * transaction — it is a deliberate backend trade-off to avoid minting a new
 * scope. Simulated transactions always carry `source: 'SIMULATED'` and only
 * fan out to endpoints with `fireOnSimulated` enabled.
 */
declare class SimulatorResource {
    private readonly http;
    constructor(http: HttpClient);
    private assertSafeEnvironment;
    /**
     * Create a simulated bank transaction.
     *
     * Returns the envelope the route actually sends — `{ transaction,
     * historyIds }`, not a bare `Transaction`. Read `result.transaction` for the
     * ledger row and `result.historyIds.length` to confirm a webhook was queued.
     *
     * `async` so guard failures reject rather than throwing synchronously.
     */
    createTransaction(params: SimulateTransactionParams, options?: SimulatorOptions): Promise<SimulatedTransactionResult>;
}

declare class TransactionsResource {
    private readonly http;
    constructor(http: HttpClient);
    /**
     * List transactions across your bank accounts. Scope: `transactions:read`.
     *
     * @remarks
     * `limit` is capped at 50 server-side. `search` matches `referenceCode` and
     * `transferContent`; `startDate`/`endDate` filter on `transactionTime`.
     */
    list(params?: ListTransactionsParams, options?: RequestOptions): Promise<Page<Transaction>>;
    /**
     * Iterate every matching transaction, fetching pages as needed.
     *
     * @example
     * for await (const txn of client.transactions.listAll({ type: 'IN' })) {
     *   console.log(txn.referenceCode);
     * }
     */
    listAll(params?: Omit<ListTransactionsParams, 'page'>, options?: RequestOptions): AsyncGenerator<Transaction, void, undefined>;
    /** Fetch one transaction. Scope: `transactions:read`. */
    retrieve(id: string, options?: RequestOptions): Promise<TransactionDetail>;
}

/** Inspect and replay webhook deliveries. Scope: `webhooks:manage`. */
declare class WebhookHistoriesResource {
    private readonly http;
    constructor(http: HttpClient);
    list(params?: ListWebhookHistoriesParams, options?: RequestOptions): Promise<Page<WebhookHistory>>;
    retrieve(id: string, options?: RequestOptions): Promise<WebhookHistory>;
    /** Re-enqueue a failed delivery. */
    retry(id: string, options?: RequestOptions): Promise<WebhookHistory>;
}

interface CreateHmacEndpointParams {
    /** Where GPM Pay should POST transaction events. */
    url: string;
    name?: string;
    scope?: 'ALL' | 'SPECIFIC';
    bankAccountIds?: string[];
    /** Provide your own, or let the SDK generate a 256-bit hex secret. */
    secret?: string;
}
interface CreateHmacEndpointResult {
    setting: WebhookSetting;
    /**
     * The signing secret, in plaintext.
     *
     * @remarks
     * Returned **once**. The API stores it encrypted and never gives it back —
     * persist it now, e.g. as `GPMPAY_WEBHOOK_SECRET`.
     */
    secret: string;
}
/** Manage webhook endpoints. Scope: `webhooks:manage`. */
declare class WebhookSettingsResource {
    private readonly http;
    constructor(http: HttpClient);
    list(params?: ListWebhookSettingsParams, options?: RequestOptions): Promise<Page<WebhookSetting>>;
    retrieve(id: string, options?: RequestOptions): Promise<WebhookSetting>;
    create(params: CreateWebhookSettingParams, options?: RequestOptions): Promise<WebhookSetting>;
    update(id: string, params: UpdateWebhookSettingParams, options?: RequestOptions): Promise<WebhookSetting>;
    remove(id: string, options?: RequestOptions): Promise<unknown>;
    /**
     * Register an HTTP endpoint with HMAC signing and hand back the secret.
     *
     * Pair the returned secret with `verifyWebhookSignature` from
     * `@gpmpay/sdk/webhooks`.
     */
    createHmacEndpoint(params: CreateHmacEndpointParams, options?: RequestOptions): Promise<CreateHmacEndpointResult>;
}

interface PingResult {
    ok: true;
    baseUrl: string;
    /** The token's public prefix — safe to print. */
    tokenPrefix: string;
    latencyMs: number;
    /**
     * Which scopes the token actually carries, determined by probing one cheap
     * read per scope. A scope lands in `denied` only on a genuine 403; any other
     * failure (network, 5xx) propagates instead of being reported as missing.
     */
    scopes: {
        granted: ApiTokenScope[];
        denied: ApiTokenScope[];
    };
}
/**
 * GPM Pay API client.
 *
 * An API token is **required** — the constructor throws immediately if one is
 * missing or malformed, rather than deferring to a 401 on the first call.
 *
 * @example
 * import { GpmPay } from '@gpmpay/sdk';
 *
 * const client = new GpmPay({ apiToken: process.env.GPMPAY_API_TOKEN! });
 * const page = await client.transactions.list({ limit: 10 });
 * console.log(page.data[0]?.transferContent);
 */
declare class GpmPay {
    readonly transactions: TransactionsResource;
    readonly bankAccounts: BankAccountsResource;
    readonly banks: BanksResource;
    readonly webhookSettings: WebhookSettingsResource;
    readonly webhookHistories: WebhookHistoriesResource;
    readonly apiTokens: ApiTokensResource;
    readonly simulator: SimulatorResource;
    private readonly http;
    private readonly token;
    /** @throws {GpmPayConfigError} when `apiToken` is missing or malformed. */
    constructor(options: GpmPayOptions);
    /**
     * Build a client from `GPMPAY_API_TOKEN` and `GPMPAY_API_URL`.
     *
     * @throws {GpmPayConfigError} when `GPMPAY_API_TOKEN` is not set.
     */
    static fromEnv(overrides?: Partial<GpmPayOptions>): GpmPay;
    /** Fully normalized API base, e.g. `https://api.gpmpay.com/api/v1`. */
    get baseUrl(): string;
    /** First 12 chars of the token. Safe to log and quote in support tickets. */
    get tokenPrefix(): string;
    toString(): string;
    /**
     * Verify connectivity and authentication, and report the token's real scopes.
     *
     * Issues one minimal read per scope in parallel and infers the grant from the
     * outcome. The token's own record cannot be used for this: `GET /api-tokens`
     * declares no `@ApiScopes()`, so the fail-closed guard rejects every API
     * token that asks for it.
     *
     * A 401 from the first probe to complete propagates — an invalid token is a
     * hard failure, not "no scopes".
     */
    ping(options?: RequestOptions): Promise<PingResult>;
    /**
     * Escape hatch for endpoints this SDK does not model yet.
     *
     * @example
     * await client.request('GET', '/some/new/endpoint');
     */
    request<T = unknown>(method: HttpMethod, path: string, options?: RequestOptions & {
        query?: Record<string, unknown>;
        body?: unknown;
    }): Promise<T>;
}

/** Mirrors `API_TOKEN_PREFIX` in `apps/backend/src/modules/api-tokens/api-tokens.service.ts`. */
declare const API_TOKEN_PREFIX = "gpm_";
/**
 * `gpm_` (4) + base64url public part (8) + `_` + base64url secret (24) = 37 chars.
 *
 * The width is fixed, so the separating `_` is unambiguous even though base64url
 * itself may contain `_`.
 */
declare const API_TOKEN_RE: RegExp;
/**
 * The token's public prefix — the first 12 chars, matching `ApiToken.tokenPrefix`
 * in the database. Safe to log and to display in support tickets.
 */
declare function tokenPrefix(token: string): string;
/** Redacted form for logs and error messages. Never reveals the secret part. */
declare function maskToken(token: string): string;

/**
 * Convert a money field to a number of VND.
 *
 * Amounts are read back as strings (Prisma `Decimal`) but written as integers.
 * The SDK never coerces silently — call this when you need arithmetic.
 */
declare function toVnd(amount: string | number | null | undefined): number;
/** Format a money field as Vietnamese currency, e.g. `100.000 ₫`. */
declare function formatVnd(amount: string | number | null | undefined): string;

declare class AbortError extends Error {
    readonly name = "AbortError";
    constructor(message?: string);
}

export { API_TOKEN_PREFIX, API_TOKEN_RE, AbortError, ApiTokenScope, Bank, BankAccount, type CreateHmacEndpointParams, type CreateHmacEndpointResult, CreateWebhookSettingParams, DEFAULT_BASE_URL, GpmPay, type GpmPayOptions, type HttpMethod, ListBankAccountsParams, ListParams, type ListTransactionsParams, ListWebhookHistoriesParams, ListWebhookSettingsParams, Page, type PingResult, type RequestLogEvent, RequestOptions, type ResponseLogEvent, SANDBOX_BASE_URL, type SimulateTransactionParams, type SimulatedTransactionResult, type SimulatorOptions, type Transaction, type TransactionDetail, TransactionSource, TransactionType, UpdateWebhookSettingParams, WebhookHistory, WebhookSetting, formatVnd, maskToken, normalizeBaseUrl, toVnd, tokenPrefix };
