@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/API.md +92 -0
- package/CHANGELOG.md +37 -0
- package/LICENSE +21 -0
- package/README.md +170 -0
- package/TESTING.md +140 -0
- package/bin/autlantic-payments.mjs +155 -0
- package/dist/client.d.ts +53 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +154 -0
- package/dist/config.d.ts +13 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +2 -0
- package/dist/constants.d.ts +5 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +7 -0
- package/dist/from-env.d.ts +4 -0
- package/dist/from-env.d.ts.map +1 -0
- package/dist/from-env.js +25 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +48 -0
- package/dist/sandbox.d.ts +5 -0
- package/dist/sandbox.d.ts.map +1 -0
- package/dist/sandbox.js +16 -0
- package/dist/test-scenarios.d.ts +48 -0
- package/dist/test-scenarios.d.ts.map +1 -0
- package/dist/test-scenarios.js +235 -0
- package/dist/webhook.d.ts +7 -0
- package/dist/webhook.d.ts.map +1 -0
- package/dist/webhook.js +47 -0
- package/package.json +65 -0
package/API.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# API reference — @autlantic/payments v0.1
|
|
2
|
+
|
|
3
|
+
## `AutlanticPayments`
|
|
4
|
+
|
|
5
|
+
### Constructor
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
new AutlanticPayments({
|
|
9
|
+
tronGridApiKey?: string;
|
|
10
|
+
sandbox?: boolean;
|
|
11
|
+
webhookSecret?: string;
|
|
12
|
+
incomingPollLimit?: number; // default 50, max 200
|
|
13
|
+
tronGridMaxRetries?: number; // default 2
|
|
14
|
+
});
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### `static fromEnv(env?)`
|
|
18
|
+
|
|
19
|
+
Reads:
|
|
20
|
+
|
|
21
|
+
| Env | Config |
|
|
22
|
+
|-----|--------|
|
|
23
|
+
| `TRONGRID_API_KEY` | `tronGridApiKey` |
|
|
24
|
+
| `AUTLANTIC_PAYMENTS_SANDBOX` or `AUTLANTIC_PAYMENTS_TEST_MODE` | `sandbox` |
|
|
25
|
+
| `AUTLANTIC_PAYMENTS_WEBHOOK_SECRET` | `webhookSecret` |
|
|
26
|
+
| `AUTLANTIC_PAYMENTS_POLL_LIMIT` | `incomingPollLimit` |
|
|
27
|
+
| `AUTLANTIC_TRONGRID_MAX_RETRIES` | `tronGridMaxRetries` |
|
|
28
|
+
|
|
29
|
+
### Methods
|
|
30
|
+
|
|
31
|
+
| Method | Returns | Description |
|
|
32
|
+
|--------|---------|-------------|
|
|
33
|
+
| `createIntent(input)` | `PaymentIntent` | Validates input, creates intent |
|
|
34
|
+
| `verifyByTxHash(intent, txHash)` | `PaymentVerificationResult` | On-chain or sandbox verify |
|
|
35
|
+
| `findMatchingPayment(intent)` | `MatchedPayment \| null` | Poll recent incoming USDT |
|
|
36
|
+
| `confirmByTxHash(intent, txHash)` | `{ ok, event?, transfer? }` | Verify + `payment.confirmed` event |
|
|
37
|
+
| `signWebhook(event)` | `{ body, signature } \| null` | HMAC-SHA256 outbound webhook |
|
|
38
|
+
| `verifyWebhook(body, header)` | `boolean` | Check `x-autlantic-signature` |
|
|
39
|
+
| `parseWebhook(body, header)` | `PaymentConfirmedEvent \| null` | Verify + parse JSON |
|
|
40
|
+
| `emitTestEvent(input)` | `EmitTestEventResult` | Sandbox: run catalog scenario + optional webhook |
|
|
41
|
+
| `triggerTestEvent(input)` | same as `emitTestEvent` | CLI alias |
|
|
42
|
+
| `listTestScenarios()` | `SandboxScenario[]` | All built-in test cases |
|
|
43
|
+
|
|
44
|
+
### Sandbox scenario ids
|
|
45
|
+
|
|
46
|
+
`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`
|
|
47
|
+
|
|
48
|
+
See [TESTING.md](./TESTING.md).
|
|
49
|
+
|
|
50
|
+
## Core types (`@autlantic/payments-core`)
|
|
51
|
+
|
|
52
|
+
- `PaymentIntent`, `CreatePaymentIntentInput`
|
|
53
|
+
- `PaymentMatchStrategy`: `"minimum_amount"` \| `"exact_amount"`
|
|
54
|
+
- `PaymentFailureCode` — see `PAYMENT_FAILURE_CODES`, `failureMessageForCode()`
|
|
55
|
+
- `verifyTransferAgainstIntent(intent, transfer)` — pure, no I/O
|
|
56
|
+
- `defaultCheckoutExpiresAt(hours?)`, `defaultMatchStrategy()`
|
|
57
|
+
- `isValidTronTxHash`, `validatePayToAddress`
|
|
58
|
+
- `isVerificationSuccess` / `isVerificationFailure`
|
|
59
|
+
|
|
60
|
+
## Chain (`@autlantic/chain-tron`)
|
|
61
|
+
|
|
62
|
+
- `fetchUsdtTransferByTxHash(txHash)`
|
|
63
|
+
- `findIncomingUsdtPayment(intent, { limit? })`
|
|
64
|
+
- `findMatchingIncomingRow(rows, intent)` — pure filter
|
|
65
|
+
- `configureTronGrid({ apiKey, fetchImpl, maxRetries, retryDelayMs })`
|
|
66
|
+
|
|
67
|
+
## Webhook event
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"type": "payment.confirmed",
|
|
72
|
+
"intentId": "pi_…",
|
|
73
|
+
"merchantRef": "order_123",
|
|
74
|
+
"txHash": "…",
|
|
75
|
+
"amountUsdt": 20,
|
|
76
|
+
"payToAddress": "T…",
|
|
77
|
+
"blockTimestamp": 1700000000000,
|
|
78
|
+
"observedAt": "2026-05-22T12:00:00.000Z"
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Header: `x-autlantic-signature` (hex HMAC-SHA256 of raw body).
|
|
83
|
+
|
|
84
|
+
## CLI
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
pnpm build:sdk
|
|
88
|
+
pnpm --filter @autlantic/payments exec autlantic-payments sandbox \
|
|
89
|
+
--merchant-ref demo --amount 20 \
|
|
90
|
+
--to TLyqzVGLV1srkB7dToTAEqgDSfPtXRJZYH \
|
|
91
|
+
--tx sandbox_cli_test
|
|
92
|
+
```
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0 — 2026-05-22 (complete + distribution)
|
|
4
|
+
|
|
5
|
+
### Distribution
|
|
6
|
+
|
|
7
|
+
- npm publish ready (`publishConfig`, MIT, dist-only exports) — see [PUBLISHING.md](../PUBLISHING.md)
|
|
8
|
+
- Hosted HTTP API: `apps/payments-api` (`/v1/intents`, `/v1/payments/verify`, API key auth)
|
|
9
|
+
|
|
10
|
+
## 0.1.0 — 2026-05-22 (complete)
|
|
11
|
+
|
|
12
|
+
### Added (final)
|
|
13
|
+
|
|
14
|
+
- `AutlanticPayments.fromEnv()` / `configFromEnv()`
|
|
15
|
+
- `parseWebhook`, `parseConfirmedWebhookEvent`, `parseAndVerifyWebhook`
|
|
16
|
+
- CLI: `autlantic-payments` (`verify` / `sandbox`)
|
|
17
|
+
- `API.md`, `SECURITY.md`, `AUTLANTIC_PAYMENTS_SDK_VERSION`
|
|
18
|
+
- TronGrid retry on 429/5xx; configurable poll limit
|
|
19
|
+
- `PAYMENT_FAILURE_CODES`, `defaultCheckoutExpiresAt`, `defaultMatchStrategy`
|
|
20
|
+
|
|
21
|
+
## 0.1.0 — 2026-05-22
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- `@autlantic/payments-core` — intents, USDT amounts, verify rules, type guards, tx/address validation
|
|
26
|
+
- `@autlantic/chain-tron` — TronGrid client, TRC-20 fetch by tx hash, incoming payment match, mockable fetch
|
|
27
|
+
- `@autlantic/payments` — `AutlanticPayments` client, sandbox mode, webhook sign/verify
|
|
28
|
+
- Match strategies: `exact_amount`, `minimum_amount`
|
|
29
|
+
- `validateCreatePaymentIntentInput`, `isValidTronTxHash`, `PaymentError`
|
|
30
|
+
- Standalone test suite (`pnpm test:sdk`) — 35+ tests, no network
|
|
31
|
+
- Examples: `example`, `example:merchant`
|
|
32
|
+
- Optional live TronGrid test (`TRONGRID_INTEGRATION=1`)
|
|
33
|
+
- Umbrella doc: [packages/SDK.md](../SDK.md)
|
|
34
|
+
|
|
35
|
+
### Notes
|
|
36
|
+
|
|
37
|
+
- v0.1 is monorepo-private; npm publish planned separately.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Autlantic
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# @autlantic/payments
|
|
2
|
+
|
|
3
|
+
Autlantic Payments SDK — verify **USDT (TRC-20)** on **TRON** for merchant checkouts.
|
|
4
|
+
|
|
5
|
+
Standalone library: use in any Node app. Optional integration with the Autlantic product is a separate step.
|
|
6
|
+
|
|
7
|
+
## Packages
|
|
8
|
+
|
|
9
|
+
| Package | Role |
|
|
10
|
+
|---------|------|
|
|
11
|
+
| [`@autlantic/payments-core`](../payments-core) | Types, intents, pure verify (no I/O) |
|
|
12
|
+
| [`@autlantic/chain-tron`](../chain-tron) | TronGrid + TRC-20 USDT |
|
|
13
|
+
| `@autlantic/payments` | `AutlanticPayments` client, sandbox, webhooks |
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @autlantic/payments
|
|
19
|
+
# monorepo: pnpm add @autlantic/payments@workspace:*
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Publish / scope setup: [PUBLISHING.md](../PUBLISHING.md)
|
|
23
|
+
|
|
24
|
+
## Hosted API (no Node SDK required)
|
|
25
|
+
|
|
26
|
+
Deploy or run [apps/payments-api](../../apps/payments-api/README.md):
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pnpm dev:payments-api
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Use `X-Autlantic-Api-Key` + REST (`/v1/intents`, `/v1/payments/verify`, …).
|
|
33
|
+
|
|
34
|
+
## Quickstart
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import { AutlanticPayments } from "@autlantic/payments";
|
|
38
|
+
|
|
39
|
+
const payments = new AutlanticPayments({
|
|
40
|
+
tronGridApiKey: process.env.TRONGRID_API_KEY,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const intent = payments.createIntent({
|
|
44
|
+
merchantRef: order.id,
|
|
45
|
+
amountUsdt: 20,
|
|
46
|
+
payToAddress: creator.payoutAddressTron,
|
|
47
|
+
matchStrategy: "minimum_amount",
|
|
48
|
+
expiresAt: new Date(Date.now() + 60 * 60 * 1000),
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const result = await payments.verifyByTxHash(intent, txHashFromUser);
|
|
52
|
+
if (result.ok) {
|
|
53
|
+
await markOrderPaid(order.id, result.transfer.txHash);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const match = await payments.findMatchingPayment(intent);
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Sandbox & test events (Stripe-style)
|
|
60
|
+
|
|
61
|
+
Full guide: **[TESTING.md](./TESTING.md)**
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
const payments = new AutlanticPayments({ sandbox: true, webhookSecret: "whsec_test" });
|
|
65
|
+
|
|
66
|
+
// Test tx hashes (like Stripe test cards)
|
|
67
|
+
await payments.verifyByTxHash(intent, "sandbox_payment_confirmed");
|
|
68
|
+
await payments.verifyByTxHash(intent, "sandbox_payment_short"); // → PAYMENT_SHORT
|
|
69
|
+
|
|
70
|
+
// Trigger events (like stripe trigger)
|
|
71
|
+
const out = payments.emitTestEvent({
|
|
72
|
+
scenario: "payment.confirmed",
|
|
73
|
+
merchantRef: "order_1",
|
|
74
|
+
amountUsdt: 20,
|
|
75
|
+
payToAddress: "TLyqzVGLV1srkB7dToTAEqgDSfPtXRJZYH",
|
|
76
|
+
});
|
|
77
|
+
// out.event, out.webhook for your handler
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Run the demo:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
pnpm example:sdk
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Match strategies
|
|
87
|
+
|
|
88
|
+
| Strategy | Use case |
|
|
89
|
+
|----------|----------|
|
|
90
|
+
| `minimum_amount` | Plan price (e.g. 20 USDT); overpay OK |
|
|
91
|
+
| `exact_amount` | Micro-unit exact match (legacy) |
|
|
92
|
+
|
|
93
|
+
## Webhooks
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
const payments = new AutlanticPayments({ webhookSecret: process.env.WEBHOOK_SECRET });
|
|
97
|
+
const out = await payments.confirmByTxHash(intent, txHash);
|
|
98
|
+
if (out.ok) {
|
|
99
|
+
const signed = payments.signWebhook(out.event);
|
|
100
|
+
// POST signed.body, header: x-autlantic-signature
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Inbound: `verifyWebhookSignature(secret, rawBody, header)`.
|
|
105
|
+
|
|
106
|
+
## API surface
|
|
107
|
+
|
|
108
|
+
| Method | Description |
|
|
109
|
+
|--------|-------------|
|
|
110
|
+
| `createIntent(input)` | Build `PaymentIntent` for checkout |
|
|
111
|
+
| `verifyByTxHash(intent, hash)` | Verify pasted Tron tx |
|
|
112
|
+
| `findMatchingPayment(intent)` | Poll recent incoming USDT |
|
|
113
|
+
| `confirmByTxHash(intent, hash)` | Verify + `payment.confirmed` event |
|
|
114
|
+
| `signWebhook(event)` | HMAC-SHA256 body + signature |
|
|
115
|
+
|
|
116
|
+
Re-exported from core/chain: `createPaymentIntent`, `verifyTransferAgainstIntent`, `fetchUsdtTransferByTxHash`, type guards, etc.
|
|
117
|
+
|
|
118
|
+
## Tests
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
pnpm test:sdk # all packages (no network)
|
|
122
|
+
pnpm example:sdk # sandbox demo script
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Per package: `pnpm --filter @autlantic/payments-core test`
|
|
126
|
+
|
|
127
|
+
### Optional live TronGrid test
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
TRONGRID_INTEGRATION=1 \
|
|
131
|
+
TRONGRID_API_KEY=your_key \
|
|
132
|
+
TRON_TEST_TX_HASH=64_char_hex \
|
|
133
|
+
TRON_TEST_PAY_TO=T… \
|
|
134
|
+
TRON_TEST_AMOUNT_USDT=20 \
|
|
135
|
+
pnpm --filter @autlantic/payments test:live
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Environment
|
|
139
|
+
|
|
140
|
+
| Variable | Used by |
|
|
141
|
+
|----------|---------|
|
|
142
|
+
| `TRONGRID_API_KEY` | Live verify / poll |
|
|
143
|
+
| `webhookSecret` (config) | Outbound webhook signing |
|
|
144
|
+
|
|
145
|
+
## Changelog
|
|
146
|
+
|
|
147
|
+
See [CHANGELOG.md](./CHANGELOG.md).
|
|
148
|
+
|
|
149
|
+
## v0.1 status
|
|
150
|
+
|
|
151
|
+
**SDK complete** for standalone use.
|
|
152
|
+
|
|
153
|
+
- Full API: [API.md](./API.md)
|
|
154
|
+
- Umbrella: [packages/SDK.md](../SDK.md)
|
|
155
|
+
- Security: [SECURITY.md](../SECURITY.md)
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
pnpm check:sdk # build + test + example
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
import { AutlanticPayments } from "@autlantic/payments";
|
|
163
|
+
const payments = AutlanticPayments.fromEnv();
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Roadmap (v0.2+)
|
|
167
|
+
|
|
168
|
+
- npm publish
|
|
169
|
+
- Multi-chain adapters on same core types
|
|
170
|
+
- Per-order deposit addresses
|
package/TESTING.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Testing & sandbox — Stripe-style guide
|
|
2
|
+
|
|
3
|
+
Use **sandbox mode** as your test environment. No real USDT, no TronGrid key required.
|
|
4
|
+
|
|
5
|
+
## Enable sandbox (test account)
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
export AUTLANTIC_PAYMENTS_SANDBOX=true
|
|
9
|
+
export AUTLANTIC_PAYMENTS_WEBHOOK_SECRET=whsec_test_123 # optional, for webhook tests
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import { AutlanticPayments } from "@autlantic/payments";
|
|
14
|
+
|
|
15
|
+
const payments = AutlanticPayments.fromEnv(); // reads env above
|
|
16
|
+
// or
|
|
17
|
+
const payments = new AutlanticPayments({ sandbox: true, webhookSecret: "whsec_test_123" });
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
**Never enable sandbox in production.**
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Test transaction hashes (like Stripe test cards)
|
|
25
|
+
|
|
26
|
+
Pass these as `txHash` in `verifyByTxHash` while `sandbox: true`:
|
|
27
|
+
|
|
28
|
+
| Test tx hash | Scenario | Expected result |
|
|
29
|
+
|--------------|----------|-----------------|
|
|
30
|
+
| `sandbox_payment_confirmed` | Successful payment | `ok: true` → `payment.confirmed` |
|
|
31
|
+
| `sandbox_payment_short` | Underpayment | `PAYMENT_SHORT` |
|
|
32
|
+
| `sandbox_payment_expired` | Expired checkout | `PAYMENT_EXPIRED` |
|
|
33
|
+
| `sandbox_payment_wrong_address` | Wrong wallet | `PAYMENT_WRONG_ADDRESS` |
|
|
34
|
+
| `sandbox_payment_too_early` | Tx before session | `PAYMENT_TOO_EARLY` |
|
|
35
|
+
| `sandbox_payment_not_found` | Tx not on chain | `PAYMENT_TX_NOT_FOUND` |
|
|
36
|
+
| `sandbox_payment_invalid_hash` | Bad hash format | `INVALID_TX_HASH` |
|
|
37
|
+
|
|
38
|
+
**Legacy aliases** still work: `sandbox_confirm_test`, `sandbox_success`, `sandbox_short`, etc.
|
|
39
|
+
|
|
40
|
+
Any other `sandbox_*` hash defaults to **success** (backward compatible).
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Trigger test events (like `stripe trigger`)
|
|
45
|
+
|
|
46
|
+
Programmatic — no tx hash needed:
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
const payments = new AutlanticPayments({ sandbox: true, webhookSecret: "whsec_test" });
|
|
50
|
+
|
|
51
|
+
// Success + signed webhook payload
|
|
52
|
+
const success = payments.emitTestEvent({
|
|
53
|
+
scenario: "payment.confirmed",
|
|
54
|
+
merchantRef: "order_1001",
|
|
55
|
+
amountUsdt: 49,
|
|
56
|
+
payToAddress: "TLyqzVGLV1srkB7dToTAEqgDSfPtXRJZYH",
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
console.log(success.event);
|
|
60
|
+
console.log(success.webhook?.body, success.webhook?.signature);
|
|
61
|
+
|
|
62
|
+
// Failure path
|
|
63
|
+
const failed = payments.emitTestEvent({
|
|
64
|
+
scenario: "payment.failed.short",
|
|
65
|
+
merchantRef: "order_1002",
|
|
66
|
+
amountUsdt: 20,
|
|
67
|
+
payToAddress: "TLyqzVGLV1srkB7dToTAEqgDSfPtXRJZYH",
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
if (!failed.verification.ok) {
|
|
71
|
+
console.log(failed.verification.code); // PAYMENT_SHORT
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
List all scenarios:
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
payments.listTestScenarios().forEach((s) => {
|
|
79
|
+
console.log(s.id, s.testTxHash, s.description);
|
|
80
|
+
});
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## CLI
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
pnpm build:sdk
|
|
89
|
+
|
|
90
|
+
# List scenarios
|
|
91
|
+
pnpm --filter @autlantic/payments exec autlantic-payments scenarios
|
|
92
|
+
|
|
93
|
+
# Trigger success event (JSON output)
|
|
94
|
+
pnpm --filter @autlantic/payments exec autlantic-payments trigger payment.confirmed \
|
|
95
|
+
--merchant-ref order_1 --amount 20 \
|
|
96
|
+
--to TLyqzVGLV1srkB7dToTAEqgDSfPtXRJZYH
|
|
97
|
+
|
|
98
|
+
# Trigger failure
|
|
99
|
+
pnpm --filter @autlantic/payments exec autlantic-payments trigger payment.failed.short \
|
|
100
|
+
--merchant-ref order_2 --amount 20 \
|
|
101
|
+
--to TLyqzVGLV1srkB7dToTAEqgDSfPtXRJZYH
|
|
102
|
+
|
|
103
|
+
# Classic verify with test tx
|
|
104
|
+
pnpm --filter @autlantic/payments exec autlantic-payments sandbox \
|
|
105
|
+
--merchant-ref order_3 --amount 20 \
|
|
106
|
+
--to TLyqzVGLV1srkB7dToTAEqgDSfPtXRJZYH \
|
|
107
|
+
--tx sandbox_payment_confirmed
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Webhook handler test flow
|
|
113
|
+
|
|
114
|
+
1. `emitTestEvent({ scenario: "payment.confirmed", ... })`
|
|
115
|
+
2. POST `webhook.body` to your endpoint with header `x-autlantic-signature: webhook.signature`
|
|
116
|
+
3. In your app: `payments.parseWebhook(rawBody, signature)`
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Live mode (optional)
|
|
121
|
+
|
|
122
|
+
Use real Tron tx hashes (64 hex) + `TRONGRID_API_KEY` with **sandbox off**.
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
TRONGRID_INTEGRATION=1 TRON_TEST_TX_HASH=<64hex> pnpm --filter @autlantic/payments test:live
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Scenario reference
|
|
131
|
+
|
|
132
|
+
| Scenario id | Event type |
|
|
133
|
+
|-------------|------------|
|
|
134
|
+
| `payment.confirmed` | `payment.confirmed` |
|
|
135
|
+
| `payment.failed.short` | `payment.failed` |
|
|
136
|
+
| `payment.failed.expired` | `payment.failed` |
|
|
137
|
+
| `payment.failed.wrong_address` | `payment.failed` |
|
|
138
|
+
| `payment.failed.too_early` | `payment.failed` |
|
|
139
|
+
| `payment.failed.tx_not_found` | `payment.failed` |
|
|
140
|
+
| `payment.failed.invalid_hash` | `payment.failed` |
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Autlantic Payments CLI (run `pnpm build:sdk` first).
|
|
4
|
+
*/
|
|
5
|
+
import { createRequire } from "node:module";
|
|
6
|
+
|
|
7
|
+
const require = createRequire(import.meta.url);
|
|
8
|
+
const {
|
|
9
|
+
AutlanticPayments,
|
|
10
|
+
configFromEnv,
|
|
11
|
+
isVerificationSuccess,
|
|
12
|
+
listSandboxScenarios,
|
|
13
|
+
} = require("../dist/index.js");
|
|
14
|
+
|
|
15
|
+
function parseArgs(argv) {
|
|
16
|
+
const out = { _: [] };
|
|
17
|
+
for (let i = 0; i < argv.length; i++) {
|
|
18
|
+
const a = argv[i];
|
|
19
|
+
if (a.startsWith("--")) {
|
|
20
|
+
const key = a.slice(2).replace(/-/g, "_");
|
|
21
|
+
out[key] = argv[i + 1];
|
|
22
|
+
i++;
|
|
23
|
+
} else {
|
|
24
|
+
out._.push(a);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return out;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function usage() {
|
|
31
|
+
console.log(`Autlantic Payments CLI
|
|
32
|
+
|
|
33
|
+
Commands:
|
|
34
|
+
scenarios List sandbox test scenarios (Stripe-style)
|
|
35
|
+
trigger <scenario-id> Emit a test event (requires sandbox)
|
|
36
|
+
sandbox Verify using a sandbox test tx hash
|
|
37
|
+
verify Verify a live Tron tx (TRONGRID_API_KEY)
|
|
38
|
+
|
|
39
|
+
Trigger / sandbox options:
|
|
40
|
+
--merchant-ref <id>
|
|
41
|
+
--amount <usdt>
|
|
42
|
+
--to <tron base58 address>
|
|
43
|
+
--tx <hash> (sandbox / verify only)
|
|
44
|
+
|
|
45
|
+
Examples:
|
|
46
|
+
autlantic-payments trigger payment.confirmed --merchant-ref o1 --amount 20 --to TLyqz...
|
|
47
|
+
autlantic-payments sandbox --merchant-ref o1 --amount 20 --to TLyqz... --tx sandbox_payment_confirmed
|
|
48
|
+
`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function sandboxPayments() {
|
|
52
|
+
const base = configFromEnv(process.env);
|
|
53
|
+
return new AutlanticPayments({ ...base, sandbox: true });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function main() {
|
|
57
|
+
const args = parseArgs(process.argv.slice(2));
|
|
58
|
+
const cmd = args._[0];
|
|
59
|
+
if (!cmd || cmd === "help" || cmd === "--help") {
|
|
60
|
+
usage();
|
|
61
|
+
process.exit(cmd ? 0 : 1);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (cmd === "scenarios") {
|
|
65
|
+
console.log(JSON.stringify(listSandboxScenarios(), null, 2));
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (cmd === "trigger") {
|
|
70
|
+
const scenarioId = args._[1];
|
|
71
|
+
const merchantRef = args.merchant_ref;
|
|
72
|
+
const amount = Number(args.amount);
|
|
73
|
+
const payTo = args.to;
|
|
74
|
+
if (!scenarioId || !merchantRef || !Number.isFinite(amount) || !payTo) {
|
|
75
|
+
usage();
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
const payments = sandboxPayments();
|
|
79
|
+
const out = payments.triggerTestEvent({
|
|
80
|
+
scenario: scenarioId,
|
|
81
|
+
merchantRef,
|
|
82
|
+
amountUsdt: amount,
|
|
83
|
+
payToAddress: payTo,
|
|
84
|
+
});
|
|
85
|
+
console.log(
|
|
86
|
+
JSON.stringify(
|
|
87
|
+
{
|
|
88
|
+
scenario: out.scenario.id,
|
|
89
|
+
ok: out.verification.ok,
|
|
90
|
+
code: out.verification.ok ? undefined : out.verification.code,
|
|
91
|
+
message: out.verification.ok ? undefined : out.verification.message,
|
|
92
|
+
event: out.event,
|
|
93
|
+
webhook: out.webhook,
|
|
94
|
+
},
|
|
95
|
+
null,
|
|
96
|
+
2,
|
|
97
|
+
),
|
|
98
|
+
);
|
|
99
|
+
process.exit(out.verification.ok ? 0 : 2);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const merchantRef = args.merchant_ref;
|
|
103
|
+
const amount = Number(args.amount);
|
|
104
|
+
const payTo = args.to;
|
|
105
|
+
const txHash = args.tx;
|
|
106
|
+
|
|
107
|
+
if (!merchantRef || !Number.isFinite(amount) || !payTo || !txHash) {
|
|
108
|
+
usage();
|
|
109
|
+
process.exit(1);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const base = configFromEnv(process.env);
|
|
113
|
+
const payments = new AutlanticPayments({
|
|
114
|
+
...base,
|
|
115
|
+
sandbox: cmd === "sandbox" ? true : base.sandbox,
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
const intent = payments.createIntent({
|
|
119
|
+
merchantRef,
|
|
120
|
+
amountUsdt: amount,
|
|
121
|
+
payToAddress: payTo,
|
|
122
|
+
matchStrategy: "minimum_amount",
|
|
123
|
+
expiresAt: new Date(Date.now() + 60 * 60 * 1000),
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
const result = await payments.verifyByTxHash(intent, txHash);
|
|
127
|
+
if (!isVerificationSuccess(result)) {
|
|
128
|
+
console.error(
|
|
129
|
+
JSON.stringify(
|
|
130
|
+
{ ok: false, code: result.code, message: result.message },
|
|
131
|
+
null,
|
|
132
|
+
2,
|
|
133
|
+
),
|
|
134
|
+
);
|
|
135
|
+
process.exit(2);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
console.log(
|
|
139
|
+
JSON.stringify(
|
|
140
|
+
{
|
|
141
|
+
ok: true,
|
|
142
|
+
txHash: result.transfer.txHash,
|
|
143
|
+
amountUsdt: result.transfer.amountUsdt,
|
|
144
|
+
merchantRef: intent.merchantRef,
|
|
145
|
+
},
|
|
146
|
+
null,
|
|
147
|
+
2,
|
|
148
|
+
),
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
main().catch((err) => {
|
|
153
|
+
console.error(err);
|
|
154
|
+
process.exit(1);
|
|
155
|
+
});
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type CreatePaymentIntentInput, type MatchedPayment, type OnChainTransfer, type PaymentConfirmedEvent, type PaymentIntent, type PaymentVerificationResult } from "@autlantic/payments-core";
|
|
2
|
+
import type { AutlanticPaymentsConfig } from "./config";
|
|
3
|
+
import { type EmitTestEventInput, type EmitTestEventResult, type SandboxScenario, type SandboxScenarioId } from "./test-scenarios";
|
|
4
|
+
export declare class AutlanticPayments {
|
|
5
|
+
private readonly config;
|
|
6
|
+
constructor(config?: AutlanticPaymentsConfig);
|
|
7
|
+
/** Construct from environment variables (see `configFromEnv`). */
|
|
8
|
+
static fromEnv(env?: Record<string, string | undefined>): AutlanticPayments;
|
|
9
|
+
/** Create a payment intent (store on your order / checkout row). */
|
|
10
|
+
createIntent(input: CreatePaymentIntentInput): PaymentIntent;
|
|
11
|
+
/**
|
|
12
|
+
* Verify a user-submitted transaction hash against an intent.
|
|
13
|
+
*/
|
|
14
|
+
verifyByTxHash(intent: PaymentIntent, txHash: string): Promise<PaymentVerificationResult>;
|
|
15
|
+
/**
|
|
16
|
+
* Poll the chain for an incoming transfer matching the intent (exact or minimum amount).
|
|
17
|
+
*/
|
|
18
|
+
findMatchingPayment(intent: PaymentIntent): Promise<MatchedPayment | null>;
|
|
19
|
+
/**
|
|
20
|
+
* Verify and return a confirmed event suitable for webhooks / internal handlers.
|
|
21
|
+
*/
|
|
22
|
+
confirmByTxHash(intent: PaymentIntent, txHash: string): Promise<{
|
|
23
|
+
ok: true;
|
|
24
|
+
event: PaymentConfirmedEvent;
|
|
25
|
+
transfer: OnChainTransfer;
|
|
26
|
+
} | {
|
|
27
|
+
ok: false;
|
|
28
|
+
result: PaymentVerificationResult;
|
|
29
|
+
}>;
|
|
30
|
+
/** Sign a webhook body (send as `x-autlantic-signature` header). */
|
|
31
|
+
signWebhook(event: PaymentConfirmedEvent): {
|
|
32
|
+
body: string;
|
|
33
|
+
signature: string;
|
|
34
|
+
} | null;
|
|
35
|
+
/** Verify an inbound webhook from Autlantic (or your own signed events). */
|
|
36
|
+
verifyWebhook(rawBody: string, signatureHeader: string | null | undefined): boolean;
|
|
37
|
+
/** Verify signature and parse `payment.confirmed` payload. */
|
|
38
|
+
parseWebhook(rawBody: string, signatureHeader: string | null | undefined): PaymentConfirmedEvent | null;
|
|
39
|
+
/**
|
|
40
|
+
* Stripe-style test harness: run a catalog scenario in sandbox (no TronGrid).
|
|
41
|
+
* Requires `sandbox: true` on the client.
|
|
42
|
+
*/
|
|
43
|
+
emitTestEvent(input: EmitTestEventInput): EmitTestEventResult;
|
|
44
|
+
/** List built-in sandbox scenarios (success + failure paths). */
|
|
45
|
+
listTestScenarios(): SandboxScenario[];
|
|
46
|
+
/**
|
|
47
|
+
* Trigger a scenario by id — same as `emitTestEvent` (CLI-friendly alias).
|
|
48
|
+
*/
|
|
49
|
+
triggerTestEvent(input: EmitTestEventInput): EmitTestEventResult;
|
|
50
|
+
private assertSandboxMode;
|
|
51
|
+
}
|
|
52
|
+
export type { EmitTestEventInput, EmitTestEventResult, SandboxScenario, SandboxScenarioId };
|
|
53
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAKA,OAAO,EAOL,KAAK,wBAAwB,EAC7B,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,aAAa,EAClB,KAAK,yBAAyB,EAC/B,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAExD,OAAO,EAOL,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACvB,MAAM,kBAAkB,CAAC;AAQ1B,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;gBAErC,MAAM,GAAE,uBAA4B;IAQhD,kEAAkE;IAClE,MAAM,CAAC,OAAO,CAAC,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,iBAAiB;IAIxF,oEAAoE;IACpE,YAAY,CAAC,KAAK,EAAE,wBAAwB,GAAG,aAAa;IAK5D;;OAEG;IACG,cAAc,CAClB,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,yBAAyB,CAAC;IAgDrC;;OAEG;IACG,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IA0BhF;;OAEG;IACG,eAAe,CACnB,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,MAAM,GACb,OAAO,CACN;QAAE,EAAE,EAAE,IAAI,CAAC;QAAC,KAAK,EAAE,qBAAqB,CAAC;QAAC,QAAQ,EAAE,eAAe,CAAA;KAAE,GACrE;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,MAAM,EAAE,yBAAyB,CAAA;KAAE,CACnD;IAWD,oEAAoE;IACpE,WAAW,CAAC,KAAK,EAAE,qBAAqB,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAOrF,4EAA4E;IAC5E,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO;IAMnF,8DAA8D;IAC9D,YAAY,CACV,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACzC,qBAAqB,GAAG,IAAI;IAM/B;;;OAGG;IACH,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,mBAAmB;IAK7D,iEAAiE;IACjE,iBAAiB,IAAI,eAAe,EAAE;IAItC;;OAEG;IACH,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,GAAG,mBAAmB;IAIhE,OAAO,CAAC,iBAAiB;CAO1B;AAED,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,eAAe,EAAE,iBAAiB,EAAE,CAAC"}
|