@gpmpay/sdk
Version:
Official Node.js SDK for GPM Pay — VietQR codes, transaction webhooks, and payment reconciliation.
104 lines (100 loc) • 4.16 kB
text/typescript
import { o as GpmPayWebhookEvent, p as GpmPayWebhookSignatureError } from '../verify-DVgS9Vh1.cjs';
export { D as DEFAULT_TOLERANCE_SECONDS, E as EVENT_HEADER, S as SIGNATURE_HEADER, V as VerifyWebhookInput, t as WebhookPayload, v as assertWebhookSignature, w as constructWebhookEvent, x as signWebhookPayload, z as verifyApiKeyHeader, y as verifyWebhookSignature } from '../verify-DVgS9Vh1.cjs';
export { W as WEBHOOK_DELIVERY_TIMEOUT_MS, f as WEBHOOK_MAX_ATTEMPTS, g as WEBHOOK_RETRY_SCHEDULE_SECONDS } from '../bank-SVz37Xt1.cjs';
/**
* Structurally-typed request. Deliberately not `express.Request` — this package
* has zero dependencies and must not force Express into your tree.
*/
interface MinimalRequest {
headers: Record<string, string | string[] | undefined>;
body?: unknown;
rawBody?: unknown;
}
interface MinimalResponse {
status(code: number): MinimalResponse;
json(body: unknown): unknown;
send(body?: unknown): unknown;
}
type NextFunction = (error?: unknown) => void;
interface GpmpayWebhookOptions {
/** The webhook setting's `authorizationSecret`. */
secret: string;
onEvent: (event: GpmPayWebhookEvent, req: MinimalRequest) => void | Promise<void>;
toleranceSeconds?: number;
/** Defaults to `X-GPMPay-Signature`. */
headerName?: string;
onError?: (error: GpmPayWebhookSignatureError, req: MinimalRequest) => void;
/**
* Respond 200 before awaiting `onEvent`. Default true.
*
* GPM Pay aborts a delivery after 5s and retries on the schedule
* `[10s, 30s, 2m, 10m, 1h, 6h]`, so a slow handler causes duplicate
* processing. Acknowledge fast, work afterwards.
*/
respondEarly?: boolean;
}
/**
* Express-compatible middleware that verifies the signature and hands you a
* typed event.
*
* @example
* app.post(
* '/webhooks/gpmpay',
* express.raw({ type: 'application/json' }),
* gpmpayWebhook({
* secret: process.env.GPMPAY_WEBHOOK_SECRET!,
* onEvent: async (event) => {
* if (event.payload.transferType !== 'in') return;
* const code = /DH(\d+)/.exec(event.payload.content)?.[0];
* if (code) await fulfil(code, event.payload.transferAmount);
* },
* }),
* );
*/
declare function gpmpayWebhook(options: GpmpayWebhookOptions): (req: MinimalRequest, res: MinimalResponse, next: NextFunction) => Promise<void>;
interface NextVerifyOptions {
secret: string;
toleranceSeconds?: number;
/** Defaults to `X-GPMPay-Signature`. */
headerName?: string;
}
/**
* Verify a webhook in a Next.js App Router route handler.
*
* `await request.text()` yields the exact bytes GPM Pay sent, so no special
* body-parser configuration is needed.
*
* @throws {GpmPayWebhookSignatureError}
*/
declare function verifyNextRequest(request: Request, options: NextVerifyOptions): Promise<GpmPayWebhookEvent>;
/**
* A ready-made App Router POST handler.
*
* @example
* // app/api/webhooks/gpmpay/route.ts
* import { createNextWebhookHandler } from '@gpmpay/sdk/webhooks';
*
* export const POST = createNextWebhookHandler({
* secret: process.env.GPMPAY_WEBHOOK_SECRET!,
* onEvent: async (event) => {
* if (event.payload.transferType !== 'in') return;
* const code = /DH(\d+)/.exec(event.payload.content)?.[0];
* if (code) await fulfil(code, event.payload.transferAmount);
* },
* });
*/
declare function createNextWebhookHandler(options: NextVerifyOptions & {
onEvent: (event: GpmPayWebhookEvent) => void | Promise<void>;
}): (request: Request) => Promise<Response>;
/**
* Read a raw body from a stream, for the Pages Router.
*
* Requires disabling the built-in parser:
* ```ts
* export const config = { api: { bodyParser: false } };
* ```
*
* @param maxBytes Guard against unbounded bodies. Default 1 MiB.
*/
declare function readRawBody(stream: AsyncIterable<Uint8Array>, maxBytes?: number): Promise<Buffer>;
export { GpmPayWebhookEvent, GpmPayWebhookSignatureError, type GpmpayWebhookOptions, type MinimalRequest, type MinimalResponse, type NextFunction, type NextVerifyOptions, createNextWebhookHandler, gpmpayWebhook, readRawBody, verifyNextRequest };