diff --git a/.changeset/pay-webhook-livemode.md b/.changeset/pay-webhook-livemode.md new file mode 100644 index 0000000..8aa9d37 --- /dev/null +++ b/.changeset/pay-webhook-livemode.md @@ -0,0 +1,8 @@ +--- +"@agentaos/pay": minor +--- + +Add `livemode` to webhook payloads and type the subscription webhook events. + +- Every `WebhookEvent` `data` now carries `livemode: boolean` (`true` = live mode, `false` = test mode) — the account-mode signal. This replaces the previous chain-specific `testnet` field, which was meaningless for card/bank rails; use `network` for the chain/rail. +- New `SubscriptionData` type and five `subscription.*` events on the `WebhookEvent` union: `subscription.created`, `subscription.renewed`, `subscription.payment_failed`, `subscription.updated`, `subscription.canceled`. diff --git a/packages/pay/src/index.ts b/packages/pay/src/index.ts index 4ccc161..b500148 100644 --- a/packages/pay/src/index.ts +++ b/packages/pay/src/index.ts @@ -23,6 +23,7 @@ export type { CheckoutCompletedData, SendCompletedData, SendFailedData, + SubscriptionData, PaginatedList, ListParams, } from './types.js'; diff --git a/packages/pay/src/types.ts b/packages/pay/src/types.ts index 3173a10..418affa 100644 --- a/packages/pay/src/types.ts +++ b/packages/pay/src/types.ts @@ -365,6 +365,8 @@ export interface CheckoutCompletedData { payer: string; payerType: 'human' | 'agent'; network: string; + /** `true` = live mode, `false` = test mode. Account mode, not the chain — see `network` for the chain/rail. */ + livemode: boolean; metadata: Record; } @@ -377,6 +379,8 @@ export interface SendCompletedData { token: string; chainId: number; network: string; + /** `true` = live mode, `false` = test mode. */ + livemode: boolean; description: string | null; } @@ -389,10 +393,34 @@ export interface SendFailedData { token: string; chainId: number; network: string; + /** `true` = live mode, `false` = test mode. */ + livemode: boolean; description: string | null; } +export interface SubscriptionData { + id: string; + /** Stripe subscription status, mirrored verbatim (e.g. `incomplete`, `active`, `trialing`, `past_due`, `unpaid`, `canceled`). */ + status: string; + planName: string | null; + currency: string; + /** Price snapshot in integer minor units (e.g. cents). */ + amountMinor: number; + /** ISO 8601 timestamp, or `null` before the first billing cycle is set. */ + currentPeriodEnd: string | null; + cancelAtPeriodEnd: boolean; + customerEmail: string | null; + customerName: string | null; + /** `true` = live mode, `false` = test mode. */ + livemode: boolean; +} + export type WebhookEvent = | { type: 'checkout.session.completed'; data: CheckoutCompletedData } | { type: 'send.completed'; data: SendCompletedData } - | { type: 'send.failed'; data: SendFailedData }; + | { type: 'send.failed'; data: SendFailedData } + | { type: 'subscription.created'; data: SubscriptionData } + | { type: 'subscription.renewed'; data: SubscriptionData } + | { type: 'subscription.payment_failed'; data: SubscriptionData } + | { type: 'subscription.updated'; data: SubscriptionData } + | { type: 'subscription.canceled'; data: SubscriptionData };