@autlantic/payments 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.js ADDED
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AutlanticPayments = void 0;
4
+ const chain_tron_1 = require("@autlantic/chain-tron");
5
+ const payments_core_1 = require("@autlantic/payments-core");
6
+ const from_env_1 = require("./from-env");
7
+ const test_scenarios_1 = require("./test-scenarios");
8
+ const webhook_1 = require("./webhook");
9
+ class AutlanticPayments {
10
+ config;
11
+ constructor(config = {}) {
12
+ this.config = config;
13
+ (0, chain_tron_1.configureTronGrid)({
14
+ apiKey: config.tronGridApiKey,
15
+ maxRetries: config.tronGridMaxRetries,
16
+ });
17
+ }
18
+ /** Construct from environment variables (see `configFromEnv`). */
19
+ static fromEnv(env = process.env) {
20
+ return new AutlanticPayments((0, from_env_1.configFromEnv)(env));
21
+ }
22
+ /** Create a payment intent (store on your order / checkout row). */
23
+ createIntent(input) {
24
+ (0, payments_core_1.assertValidCreatePaymentIntentInput)(input);
25
+ return (0, payments_core_1.createPaymentIntent)(input);
26
+ }
27
+ /**
28
+ * Verify a user-submitted transaction hash against an intent.
29
+ */
30
+ async verifyByTxHash(intent, txHash) {
31
+ const trimmed = txHash.trim();
32
+ if (!trimmed) {
33
+ return {
34
+ ok: false,
35
+ code: "INVALID_TX_HASH",
36
+ message: "Transaction hash is required",
37
+ intent,
38
+ };
39
+ }
40
+ if (!(0, payments_core_1.isValidTronTxHash)(trimmed) && !this.config.sandbox) {
41
+ return {
42
+ ok: false,
43
+ code: "INVALID_TX_HASH",
44
+ message: "Transaction hash must be 64 hexadecimal characters",
45
+ intent,
46
+ };
47
+ }
48
+ if (this.config.sandbox) {
49
+ if (!(0, test_scenarios_1.isSandboxTxHash)(trimmed)) {
50
+ return {
51
+ ok: false,
52
+ code: "SANDBOX_ONLY",
53
+ message: 'Sandbox mode: use a tx hash starting with "sandbox_"',
54
+ intent,
55
+ };
56
+ }
57
+ return (0, test_scenarios_1.verifySandboxPayment)(intent, trimmed);
58
+ }
59
+ const transfer = await (0, chain_tron_1.fetchUsdtTransferByTxHash)(trimmed);
60
+ if (!transfer) {
61
+ return {
62
+ ok: false,
63
+ code: "PAYMENT_TX_NOT_FOUND",
64
+ message: "Could not find a USDT (TRC-20) transfer for this transaction hash",
65
+ intent,
66
+ };
67
+ }
68
+ return (0, payments_core_1.verifyTransferAgainstIntent)((0, payments_core_1.withIntentStatus)(intent, "confirming"), transfer);
69
+ }
70
+ /**
71
+ * Poll the chain for an incoming transfer matching the intent (exact or minimum amount).
72
+ */
73
+ async findMatchingPayment(intent) {
74
+ if (this.config.sandbox) {
75
+ const transfer = (0, test_scenarios_1.sandboxTransferForIntent)(intent, (0, test_scenarios_1.getSandboxScenario)("payment.confirmed").testTxHash, "payment.confirmed");
76
+ const verified = (0, payments_core_1.verifyTransferAgainstIntent)(intent, transfer);
77
+ if (!verified.ok)
78
+ return null;
79
+ return { intent: (0, payments_core_1.withIntentStatus)(intent, "confirmed"), transfer };
80
+ }
81
+ const transfer = await (0, chain_tron_1.findIncomingUsdtPayment)(intent, {
82
+ limit: this.config.incomingPollLimit,
83
+ });
84
+ if (!transfer)
85
+ return null;
86
+ const verified = (0, payments_core_1.verifyTransferAgainstIntent)(intent, transfer);
87
+ if (!verified.ok)
88
+ return null;
89
+ return {
90
+ intent: (0, payments_core_1.withIntentStatus)(intent, "confirmed"),
91
+ transfer,
92
+ };
93
+ }
94
+ /**
95
+ * Verify and return a confirmed event suitable for webhooks / internal handlers.
96
+ */
97
+ async confirmByTxHash(intent, txHash) {
98
+ const result = await this.verifyByTxHash(intent, txHash);
99
+ if (!result.ok)
100
+ return { ok: false, result };
101
+ const confirmedIntent = (0, payments_core_1.withIntentStatus)(result.intent, "confirmed");
102
+ return {
103
+ ok: true,
104
+ event: (0, payments_core_1.toConfirmedEvent)(confirmedIntent, result.transfer),
105
+ transfer: result.transfer,
106
+ };
107
+ }
108
+ /** Sign a webhook body (send as `x-autlantic-signature` header). */
109
+ signWebhook(event) {
110
+ const secret = this.config.webhookSecret;
111
+ if (!secret)
112
+ return null;
113
+ const body = (0, webhook_1.serializeConfirmedEvent)(event);
114
+ return { body, signature: (0, webhook_1.signWebhookPayload)(secret, body) };
115
+ }
116
+ /** Verify an inbound webhook from Autlantic (or your own signed events). */
117
+ verifyWebhook(rawBody, signatureHeader) {
118
+ const secret = this.config.webhookSecret;
119
+ if (!secret)
120
+ return false;
121
+ return (0, webhook_1.verifyWebhookSignature)(secret, rawBody, signatureHeader);
122
+ }
123
+ /** Verify signature and parse `payment.confirmed` payload. */
124
+ parseWebhook(rawBody, signatureHeader) {
125
+ const secret = this.config.webhookSecret;
126
+ if (!secret)
127
+ return null;
128
+ return (0, webhook_1.parseAndVerifyWebhook)(secret, rawBody, signatureHeader);
129
+ }
130
+ /**
131
+ * Stripe-style test harness: run a catalog scenario in sandbox (no TronGrid).
132
+ * Requires `sandbox: true` on the client.
133
+ */
134
+ emitTestEvent(input) {
135
+ this.assertSandboxMode("emitTestEvent");
136
+ return (0, test_scenarios_1.emitSandboxTestEvent)(input, this.config.webhookSecret);
137
+ }
138
+ /** List built-in sandbox scenarios (success + failure paths). */
139
+ listTestScenarios() {
140
+ return (0, test_scenarios_1.listSandboxScenarios)();
141
+ }
142
+ /**
143
+ * Trigger a scenario by id — same as `emitTestEvent` (CLI-friendly alias).
144
+ */
145
+ triggerTestEvent(input) {
146
+ return this.emitTestEvent(input);
147
+ }
148
+ assertSandboxMode(method) {
149
+ if (!this.config.sandbox) {
150
+ throw new Error(`${method} requires sandbox mode. Use new AutlanticPayments({ sandbox: true }) or AUTLANTIC_PAYMENTS_SANDBOX=true.`);
151
+ }
152
+ }
153
+ }
154
+ exports.AutlanticPayments = AutlanticPayments;
@@ -0,0 +1,13 @@
1
+ export type AutlanticPaymentsConfig = {
2
+ /** TronGrid API key (or set TRONGRID_API_KEY env). */
3
+ tronGridApiKey?: string;
4
+ /** Simulate confirmations without hitting the chain. */
5
+ sandbox?: boolean;
6
+ /** Secret for signing outbound webhooks to your app. */
7
+ webhookSecret?: string;
8
+ /** Max TRC-20 rows to scan when polling incoming payments (default 50). */
9
+ incomingPollLimit?: number;
10
+ /** TronGrid retries on 429/5xx (default 2). */
11
+ tronGridMaxRetries?: number;
12
+ };
13
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,uBAAuB,GAAG;IACpC,sDAAsD;IACtD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wDAAwD;IACxD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wDAAwD;IACxD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2EAA2E;IAC3E,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,+CAA+C;IAC/C,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC"}
package/dist/config.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,5 @@
1
+ /** Current SDK release (semver). */
2
+ export declare const AUTLANTIC_PAYMENTS_SDK_VERSION = "0.1.0";
3
+ /** HTTP header for outbound / inbound webhook signatures. */
4
+ export declare const WEBHOOK_SIGNATURE_HEADER = "x-autlantic-signature";
5
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,eAAO,MAAM,8BAA8B,UAAU,CAAC;AAEtD,6DAA6D;AAC7D,eAAO,MAAM,wBAAwB,0BAA0B,CAAC"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WEBHOOK_SIGNATURE_HEADER = exports.AUTLANTIC_PAYMENTS_SDK_VERSION = void 0;
4
+ /** Current SDK release (semver). */
5
+ exports.AUTLANTIC_PAYMENTS_SDK_VERSION = "0.1.0";
6
+ /** HTTP header for outbound / inbound webhook signatures. */
7
+ exports.WEBHOOK_SIGNATURE_HEADER = "x-autlantic-signature";
@@ -0,0 +1,4 @@
1
+ import type { AutlanticPaymentsConfig } from "./config";
2
+ /** Build client config from `process.env` (or a custom env object). */
3
+ export declare function configFromEnv(env?: Record<string, string | undefined>): AutlanticPaymentsConfig;
4
+ //# sourceMappingURL=from-env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"from-env.d.ts","sourceRoot":"","sources":["../src/from-env.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAQxD,uEAAuE;AACvE,wBAAgB,aAAa,CAC3B,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GACpD,uBAAuB,CAgBzB"}
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.configFromEnv = configFromEnv;
4
+ function envFlag(value) {
5
+ if (!value)
6
+ return false;
7
+ const v = value.trim().toLowerCase();
8
+ return v === "1" || v === "true" || v === "yes";
9
+ }
10
+ /** Build client config from `process.env` (or a custom env object). */
11
+ function configFromEnv(env = process.env) {
12
+ return {
13
+ tronGridApiKey: env.TRONGRID_API_KEY?.trim() || undefined,
14
+ sandbox: envFlag(env.AUTLANTIC_PAYMENTS_SANDBOX) || envFlag(env.AUTLANTIC_PAYMENTS_TEST_MODE),
15
+ webhookSecret: env.AUTLANTIC_PAYMENTS_WEBHOOK_SECRET?.trim() ||
16
+ env.AUTLANTIC_WEBHOOK_SECRET?.trim() ||
17
+ undefined,
18
+ incomingPollLimit: env.AUTLANTIC_PAYMENTS_POLL_LIMIT
19
+ ? Number(env.AUTLANTIC_PAYMENTS_POLL_LIMIT)
20
+ : undefined,
21
+ tronGridMaxRetries: env.AUTLANTIC_TRONGRID_MAX_RETRIES
22
+ ? Number(env.AUTLANTIC_TRONGRID_MAX_RETRIES)
23
+ : undefined,
24
+ };
25
+ }
@@ -0,0 +1,9 @@
1
+ export { AutlanticPayments } from "./client";
2
+ export type { AutlanticPaymentsConfig } from "./config";
3
+ export { configFromEnv } from "./from-env";
4
+ export { AUTLANTIC_PAYMENTS_SDK_VERSION, WEBHOOK_SIGNATURE_HEADER, } from "./constants";
5
+ export { signWebhookPayload, verifyWebhookSignature, serializeConfirmedEvent, parseConfirmedWebhookEvent, parseAndVerifyWebhook, } from "./webhook";
6
+ export { SANDBOX_TX_PREFIX, SANDBOX_SCENARIOS, emitSandboxTestEvent, getSandboxScenario, isSandboxTxHash, listSandboxScenarios, resolveSandboxScenario, sandboxTransferForIntent, verifySandboxPayment, type EmitTestEventInput, type EmitTestEventResult, type SandboxScenario, type SandboxScenarioId, } from "./test-scenarios";
7
+ export * from "@autlantic/payments-core";
8
+ export { configureTronGrid, fetchUsdtTransferByTxHash, findIncomingUsdtPayment, findExactUsdtIncomingPayment, findMatchingIncomingRow, USDT_TRC20_CONTRACT, type FindIncomingOptions, type Trc20IncomingRow, } from "@autlantic/chain-tron";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,YAAY,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EACL,8BAA8B,EAC9B,wBAAwB,GACzB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,EACxB,oBAAoB,EACpB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,iBAAiB,GACvB,MAAM,kBAAkB,CAAC;AAE1B,cAAc,0BAA0B,CAAC;AACzC,OAAO,EACL,iBAAiB,EACjB,yBAAyB,EACzB,uBAAuB,EACvB,4BAA4B,EAC5B,uBAAuB,EACvB,mBAAmB,EACnB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,GACtB,MAAM,uBAAuB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.USDT_TRC20_CONTRACT = exports.findMatchingIncomingRow = exports.findExactUsdtIncomingPayment = exports.findIncomingUsdtPayment = exports.fetchUsdtTransferByTxHash = exports.configureTronGrid = exports.verifySandboxPayment = exports.sandboxTransferForIntent = exports.resolveSandboxScenario = exports.listSandboxScenarios = exports.isSandboxTxHash = exports.getSandboxScenario = exports.emitSandboxTestEvent = exports.SANDBOX_SCENARIOS = exports.SANDBOX_TX_PREFIX = exports.parseAndVerifyWebhook = exports.parseConfirmedWebhookEvent = exports.serializeConfirmedEvent = exports.verifyWebhookSignature = exports.signWebhookPayload = exports.WEBHOOK_SIGNATURE_HEADER = exports.AUTLANTIC_PAYMENTS_SDK_VERSION = exports.configFromEnv = exports.AutlanticPayments = void 0;
18
+ var client_1 = require("./client");
19
+ Object.defineProperty(exports, "AutlanticPayments", { enumerable: true, get: function () { return client_1.AutlanticPayments; } });
20
+ var from_env_1 = require("./from-env");
21
+ Object.defineProperty(exports, "configFromEnv", { enumerable: true, get: function () { return from_env_1.configFromEnv; } });
22
+ var constants_1 = require("./constants");
23
+ Object.defineProperty(exports, "AUTLANTIC_PAYMENTS_SDK_VERSION", { enumerable: true, get: function () { return constants_1.AUTLANTIC_PAYMENTS_SDK_VERSION; } });
24
+ Object.defineProperty(exports, "WEBHOOK_SIGNATURE_HEADER", { enumerable: true, get: function () { return constants_1.WEBHOOK_SIGNATURE_HEADER; } });
25
+ var webhook_1 = require("./webhook");
26
+ Object.defineProperty(exports, "signWebhookPayload", { enumerable: true, get: function () { return webhook_1.signWebhookPayload; } });
27
+ Object.defineProperty(exports, "verifyWebhookSignature", { enumerable: true, get: function () { return webhook_1.verifyWebhookSignature; } });
28
+ Object.defineProperty(exports, "serializeConfirmedEvent", { enumerable: true, get: function () { return webhook_1.serializeConfirmedEvent; } });
29
+ Object.defineProperty(exports, "parseConfirmedWebhookEvent", { enumerable: true, get: function () { return webhook_1.parseConfirmedWebhookEvent; } });
30
+ Object.defineProperty(exports, "parseAndVerifyWebhook", { enumerable: true, get: function () { return webhook_1.parseAndVerifyWebhook; } });
31
+ var test_scenarios_1 = require("./test-scenarios");
32
+ Object.defineProperty(exports, "SANDBOX_TX_PREFIX", { enumerable: true, get: function () { return test_scenarios_1.SANDBOX_TX_PREFIX; } });
33
+ Object.defineProperty(exports, "SANDBOX_SCENARIOS", { enumerable: true, get: function () { return test_scenarios_1.SANDBOX_SCENARIOS; } });
34
+ Object.defineProperty(exports, "emitSandboxTestEvent", { enumerable: true, get: function () { return test_scenarios_1.emitSandboxTestEvent; } });
35
+ Object.defineProperty(exports, "getSandboxScenario", { enumerable: true, get: function () { return test_scenarios_1.getSandboxScenario; } });
36
+ Object.defineProperty(exports, "isSandboxTxHash", { enumerable: true, get: function () { return test_scenarios_1.isSandboxTxHash; } });
37
+ Object.defineProperty(exports, "listSandboxScenarios", { enumerable: true, get: function () { return test_scenarios_1.listSandboxScenarios; } });
38
+ Object.defineProperty(exports, "resolveSandboxScenario", { enumerable: true, get: function () { return test_scenarios_1.resolveSandboxScenario; } });
39
+ Object.defineProperty(exports, "sandboxTransferForIntent", { enumerable: true, get: function () { return test_scenarios_1.sandboxTransferForIntent; } });
40
+ Object.defineProperty(exports, "verifySandboxPayment", { enumerable: true, get: function () { return test_scenarios_1.verifySandboxPayment; } });
41
+ __exportStar(require("@autlantic/payments-core"), exports);
42
+ var chain_tron_1 = require("@autlantic/chain-tron");
43
+ Object.defineProperty(exports, "configureTronGrid", { enumerable: true, get: function () { return chain_tron_1.configureTronGrid; } });
44
+ Object.defineProperty(exports, "fetchUsdtTransferByTxHash", { enumerable: true, get: function () { return chain_tron_1.fetchUsdtTransferByTxHash; } });
45
+ Object.defineProperty(exports, "findIncomingUsdtPayment", { enumerable: true, get: function () { return chain_tron_1.findIncomingUsdtPayment; } });
46
+ Object.defineProperty(exports, "findExactUsdtIncomingPayment", { enumerable: true, get: function () { return chain_tron_1.findExactUsdtIncomingPayment; } });
47
+ Object.defineProperty(exports, "findMatchingIncomingRow", { enumerable: true, get: function () { return chain_tron_1.findMatchingIncomingRow; } });
48
+ Object.defineProperty(exports, "USDT_TRC20_CONTRACT", { enumerable: true, get: function () { return chain_tron_1.USDT_TRC20_CONTRACT; } });
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @deprecated Import from `./test-scenarios` — re-exported for compatibility.
3
+ */
4
+ export { SANDBOX_TX_PREFIX, SANDBOX_SCENARIOS, emitSandboxTestEvent, getSandboxScenario, isSandboxTxHash, listSandboxScenarios, resolveSandboxScenario, sandboxTransferForIntent, verifySandboxPayment, type EmitTestEventInput, type EmitTestEventResult, type SandboxScenario, type SandboxScenarioId, } from "./test-scenarios";
5
+ //# sourceMappingURL=sandbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../src/sandbox.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,EACxB,oBAAoB,EACpB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,iBAAiB,GACvB,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.verifySandboxPayment = exports.sandboxTransferForIntent = exports.resolveSandboxScenario = exports.listSandboxScenarios = exports.isSandboxTxHash = exports.getSandboxScenario = exports.emitSandboxTestEvent = exports.SANDBOX_SCENARIOS = exports.SANDBOX_TX_PREFIX = void 0;
4
+ /**
5
+ * @deprecated Import from `./test-scenarios` — re-exported for compatibility.
6
+ */
7
+ var test_scenarios_1 = require("./test-scenarios");
8
+ Object.defineProperty(exports, "SANDBOX_TX_PREFIX", { enumerable: true, get: function () { return test_scenarios_1.SANDBOX_TX_PREFIX; } });
9
+ Object.defineProperty(exports, "SANDBOX_SCENARIOS", { enumerable: true, get: function () { return test_scenarios_1.SANDBOX_SCENARIOS; } });
10
+ Object.defineProperty(exports, "emitSandboxTestEvent", { enumerable: true, get: function () { return test_scenarios_1.emitSandboxTestEvent; } });
11
+ Object.defineProperty(exports, "getSandboxScenario", { enumerable: true, get: function () { return test_scenarios_1.getSandboxScenario; } });
12
+ Object.defineProperty(exports, "isSandboxTxHash", { enumerable: true, get: function () { return test_scenarios_1.isSandboxTxHash; } });
13
+ Object.defineProperty(exports, "listSandboxScenarios", { enumerable: true, get: function () { return test_scenarios_1.listSandboxScenarios; } });
14
+ Object.defineProperty(exports, "resolveSandboxScenario", { enumerable: true, get: function () { return test_scenarios_1.resolveSandboxScenario; } });
15
+ Object.defineProperty(exports, "sandboxTransferForIntent", { enumerable: true, get: function () { return test_scenarios_1.sandboxTransferForIntent; } });
16
+ Object.defineProperty(exports, "verifySandboxPayment", { enumerable: true, get: function () { return test_scenarios_1.verifySandboxPayment; } });
@@ -0,0 +1,48 @@
1
+ import { type CreatePaymentIntentInput, type OnChainTransfer, type PaymentConfirmedEvent, type PaymentFailureCode, type PaymentIntent, type PaymentVerificationResult } from "@autlantic/payments-core";
2
+ import { WEBHOOK_SIGNATURE_HEADER } from "./constants";
3
+ export declare const SANDBOX_TX_PREFIX = "sandbox_";
4
+ /** Stripe-style test scenario ids. */
5
+ export type SandboxScenarioId = "payment.confirmed" | "payment.failed.short" | "payment.failed.expired" | "payment.failed.wrong_address" | "payment.failed.too_early" | "payment.failed.tx_not_found" | "payment.failed.invalid_hash";
6
+ export type SandboxScenario = {
7
+ id: SandboxScenarioId;
8
+ /** Human label for docs / CLI */
9
+ label: string;
10
+ description: string;
11
+ /** Use this as `txHash` in sandbox `verifyByTxHash` */
12
+ testTxHash: string;
13
+ /** Webhook `event.type` when applicable */
14
+ eventType: string;
15
+ expectsSuccess: boolean;
16
+ expectedCode?: PaymentFailureCode;
17
+ };
18
+ /** Catalog of sandbox test cases (like Stripe test cards). */
19
+ export declare const SANDBOX_SCENARIOS: SandboxScenario[];
20
+ export declare function isSandboxTxHash(txHash: string): boolean;
21
+ export declare function getSandboxScenario(id: SandboxScenarioId): SandboxScenario;
22
+ export declare function listSandboxScenarios(): SandboxScenario[];
23
+ export declare function resolveSandboxScenario(txHash: string): SandboxScenarioId | null;
24
+ /** Unique per checkout (merchantRef) so sandbox test txs do not collide in @unique txHash columns. */
25
+ export declare function sandboxStoredTxHash(intent: PaymentIntent, inputTxHash: string): string;
26
+ export declare function sandboxTransferForIntent(intent: PaymentIntent, txHash: string, scenarioId?: SandboxScenarioId): OnChainTransfer;
27
+ export declare function verifySandboxPayment(intent: PaymentIntent, txHash: string): PaymentVerificationResult;
28
+ export type EmitTestEventInput = {
29
+ scenario: SandboxScenarioId;
30
+ merchantRef: string;
31
+ amountUsdt: number;
32
+ payToAddress: string;
33
+ expiresAt?: Date;
34
+ matchStrategy?: CreatePaymentIntentInput["matchStrategy"];
35
+ };
36
+ export type EmitTestEventResult = {
37
+ scenario: SandboxScenario;
38
+ intent: PaymentIntent;
39
+ verification: PaymentVerificationResult;
40
+ event?: PaymentConfirmedEvent;
41
+ webhook?: {
42
+ body: string;
43
+ signature: string;
44
+ headerName: typeof WEBHOOK_SIGNATURE_HEADER;
45
+ };
46
+ };
47
+ export declare function emitSandboxTestEvent(input: EmitTestEventInput, webhookSecret?: string): EmitTestEventResult;
48
+ //# sourceMappingURL=test-scenarios.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-scenarios.d.ts","sourceRoot":"","sources":["../src/test-scenarios.ts"],"names":[],"mappings":"AACA,OAAO,EAOL,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,yBAAyB,EAC/B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAGvD,eAAO,MAAM,iBAAiB,aAAa,CAAC;AAE5C,sCAAsC;AACtC,MAAM,MAAM,iBAAiB,GACzB,mBAAmB,GACnB,sBAAsB,GACtB,wBAAwB,GACxB,8BAA8B,GAC9B,0BAA0B,GAC1B,6BAA6B,GAC7B,6BAA6B,CAAC;AAElC,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,iBAAiB,CAAC;IACtB,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,kBAAkB,CAAC;CACnC,CAAC;AAEF,8DAA8D;AAC9D,eAAO,MAAM,iBAAiB,EAAE,eAAe,EA+D9C,CAAC;AA2BF,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,iBAAiB,GAAG,eAAe,CAIzE;AAED,wBAAgB,oBAAoB,IAAI,eAAe,EAAE,CAExD;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAS/E;AAED,sGAAsG;AACtG,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAItF;AAID,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,MAAM,EACd,UAAU,GAAE,iBAAuC,GAClD,eAAe,CA2CjB;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,MAAM,GACb,yBAAyB,CAwC3B;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,aAAa,CAAC,EAAE,wBAAwB,CAAC,eAAe,CAAC,CAAC;CAC3D,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,EAAE,eAAe,CAAC;IAC1B,MAAM,EAAE,aAAa,CAAC;IACtB,YAAY,EAAE,yBAAyB,CAAC;IACxC,KAAK,CAAC,EAAE,qBAAqB,CAAC;IAC9B,OAAO,CAAC,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,OAAO,wBAAwB,CAAC;KAC7C,CAAC;CACH,CAAC;AAEF,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,kBAAkB,EACzB,aAAa,CAAC,EAAE,MAAM,GACrB,mBAAmB,CA6BrB"}
@@ -0,0 +1,235 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SANDBOX_SCENARIOS = exports.SANDBOX_TX_PREFIX = void 0;
4
+ exports.isSandboxTxHash = isSandboxTxHash;
5
+ exports.getSandboxScenario = getSandboxScenario;
6
+ exports.listSandboxScenarios = listSandboxScenarios;
7
+ exports.resolveSandboxScenario = resolveSandboxScenario;
8
+ exports.sandboxStoredTxHash = sandboxStoredTxHash;
9
+ exports.sandboxTransferForIntent = sandboxTransferForIntent;
10
+ exports.verifySandboxPayment = verifySandboxPayment;
11
+ exports.emitSandboxTestEvent = emitSandboxTestEvent;
12
+ const node_crypto_1 = require("node:crypto");
13
+ const payments_core_1 = require("@autlantic/payments-core");
14
+ const constants_1 = require("./constants");
15
+ const webhook_1 = require("./webhook");
16
+ exports.SANDBOX_TX_PREFIX = "sandbox_";
17
+ /** Catalog of sandbox test cases (like Stripe test cards). */
18
+ exports.SANDBOX_SCENARIOS = [
19
+ {
20
+ id: "payment.confirmed",
21
+ label: "Successful USDT payment",
22
+ description: "Payment meets amount and address; emits payment.confirmed.",
23
+ testTxHash: "sandbox_payment_confirmed",
24
+ eventType: "payment.confirmed",
25
+ expectsSuccess: true,
26
+ },
27
+ {
28
+ id: "payment.failed.short",
29
+ label: "Underpayment",
30
+ description: "On-chain amount below checkout requirement.",
31
+ testTxHash: "sandbox_payment_short",
32
+ eventType: "payment.failed",
33
+ expectsSuccess: false,
34
+ expectedCode: "PAYMENT_SHORT",
35
+ },
36
+ {
37
+ id: "payment.failed.expired",
38
+ label: "Expired checkout",
39
+ description: "Checkout session past expiresAt.",
40
+ testTxHash: "sandbox_payment_expired",
41
+ eventType: "payment.failed",
42
+ expectsSuccess: false,
43
+ expectedCode: "PAYMENT_EXPIRED",
44
+ },
45
+ {
46
+ id: "payment.failed.wrong_address",
47
+ label: "Wrong payout wallet",
48
+ description: "USDT sent to a different address than the intent.",
49
+ testTxHash: "sandbox_payment_wrong_address",
50
+ eventType: "payment.failed",
51
+ expectsSuccess: false,
52
+ expectedCode: "PAYMENT_WRONG_ADDRESS",
53
+ },
54
+ {
55
+ id: "payment.failed.too_early",
56
+ label: "Transaction too early",
57
+ description: "Transfer before checkout session (outside grace window).",
58
+ testTxHash: "sandbox_payment_too_early",
59
+ eventType: "payment.failed",
60
+ expectsSuccess: false,
61
+ expectedCode: "PAYMENT_TOO_EARLY",
62
+ },
63
+ {
64
+ id: "payment.failed.tx_not_found",
65
+ label: "Transaction not found",
66
+ description: "No USDT transfer for this hash (simulated).",
67
+ testTxHash: "sandbox_payment_not_found",
68
+ eventType: "payment.failed",
69
+ expectsSuccess: false,
70
+ expectedCode: "PAYMENT_TX_NOT_FOUND",
71
+ },
72
+ {
73
+ id: "payment.failed.invalid_hash",
74
+ label: "Invalid transaction hash",
75
+ description: "Malformed tx id (not 64 hex in production rules).",
76
+ testTxHash: "sandbox_payment_invalid_hash",
77
+ eventType: "payment.failed",
78
+ expectsSuccess: false,
79
+ expectedCode: "INVALID_TX_HASH",
80
+ },
81
+ ];
82
+ const SCENARIO_BY_ID = new Map(exports.SANDBOX_SCENARIOS.map((s) => [s.id, s]));
83
+ const TX_ALIASES = {
84
+ sandbox_payment_confirmed: "payment.confirmed",
85
+ sandbox_payment_short: "payment.failed.short",
86
+ sandbox_payment_expired: "payment.failed.expired",
87
+ sandbox_payment_wrong_address: "payment.failed.wrong_address",
88
+ sandbox_payment_too_early: "payment.failed.too_early",
89
+ sandbox_payment_not_found: "payment.failed.tx_not_found",
90
+ sandbox_payment_invalid_hash: "payment.failed.invalid_hash",
91
+ sandbox_confirm: "payment.confirmed",
92
+ sandbox_confirm_test: "payment.confirmed",
93
+ sandbox_success: "payment.confirmed",
94
+ sandbox_paid: "payment.confirmed",
95
+ sandbox_payer_submitted_tx: "payment.confirmed",
96
+ sandbox_underpay: "payment.failed.short",
97
+ sandbox_short: "payment.failed.short",
98
+ sandbox_expired: "payment.failed.expired",
99
+ sandbox_wrong_address: "payment.failed.wrong_address",
100
+ sandbox_too_early: "payment.failed.too_early",
101
+ sandbox_not_found: "payment.failed.tx_not_found",
102
+ sandbox_tx_not_found: "payment.failed.tx_not_found",
103
+ sandbox_invalid_hash: "payment.failed.invalid_hash",
104
+ };
105
+ function isSandboxTxHash(txHash) {
106
+ return txHash.trim().toLowerCase().startsWith(exports.SANDBOX_TX_PREFIX);
107
+ }
108
+ function getSandboxScenario(id) {
109
+ const scenario = SCENARIO_BY_ID.get(id);
110
+ if (!scenario)
111
+ throw new Error(`Unknown sandbox scenario: ${id}`);
112
+ return scenario;
113
+ }
114
+ function listSandboxScenarios() {
115
+ return [...exports.SANDBOX_SCENARIOS];
116
+ }
117
+ function resolveSandboxScenario(txHash) {
118
+ if (!isSandboxTxHash(txHash))
119
+ return null;
120
+ const key = txHash.trim().toLowerCase();
121
+ if (TX_ALIASES[key])
122
+ return TX_ALIASES[key];
123
+ for (const scenario of exports.SANDBOX_SCENARIOS) {
124
+ if (scenario.testTxHash === key)
125
+ return scenario.id;
126
+ }
127
+ /** Legacy: any other sandbox_* tx succeeds */
128
+ return "payment.confirmed";
129
+ }
130
+ /** Unique per checkout (merchantRef) so sandbox test txs do not collide in @unique txHash columns. */
131
+ function sandboxStoredTxHash(intent, inputTxHash) {
132
+ return (0, node_crypto_1.createHash)("sha256")
133
+ .update(`${inputTxHash.trim().toLowerCase()}|${intent.merchantRef}`)
134
+ .digest("hex");
135
+ }
136
+ const SANDBOX_ALT_PAYOUT = "TJXZEpXAzQD9s7YhfHwdCNJYwVf3fWmXnA";
137
+ function sandboxTransferForIntent(intent, txHash, scenarioId = "payment.confirmed") {
138
+ const hash = sandboxStoredTxHash(intent, txHash);
139
+ const base = {
140
+ txHash: hash,
141
+ fromAddress: "TLyqzVGLV1srkB7dToTAEqgDSfPtXRJZYH",
142
+ token: "USDT_TRC20",
143
+ network: "tron",
144
+ blockTimestamp: intent.createdAt.getTime() + 5_000,
145
+ };
146
+ switch (scenarioId) {
147
+ case "payment.failed.short":
148
+ return {
149
+ ...base,
150
+ toAddress: intent.payToAddress,
151
+ amountUsdt: Math.max(0.000001, intent.amount.valueUsdt - 1),
152
+ amountMicro: BigInt(Math.round(Math.max(0.000001, intent.amount.valueUsdt - 1) * 1_000_000)),
153
+ };
154
+ case "payment.failed.wrong_address":
155
+ return {
156
+ ...base,
157
+ toAddress: SANDBOX_ALT_PAYOUT,
158
+ amountUsdt: intent.amount.valueUsdt,
159
+ amountMicro: BigInt(Math.round(intent.amount.valueUsdt * 1_000_000)),
160
+ };
161
+ case "payment.failed.too_early":
162
+ return {
163
+ ...base,
164
+ toAddress: intent.payToAddress,
165
+ amountUsdt: intent.amount.valueUsdt,
166
+ amountMicro: BigInt(Math.round(intent.amount.valueUsdt * 1_000_000)),
167
+ blockTimestamp: intent.createdAt.getTime() - payments_core_1.ORDER_TIME_GRACE_MS - 60_000,
168
+ };
169
+ default:
170
+ return {
171
+ ...base,
172
+ toAddress: intent.payToAddress,
173
+ amountUsdt: intent.amount.valueUsdt,
174
+ amountMicro: BigInt(Math.round(intent.amount.valueUsdt * 1_000_000)),
175
+ };
176
+ }
177
+ }
178
+ function verifySandboxPayment(intent, txHash) {
179
+ if (!isSandboxTxHash(txHash)) {
180
+ return {
181
+ ok: false,
182
+ code: "SANDBOX_ONLY",
183
+ message: `Sandbox mode: use a tx hash starting with "${exports.SANDBOX_TX_PREFIX}"`,
184
+ intent,
185
+ };
186
+ }
187
+ const scenarioId = resolveSandboxScenario(txHash);
188
+ if (scenarioId === "payment.failed.invalid_hash") {
189
+ return {
190
+ ok: false,
191
+ code: "INVALID_TX_HASH",
192
+ message: (0, payments_core_1.failureMessageForCode)("INVALID_TX_HASH"),
193
+ intent,
194
+ };
195
+ }
196
+ if (scenarioId === "payment.failed.tx_not_found") {
197
+ return {
198
+ ok: false,
199
+ code: "PAYMENT_TX_NOT_FOUND",
200
+ message: (0, payments_core_1.failureMessageForCode)("PAYMENT_TX_NOT_FOUND"),
201
+ intent,
202
+ };
203
+ }
204
+ const intentForVerify = scenarioId === "payment.failed.expired"
205
+ ? { ...intent, expiresAt: new Date(0) }
206
+ : intent;
207
+ const transfer = sandboxTransferForIntent(intent, txHash, scenarioId);
208
+ return (0, payments_core_1.verifyTransferAgainstIntent)((0, payments_core_1.withIntentStatus)(intentForVerify, "confirming"), transfer);
209
+ }
210
+ function emitSandboxTestEvent(input, webhookSecret) {
211
+ const scenario = getSandboxScenario(input.scenario);
212
+ const intent = (0, payments_core_1.createPaymentIntent)({
213
+ merchantRef: input.merchantRef,
214
+ amountUsdt: input.amountUsdt,
215
+ payToAddress: input.payToAddress,
216
+ matchStrategy: input.matchStrategy ?? "minimum_amount",
217
+ expiresAt: input.expiresAt ?? new Date(Date.now() + 60 * 60 * 1000),
218
+ });
219
+ const verification = verifySandboxPayment(intent, scenario.testTxHash);
220
+ let event;
221
+ let webhook;
222
+ if (verification.ok) {
223
+ const confirmedIntent = (0, payments_core_1.withIntentStatus)(verification.intent, "confirmed");
224
+ event = (0, payments_core_1.toConfirmedEvent)(confirmedIntent, verification.transfer);
225
+ if (webhookSecret) {
226
+ const body = (0, webhook_1.serializeConfirmedEvent)(event);
227
+ webhook = {
228
+ body,
229
+ signature: (0, webhook_1.signWebhookPayload)(webhookSecret, body),
230
+ headerName: constants_1.WEBHOOK_SIGNATURE_HEADER,
231
+ };
232
+ }
233
+ }
234
+ return { scenario, intent, verification, event, webhook };
235
+ }
@@ -0,0 +1,7 @@
1
+ import type { PaymentConfirmedEvent } from "@autlantic/payments-core";
2
+ export declare function signWebhookPayload(secret: string, body: string): string;
3
+ export declare function verifyWebhookSignature(secret: string, rawBody: string, signatureHeader: string | null | undefined): boolean;
4
+ export declare function serializeConfirmedEvent(event: PaymentConfirmedEvent): string;
5
+ export declare function parseConfirmedWebhookEvent(rawBody: string): PaymentConfirmedEvent | null;
6
+ export declare function parseAndVerifyWebhook(secret: string, rawBody: string, signatureHeader: string | null | undefined): PaymentConfirmedEvent | null;
7
+ //# sourceMappingURL=webhook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../src/webhook.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAEtE,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,MAAM,CAER;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACzC,OAAO,CAWT;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,qBAAqB,GAAG,MAAM,CAE5E;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,GACd,qBAAqB,GAAG,IAAI,CAS9B;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACzC,qBAAqB,GAAG,IAAI,CAG9B"}