@curless/agentbank-merchant-sdk 0.1.3 → 0.1.5
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/README.md +14 -2
- package/dist/resources/payment-intents.d.ts +0 -4
- package/dist/resources/payment-intents.d.ts.map +1 -1
- package/dist/resources/payment-intents.js +5 -5
- package/dist/resources/payment-intents.js.map +1 -1
- package/dist/webhooks.d.ts.map +1 -1
- package/dist/webhooks.js +9 -1
- package/dist/webhooks.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,11 +5,16 @@ Drop into a merchant's backend (Shopify storefront, ClubMed booking flow,
|
|
|
5
5
|
TikTok Shop seller service, anything that wants to **accept agent payments**)
|
|
6
6
|
and you get:
|
|
7
7
|
|
|
8
|
-
- **`AgentbankMerchant`** — typed client for `PaymentIntents` (create/get/capture/list across ACP / x402 / AP2 / UCP / A2A) and `WebhookEndpoints`.
|
|
8
|
+
- **`AgentbankMerchant`** — typed client for `PaymentIntents` (create/get/capture/list/ledger-entries across ACP / x402 / AP2 / UCP / A2A), plus `PaymentLinks`, `Customers`, `BalanceTransactions`, and `WebhookEndpoints`. No refund method — refunds are Curless-originated (see below).
|
|
9
9
|
- **`verifyWebhook` / `parseVerifiedWebhook`** — HMAC-SHA256 signature verification (Stripe-style `t=…,v1=…`), constant-time, **edge-safe** (Web Crypto, runs on Vercel Edge / Cloudflare Workers). Async — `await` them.
|
|
10
10
|
- **`x402`** — `buildChallenge()` to emit your own canonical 402 from your route, `decodeXPaymentHeader()` to parse what the agent paid with.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
One runtime dependency (`@curless/agentbank-core`, for portable crypto + the HTTP layer). **Edge-safe** — Web Crypto only, no `node:` builtins. Node 18+.
|
|
13
|
+
|
|
14
|
+
> **Refunds**: agentbank exposes no refund-initiation endpoint. The merchant
|
|
15
|
+
> refunds in Curless (it holds the money); Curless executes the card refund and
|
|
16
|
+
> forwards the event, which advances the PI to `refunded` / `partially_refunded`.
|
|
17
|
+
> Read the resulting state via `paymentIntents.get()` / `.list()`.
|
|
13
18
|
|
|
14
19
|
```ts
|
|
15
20
|
import { AgentbankMerchant, parseVerifiedWebhook, x402 } from '@curless/agentbank-merchant-sdk';
|
|
@@ -46,3 +51,10 @@ return new Response(JSON.stringify(x402.buildChallenge({
|
|
|
46
51
|
resource: 'https://shop.example/api/checkout',
|
|
47
52
|
})), { status: 402, headers: { 'content-type': 'application/json' } });
|
|
48
53
|
```
|
|
54
|
+
|
|
55
|
+
## Timeouts & errors
|
|
56
|
+
|
|
57
|
+
Every request carries a 30s default deadline (`timeoutMs` on the constructor
|
|
58
|
+
or per request; `0` disables) and supports `AbortSignal` via
|
|
59
|
+
`RequestOptions.signal`. ALL failures throw `AgentbankError` — transport
|
|
60
|
+
failures use `status === 0` with code `timeout` / `aborted` / `network_error`.
|
|
@@ -21,10 +21,6 @@ export declare class PaymentIntentsResource {
|
|
|
21
21
|
create(input: CreatePaymentIntentInput): Promise<PaymentIntent>;
|
|
22
22
|
get(id: string): Promise<PaymentIntent>;
|
|
23
23
|
capture(id: string): Promise<PaymentIntent>;
|
|
24
|
-
refund(id: string, opts?: {
|
|
25
|
-
amount?: number;
|
|
26
|
-
reason?: string;
|
|
27
|
-
}): Promise<PaymentIntent>;
|
|
28
24
|
ledgerEntries(id: string): Promise<PaymentIntentLedger>;
|
|
29
25
|
list(params?: {
|
|
30
26
|
limit?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payment-intents.d.ts","sourceRoot":"","sources":["../../src/resources/payment-intents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EAChB,MAAM,aAAa,CAAC;AAErB,MAAM,MAAM,wBAAwB,GAAG;IAGrC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,eAAe,CAAC;IAC1B,KAAK,EAAE,KAAK,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAIF,qBAAa,sBAAsB;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,iBAAiB;IAEtD,MAAM,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,aAAa,CAAC;IAQ/D,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAOvC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"payment-intents.d.ts","sourceRoot":"","sources":["../../src/resources/payment-intents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EAChB,MAAM,aAAa,CAAC;AAErB,MAAM,MAAM,wBAAwB,GAAG;IAGrC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,eAAe,CAAC;IAC1B,KAAK,EAAE,KAAK,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAIF,qBAAa,sBAAsB;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,iBAAiB;IAEtD,MAAM,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,aAAa,CAAC;IAQ/D,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAOvC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAe3C,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAOvD,IAAI,CACF,MAAM,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,mBAAmB,CAAA;KAAO,GAC7E,OAAO,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;CAKrC"}
|
|
@@ -18,11 +18,11 @@ export class PaymentIntentsResource {
|
|
|
18
18
|
capture(id) {
|
|
19
19
|
return this.client.request('POST', `/v1/payment-intents/${encodeURIComponent(id)}/capture`);
|
|
20
20
|
}
|
|
21
|
-
//
|
|
22
|
-
// the
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
// No refund() — agentbank does not expose a refund-initiation endpoint.
|
|
22
|
+
// Refunds are Curless-originated: the merchant refunds in Curless (it holds
|
|
23
|
+
// the money), Curless executes the card refund and forwards the event to
|
|
24
|
+
// agentbank, which records the reversal + advances the PI to
|
|
25
|
+
// refunded / partially_refunded. Read the resulting state via get()/list().
|
|
26
26
|
// The double-entry ledger trail behind this PI (authorize → capture →
|
|
27
27
|
// settle → refund), oldest-first — "where did this money go".
|
|
28
28
|
ledgerEntries(id) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payment-intents.js","sourceRoot":"","sources":["../../src/resources/payment-intents.ts"],"names":[],"mappings":"AAuBA,wEAAwE;AACxE,uEAAuE;AACvE,MAAM,OAAO,sBAAsB;IACJ;IAA7B,YAA6B,MAAyB;QAAzB,WAAM,GAAN,MAAM,CAAmB;IAAG,CAAC;IAE1D,MAAM,CAAC,KAA+B;QACpC,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC;QAC1C,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAgB,MAAM,EAAE,qBAAqB,EAAE;YACvE,IAAI;YACJ,cAAc;SACf,CAAC,CAAC;IACL,CAAC;IAED,GAAG,CAAC,EAAU;QACZ,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CACxB,KAAK,EACL,uBAAuB,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAChD,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,EAAU;QAChB,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CACxB,MAAM,EACN,uBAAuB,kBAAkB,CAAC,EAAE,CAAC,UAAU,CACxD,CAAC;IACJ,CAAC;IAED,
|
|
1
|
+
{"version":3,"file":"payment-intents.js","sourceRoot":"","sources":["../../src/resources/payment-intents.ts"],"names":[],"mappings":"AAuBA,wEAAwE;AACxE,uEAAuE;AACvE,MAAM,OAAO,sBAAsB;IACJ;IAA7B,YAA6B,MAAyB;QAAzB,WAAM,GAAN,MAAM,CAAmB;IAAG,CAAC;IAE1D,MAAM,CAAC,KAA+B;QACpC,MAAM,EAAE,cAAc,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC;QAC1C,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAgB,MAAM,EAAE,qBAAqB,EAAE;YACvE,IAAI;YACJ,cAAc;SACf,CAAC,CAAC;IACL,CAAC;IAED,GAAG,CAAC,EAAU;QACZ,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CACxB,KAAK,EACL,uBAAuB,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAChD,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,EAAU;QAChB,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CACxB,MAAM,EACN,uBAAuB,kBAAkB,CAAC,EAAE,CAAC,UAAU,CACxD,CAAC;IACJ,CAAC;IAED,wEAAwE;IACxE,4EAA4E;IAC5E,yEAAyE;IACzE,6DAA6D;IAC7D,4EAA4E;IAE5E,sEAAsE;IACtE,8DAA8D;IAC9D,aAAa,CAAC,EAAU;QACtB,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CACxB,KAAK,EACL,uBAAuB,kBAAkB,CAAC,EAAE,CAAC,iBAAiB,CAC/D,CAAC;IACJ,CAAC;IAED,IAAI,CACF,SAA4E,EAAE;QAE9E,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAA2B,KAAK,EAAE,qBAAqB,EAAE;YACjF,KAAK,EAAE,MAAM;SACd,CAAC,CAAC;IACL,CAAC;CACF"}
|
package/dist/webhooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../src/webhooks.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,wBAAwB,0BAA0B,CAAC;AAEhE,MAAM,MAAM,oBAAoB,GAAG;IAEjC,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,QAAQ,MAAM,EACd,SAAS,MAAM,EACf,iBAAiB,MAAM,GAAG,SAAS,GAAG,IAAI,EAC1C,OAAM,oBAAyB,KAC9B,OAAO,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../src/webhooks.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,wBAAwB,0BAA0B,CAAC;AAEhE,MAAM,MAAM,oBAAoB,GAAG;IAEjC,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,QAAQ,MAAM,EACd,SAAS,MAAM,EACf,iBAAiB,MAAM,GAAG,SAAS,GAAG,IAAI,EAC1C,OAAM,oBAAyB,KAC9B,OAAO,CAAC,OAAO,CAoBjB,CAAC;AAIF,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,MAAM,EACd,SAAS,MAAM,EACf,iBAAiB,MAAM,GAAG,SAAS,GAAG,IAAI,EAC1C,OAAM,oBAAyB,KAC9B,OAAO,CAAC,YAAY,CAYtB,CAAC"}
|
package/dist/webhooks.js
CHANGED
|
@@ -16,7 +16,15 @@ export const verifyWebhook = async (secret, rawBody, signatureHeader, opts = {})
|
|
|
16
16
|
return false;
|
|
17
17
|
const toleranceSec = opts.toleranceSec ?? 300;
|
|
18
18
|
const nowSec = opts.nowSec ?? Math.floor(Date.now() / 1000);
|
|
19
|
-
|
|
19
|
+
// Trim keys/values so a proxy that rewrites the header with spaces
|
|
20
|
+
// (`t=1, v1=ab`) still verifies — matches the server + Python SDK parsers.
|
|
21
|
+
const fields = new Map();
|
|
22
|
+
for (const part of signatureHeader.split(',')) {
|
|
23
|
+
const idx = part.indexOf('=');
|
|
24
|
+
if (idx === -1)
|
|
25
|
+
continue;
|
|
26
|
+
fields.set(part.slice(0, idx).trim(), part.slice(idx + 1).trim());
|
|
27
|
+
}
|
|
20
28
|
const t = Number(fields.get('t'));
|
|
21
29
|
const v1 = fields.get('v1');
|
|
22
30
|
if (!Number.isFinite(t) || !v1)
|
package/dist/webhooks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../src/webhooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE5E,wEAAwE;AACxE,+DAA+D;AAC/D,0EAA0E;AAC1E,EAAE;AACF,6EAA6E;AAC7E,0EAA0E;AAC1E,yEAAyE;AACzE,6BAA6B;AAC7B,EAAE;AACF,uEAAuE;AACvE,+DAA+D;AAE/D,MAAM,CAAC,MAAM,wBAAwB,GAAG,uBAAuB,CAAC;AAShE,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAChC,MAAc,EACd,OAAe,EACf,eAA0C,EAC1C,OAA6B,EAAE,EACb,EAAE;IACpB,IAAI,CAAC,eAAe;QAAE,OAAO,KAAK,CAAC;IACnC,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,GAAG,CAAC;IAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAE5D,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../src/webhooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE5E,wEAAwE;AACxE,+DAA+D;AAC/D,0EAA0E;AAC1E,EAAE;AACF,6EAA6E;AAC7E,0EAA0E;AAC1E,yEAAyE;AACzE,6BAA6B;AAC7B,EAAE;AACF,uEAAuE;AACvE,+DAA+D;AAE/D,MAAM,CAAC,MAAM,wBAAwB,GAAG,uBAAuB,CAAC;AAShE,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAChC,MAAc,EACd,OAAe,EACf,eAA0C,EAC1C,OAA6B,EAAE,EACb,EAAE;IACpB,IAAI,CAAC,eAAe;QAAE,OAAO,KAAK,CAAC;IACnC,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,GAAG,CAAC;IAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAE5D,mEAAmE;IACnE,2EAA2E;IAC3E,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,IAAI,IAAI,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,SAAS;QACzB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACpE,CAAC;IACD,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAClC,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC;IAC7C,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,YAAY;QAAE,OAAO,KAAK,CAAC;IAEtD,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC;IAChE,OAAO,kBAAkB,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;AAC1C,CAAC,CAAC;AAWF,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EACvC,MAAc,EACd,OAAe,EACf,eAA0C,EAC1C,OAA6B,EAAE,EACR,EAAE;IACzB,IAAI,CAAC,CAAC,MAAM,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;QACnE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAC/C,CAAC;IACD,IAAI,KAAmB,CAAC;IACxB,IAAI,CAAC;QACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAiB,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5C,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACzE,OAAO,KAAK,CAAC;AACf,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@curless/agentbank-merchant-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Merchant-side SDK for agentbank — accept agent payments: PaymentIntents, edge-safe webhook verification, x402 challenge helpers.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|