import Stripe from 'stripe'; import { ShopCart, ShopOrder } from '../types.js'; import { a as CartStore } from '../store-B6Oh5IPN.js'; /** * F136 Phase 1 — Order document factory. * * Pure function that takes a Stripe Checkout Session + the cart it * referenced and produces a `ShopOrder` data object ready for the host * to persist. The host owns "where orders live" (filesystem JSON, * GitHub adapter, external DB) so we don't write here — we return the * doc shape and let the host call its CMS write path. */ interface BuildOrderInput { session: Stripe.Checkout.Session; cart: ShopCart; /** Slug prefix for the order number — default "WH". */ orderNumberPrefix?: string; } declare function buildOrderFromCheckoutSession(input: BuildOrderInput): { id: string; slug: string; data: ShopOrder['data']; }; /** * F136 Phase 1 — POST /api/shop/webhooks Stripe webhook handler. * * Verifies the Stripe signature header, dispatches events to the host's * `onOrderPaid` / `onOrderFailed` / `onOrderRefunded` callbacks. Order * persistence is the host's responsibility — this module only reshapes * Stripe payloads into CMS-friendly objects. * * Important: Stripe webhook signature verification needs the *raw* * request body. In Next.js Route Handlers and Hono, that means reading * `req.text()` directly. Frameworks that JSON-parse the body before our * handler runs will break signature verification. * * Connect mode: events about activity ON a connected account arrive * with `event.account = 'acct_xxx'` set. We pass that through to the * `onOrderPaid` callback so the host can route the order to the right * tenant. The pattern matches sanneandersen-site (proven on real * Stripe transactions). * * Idempotency: Stripe re-delivers the same event up to 10 times if the * receiver returns non-2xx. The host's `onOrderPaid` MUST be idempotent * — it is called per Stripe delivery, not per logical "this charge * succeeded" boundary. The recommended pattern: store the * `session.id` (or `event.id`) on first write and no-op on later * deliveries. */ interface OnOrderPaidArgs { order: ReturnType; session: Stripe.Checkout.Session; /** `acct_xxx` if this is a Connect event for a connected account, else null. */ connectedAccountId: string | null; /** Discriminator from `session.metadata.kind` (default 'order'). */ kind: string; /** Human label for the payment method ("Visa •••• 4242", "MobilePay"…) when expanded. */ paymentMethodLabel: string | null; /** Stripe Event id — useful for the host's idempotency key. */ eventId: string; } interface WebhookHandlerOptions { /** `whsec_…` from Stripe Dashboard. */ webhookSecret: string; /** Stripe secret key — same one used elsewhere. */ secretKey?: string; /** Cart store so we can look up the cart that produced the session. */ cartStore: CartStore; /** Called when checkout.session.completed arrives with payment_status='paid'. */ onOrderPaid(args: OnOrderPaidArgs): Promise; /** Called on checkout.session.async_payment_failed or payment_intent.payment_failed. */ onOrderFailed?(args: { sessionId?: string; paymentIntentId?: string; reason?: string; connectedAccountId: string | null; eventId: string; }): Promise; /** Called on charge.refunded. */ onOrderRefunded?(args: { paymentIntentId: string; amountRefunded: number; fullyRefunded: boolean; connectedAccountId: string | null; eventId: string; }): Promise; /** Slug prefix for order numbers — default "WH". */ orderNumberPrefix?: string; /** Called after a successful checkout to clear the cart. Default: true. */ clearCartOnPaid?: boolean; /** * Expand `payment_intent.latest_charge.payment_method_details` so we * can label the payment method. Default: true. Disable for sites that * don't need this and want to save one API call per webhook. */ expandPaymentMethod?: boolean; } declare function createStripeWebhookHandler(opts: WebhookHandlerOptions): (req: Request) => Promise; /** * F136 Phase 1 — Format Stripe payment_method_details into a human label. * * Lifted from the proven sanneandersen-site implementation * (verified on real Stripe transactions). Examples: * - "Visa •••• 4242" * - "Mastercard •••• 1234" * - "Apple Pay" * - "Google Pay" * - "MobilePay" * - "Klarna" */ declare function formatPaymentMethod(pm: Stripe.Charge.PaymentMethodDetails | null | undefined): string | null; export { type BuildOrderInput, type OnOrderPaidArgs, type WebhookHandlerOptions, buildOrderFromCheckoutSession, createStripeWebhookHandler, formatPaymentMethod };