{"_id":"@classytic/revenue-stripe","_rev":"5-9ca4b80c33b328b557f92816b30bba6f","name":"@classytic/revenue-stripe","dist-tags":{"latest":"0.2.2"},"versions":{"0.1.0":{"name":"@classytic/revenue-stripe","version":"0.1.0","keywords":["revenue","payment","stripe","stripe-saas","stripe-connect","stripe-checkout","subscriptions","payment-intents","webhooks","provider","typescript"],"author":{"url":"https://github.com/classytic","name":"Classytic","email":"classytic.dev@gmail.com"},"license":"MIT","_id":"@classytic/revenue-stripe@0.1.0","maintainers":[{"name":"siam923","email":"classytic.dev@gmail.com"},{"name":"classytic-bot","email":"classytic.dev+bot@gmail.com"}],"contributors":[{"url":"https://github.com/siam923","name":"Sadman Chowdhury"}],"homepage":"https://github.com/classytic/revenue#readme","bugs":{"url":"https://github.com/classytic/revenue/issues"},"dist":{"shasum":"767553aa790870f96e0f37998c385ae68d62dccb","tarball":"https://registry.npmjs.org/@classytic/revenue-stripe/-/revenue-stripe-0.1.0.tgz","fileCount":37,"integrity":"sha512-YuOu3PoEF1HN9J6FONI8f5jcAkddCLhzPJb0x/hZF9pUJi5s5jTQ6Ruxkj/v3Bh/q0FZLbFxz2aqLQCy3Lw5uA==","signatures":[{"sig":"MEQCIDSA7RQc5pZBIEr2MnriaPBeNEeJEHJSyOT05jAyGsNIAiBvy6SParB/3nERX79k7dMFQU3HVwEuMbbe4rlnIuXeZw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":171297},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","module":"./dist/index.mjs","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./saas":{"types":"./dist/saas/index.d.mts","default":"./dist/saas/index.mjs"},"./connect":{"types":"./dist/connect/index.d.mts","default":"./dist/connect/index.mjs"},"./checkout":{"types":"./dist/checkout/index.d.mts","default":"./dist/checkout/index.mjs"},"./webhooks":{"types":"./dist/webhooks/index.d.mts","default":"./dist/webhooks/index.mjs"}},"gitHead":"7fd86553218615fb809f5a0fc43271e9c9f05905","scripts":{"dev":"tsdown --watch","test":"vitest run","build":"tsdown","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"classytic-bot","email":"classytic.dev+bot@gmail.com"},"repository":{"url":"git+https://github.com/classytic/revenue.git","type":"git"},"_npmVersion":"10.9.3","description":"Stripe provider for @classytic/revenue — SaaS subscriptions, marketplace Connect, lean Checkout. Subpath-split so hosts tree-shake what they don't use.","directories":{},"sideEffects":false,"_nodeVersion":"22.19.0","dependencies":{"nanoid":"^5.1.6"},"_hasShrinkwrap":false,"devDependencies":{"stripe":"^22.1.1","tsdown":"^0.20.3","vitest":"^3.2.4","typescript":"^5.6.3","@types/node":"^22.0.0"},"peerDependencies":{"stripe":"^22","@classytic/revenue":">=2.1.0","@classytic/primitives":">=0.7.1"},"_npmOperationalInternal":{"tmp":"tmp/revenue-stripe_0.1.0_1781371891624_0.6467355382953306","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@classytic/revenue-stripe","version":"0.1.1","keywords":["revenue","payment","stripe","stripe-saas","stripe-connect","stripe-checkout","subscriptions","payment-intents","webhooks","provider","typescript"],"author":{"url":"https://github.com/classytic","name":"Classytic","email":"classytic.dev@gmail.com"},"license":"MIT","_id":"@classytic/revenue-stripe@0.1.1","maintainers":[{"name":"siam923","email":"classytic.dev@gmail.com"},{"name":"classytic-bot","email":"classytic.dev+bot@gmail.com"}],"contributors":[{"url":"https://github.com/siam923","name":"Sadman Chowdhury"}],"homepage":"https://github.com/classytic/revenue#readme","bugs":{"url":"https://github.com/classytic/revenue/issues"},"dist":{"shasum":"5d84f4c4206bb26b03c5d4d1643f4cb8b665d68b","tarball":"https://registry.npmjs.org/@classytic/revenue-stripe/-/revenue-stripe-0.1.1.tgz","fileCount":37,"integrity":"sha512-AXxAuxTWqkfuTSdJ2nH4CFmckofum1/+wnVTUDATOpOL7PtzGOoT96oIeIejiPJFtbbgJjllOYdmToRZh9dfEQ==","signatures":[{"sig":"MEUCIQDCpVqVxVD4uvCeCn5wOmWiaAqDCKYf8eAU+nAZiwjliwIgBFr6zpiuotSm9GfUq32fFpvuhlbZX1a4urKHz4Eszgg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":171298},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","module":"./dist/index.mjs","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./saas":{"types":"./dist/saas/index.d.mts","default":"./dist/saas/index.mjs"},"./connect":{"types":"./dist/connect/index.d.mts","default":"./dist/connect/index.mjs"},"./checkout":{"types":"./dist/checkout/index.d.mts","default":"./dist/checkout/index.mjs"},"./webhooks":{"types":"./dist/webhooks/index.d.mts","default":"./dist/webhooks/index.mjs"}},"gitHead":"69c5146014fb183f1721b3611bf75480e0b9b335","scripts":{"dev":"tsdown --watch","test":"vitest run","build":"tsdown","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"classytic-bot","email":"classytic.dev+bot@gmail.com"},"repository":{"url":"git+https://github.com/classytic/revenue.git","type":"git"},"_npmVersion":"10.9.3","description":"Stripe provider for @classytic/revenue — SaaS subscriptions, marketplace Connect, lean Checkout. Subpath-split so hosts tree-shake what they don't use.","directories":{},"sideEffects":false,"_nodeVersion":"22.19.0","dependencies":{"nanoid":"^5.1.6"},"_hasShrinkwrap":false,"devDependencies":{"stripe":"^22.1.1","tsdown":"^0.20.3","vitest":"^3.2.4","typescript":"^5.6.3","@types/node":"^22.0.0"},"peerDependencies":{"stripe":"^22","@classytic/revenue":">=2.1.0","@classytic/primitives":">=0.11.0"},"_npmOperationalInternal":{"tmp":"tmp/revenue-stripe_0.1.1_1784120283502_0.7718558997053919","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@classytic/revenue-stripe","version":"0.2.0","keywords":["revenue","payment","stripe","stripe-saas","stripe-connect","stripe-checkout","subscriptions","payment-intents","webhooks","provider","typescript"],"author":{"url":"https://github.com/classytic","name":"Classytic","email":"classytic.dev@gmail.com"},"license":"SEE LICENSE IN LICENSE","_id":"@classytic/revenue-stripe@0.2.0","maintainers":[{"name":"siam923","email":"classytic.dev@gmail.com"},{"name":"classytic-bot","email":"classytic.dev+bot@gmail.com"}],"contributors":[{"url":"https://github.com/siam923","name":"Sadman Chowdhury"}],"homepage":"https://github.com/classytic/revenue#readme","bugs":{"url":"https://github.com/classytic/revenue/issues"},"dist":{"shasum":"193282a23c2e4426e4b08087906692f6a4e45c16","tarball":"https://registry.npmjs.org/@classytic/revenue-stripe/-/revenue-stripe-0.2.0.tgz","fileCount":21,"integrity":"sha512-W3ldjvkpCmDa6UcEKuzr/g9yxK6oQGfvrOX7qtrCJApuF2A3k4RgRyy738cgwMAj3EK/R9Jpx0PiZpLYqumqvg==","signatures":[{"sig":"MEUCIQD482j4vNBZ2BR2SiVaKrx+B2TMhk6sfyOd0sxr06+6PwIgQ1PtmwKl/UcPlpjT3TICaF07FTk0jJ9iXU71+NqcWUk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":91439},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","module":"./dist/index.mjs","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./saas":{"types":"./dist/saas/index.d.mts","default":"./dist/saas/index.mjs"},"./connect":{"types":"./dist/connect/index.d.mts","default":"./dist/connect/index.mjs"},"./checkout":{"types":"./dist/checkout/index.d.mts","default":"./dist/checkout/index.mjs"},"./webhooks":{"types":"./dist/webhooks/index.d.mts","default":"./dist/webhooks/index.mjs"}},"gitHead":"42a1f2f9a2f13b482f76a1e64a4aacb1bcf9c4df","scripts":{"dev":"tsdown --watch","test":"vitest run","build":"tsdown","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"classytic-bot","email":"classytic.dev+bot@gmail.com"},"repository":{"url":"git+https://github.com/classytic/revenue.git","type":"git"},"_npmVersion":"11.18.0","description":"Stripe provider for @classytic/revenue — SaaS subscriptions, marketplace Connect, lean Checkout. Subpath-split so hosts tree-shake what they don't use.","directories":{},"sideEffects":false,"_nodeVersion":"22.19.0","dependencies":{"nanoid":"^5.1.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"stripe":"^22.1.1","tsdown":"^0.22.14","vitest":"^3.2.4","publint":"^0.3.23","typescript":"^5.6.3","@types/node":"^22.0.0"},"peerDependencies":{"stripe":"^22","@classytic/revenue":">=2.9.0","@classytic/primitives":">=0.23.0"},"_npmOperationalInternal":{"tmp":"tmp/revenue-stripe_0.2.0_1787031989436_0.46436367140346135","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@classytic/revenue-stripe","version":"0.2.1","keywords":["revenue","payment","stripe","stripe-saas","stripe-connect","stripe-checkout","subscriptions","payment-intents","webhooks","provider","typescript"],"author":{"url":"https://github.com/classytic","name":"Classytic","email":"classytic.dev@gmail.com"},"license":"SEE LICENSE IN LICENSE","_id":"@classytic/revenue-stripe@0.2.1","maintainers":[{"name":"siam923","email":"classytic.dev@gmail.com"},{"name":"classytic-bot","email":"classytic.dev+bot@gmail.com"}],"contributors":[{"url":"https://github.com/siam923","name":"Sadman Chowdhury"}],"homepage":"https://github.com/classytic/revenue#readme","bugs":{"url":"https://github.com/classytic/revenue/issues"},"dist":{"shasum":"8c4b5df06841170477fe4e9ae141ff459393423e","tarball":"https://registry.npmjs.org/@classytic/revenue-stripe/-/revenue-stripe-0.2.1.tgz","fileCount":21,"integrity":"sha512-+Fy8UgX/C6D7jQR00A989aAZ5J5fXJvU8LdTC+Kc8hySkbIVMR0yEdPOpA8E2ZMNnMOWrk6plNYJqRl2S39xnw==","signatures":[{"sig":"MEUCIHys7j5bDc6i6ovNJ6TgYr3XZsfpQd2/M1Kzk7C3h84WAiEAlsG5gclMAVLwnci/5DZC/HpQx7P3jVw9xUCaJX4X8JY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":92390},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","module":"./dist/index.mjs","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./saas":{"types":"./dist/saas/index.d.mts","default":"./dist/saas/index.mjs"},"./connect":{"types":"./dist/connect/index.d.mts","default":"./dist/connect/index.mjs"},"./checkout":{"types":"./dist/checkout/index.d.mts","default":"./dist/checkout/index.mjs"},"./webhooks":{"types":"./dist/webhooks/index.d.mts","default":"./dist/webhooks/index.mjs"}},"gitHead":"f9f3c39996517445be97e1017883cb584358259a","scripts":{"dev":"tsdown --watch","test":"vitest run","build":"tsdown","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"classytic-bot","email":"classytic.dev+bot@gmail.com"},"repository":{"url":"git+https://github.com/classytic/revenue.git","type":"git"},"_npmVersion":"11.19.0","description":"Stripe provider for @classytic/revenue — SaaS subscriptions, marketplace Connect, lean Checkout. Subpath-split so hosts tree-shake what they don't use.","directories":{},"sideEffects":false,"_nodeVersion":"24.20.0","dependencies":{"nanoid":"^5.1.6"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"stripe":"^22.1.1","tsdown":"^0.22.14","vitest":"^3.2.4","publint":"^0.3.23","typescript":"^5.6.3","@types/node":"^22.0.0"},"peerDependencies":{"stripe":"^22","@classytic/revenue":">=2.9.0","@classytic/primitives":">=0.23.0"},"_npmOperationalInternal":{"tmp":"tmp/revenue-stripe_0.2.1_1788105359232_0.9111044083959086","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@classytic/revenue-stripe","version":"0.2.2","description":"Stripe provider for @classytic/revenue — SaaS subscriptions, marketplace Connect, lean Checkout. Subpath-split so hosts tree-shake what they don't use.","type":"module","sideEffects":false,"main":"./dist/index.mjs","module":"./dist/index.mjs","types":"./dist/index.d.mts","keywords":["revenue","payment","stripe","stripe-saas","stripe-connect","stripe-checkout","subscriptions","payment-intents","webhooks","provider","typescript"],"author":{"name":"Classytic","email":"classytic.dev@gmail.com","url":"https://github.com/classytic"},"contributors":[{"name":"Sadman Chowdhury","url":"https://github.com/siam923"}],"license":"SEE LICENSE IN LICENSE","publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/classytic/revenue.git"},"scripts":{"build":"tsdown","dev":"tsdown --watch","typecheck":"tsc --noEmit","test":"vitest run","test:watch":"vitest","prepublishOnly":"npm run build"},"exports":{".":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"./saas":{"types":"./dist/saas/index.d.mts","default":"./dist/saas/index.mjs"},"./connect":{"types":"./dist/connect/index.d.mts","default":"./dist/connect/index.mjs"},"./checkout":{"types":"./dist/checkout/index.d.mts","default":"./dist/checkout/index.mjs"},"./webhooks":{"types":"./dist/webhooks/index.d.mts","default":"./dist/webhooks/index.mjs"}},"peerDependencies":{"@classytic/primitives":">=0.26.3","@classytic/revenue":">=2.9.0","stripe":"^22"},"devDependencies":{"@types/node":"^22.0.0","publint":"^0.3.23","stripe":"^22.1.1","tsdown":"^0.22.14","typescript":"^5.6.3","vitest":"^3.2.4"},"dependencies":{"nanoid":"^5.1.6"},"engines":{"node":">=18.0.0"},"gitHead":"876ba54b3a4b7ed4b12f0f41e3a177fb3768ef69","_id":"@classytic/revenue-stripe@0.2.2","bugs":{"url":"https://github.com/classytic/revenue/issues"},"homepage":"https://github.com/classytic/revenue#readme","_nodeVersion":"24.20.0","_npmVersion":"11.19.0","dist":{"integrity":"sha512-3nNr1oQPCyg83xe4f5UxckGkHD1wdM0dd6J/0qFr/LTQcxQ8RhMvpzQq4G3nAbYsFythU/NU1TU+SzSbJ5bdVQ==","shasum":"456da7b5f440c242bdbcb4d4707fa53b4756a3f4","tarball":"https://registry.npmjs.org/@classytic/revenue-stripe/-/revenue-stripe-0.2.2.tgz","fileCount":21,"unpackedSize":93468,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIFEZbZsSoU/Y8oKMHyAdu87Q5GqpIjP/4Aq9pJcj4vLEAiEA9YmPGvQF2LPy6wD0iEcSeoiZbHa9z34L8xR2RvVFsLg="}]},"_npmUser":{"name":"classytic-bot","email":"classytic.dev+bot@gmail.com"},"directories":{},"maintainers":[{"name":"siam923","email":"classytic.dev@gmail.com"},{"name":"classytic-bot","email":"classytic.dev+bot@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/revenue-stripe_0.2.2_1788161001848_0.3667049619324607"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-13T17:31:31.478Z","modified":"2026-08-31T07:23:22.230Z","0.1.0":"2026-06-13T17:31:31.780Z","0.1.1":"2026-07-15T12:58:03.646Z","0.2.0":"2026-08-18T05:46:29.580Z","0.2.1":"2026-08-30T15:55:59.357Z","0.2.2":"2026-08-31T07:23:21.969Z"},"bugs":{"url":"https://github.com/classytic/revenue/issues"},"author":{"name":"Classytic","email":"classytic.dev@gmail.com","url":"https://github.com/classytic"},"license":"SEE LICENSE IN LICENSE","homepage":"https://github.com/classytic/revenue#readme","keywords":["revenue","payment","stripe","stripe-saas","stripe-connect","stripe-checkout","subscriptions","payment-intents","webhooks","provider","typescript"],"repository":{"type":"git","url":"git+https://github.com/classytic/revenue.git"},"description":"Stripe provider for @classytic/revenue — SaaS subscriptions, marketplace Connect, lean Checkout. Subpath-split so hosts tree-shake what they don't use.","contributors":[{"name":"Sadman Chowdhury","url":"https://github.com/siam923"}],"maintainers":[{"name":"siam923","email":"classytic.dev@gmail.com"},{"name":"classytic-bot","email":"classytic.dev+bot@gmail.com"}],"readme":"# @classytic/revenue-stripe-connect\n\n> Stripe Connect Express provider for [`@classytic/revenue`](https://www.npmjs.com/package/@classytic/revenue).\n\nDrop-in alternative to `@classytic/revenue-manual` that ships real Stripe Connect Express onboarding, Payment Intents with `application_fee_amount`, refunds, webhook routing, and payment links. Same `PaymentProvider` contract — every other line of host code stays the same.\n\n## Install\n\n```bash\nnpm install @classytic/revenue-stripe-connect stripe @classytic/revenue @classytic/primitives\n```\n\nRequires Node 18+. Pin `stripe@^22`.\n\n## Quick start\n\n```ts\nimport { Revenue } from '@classytic/revenue';\nimport { StripeConnectProvider } from '@classytic/revenue-stripe-connect';\n\nconst stripeProvider = new StripeConnectProvider({\n  secretKey: process.env.STRIPE_SECRET_KEY!,\n  webhookSecret: process.env.STRIPE_WEBHOOK_SECRET!,\n  platformFeePercent: 1,        // 1% on every Connect destination charge\n  defaultCurrency: 'USD',\n});\n\nconst revenue = Revenue\n  .create({ defaultCurrency: 'USD' })\n  .withModels({ Transaction, Subscription })\n  .withProvider('stripe', stripeProvider)\n  .build();\n```\n\nHost checkout / refund / verify code is unchanged from `revenue-manual`:\n\n```ts\nconst { transaction, paymentIntent } = await revenue.monetization.create({\n  data: { customerId: user._id },\n  amount: 2999,\n  gateway: 'stripe',\n  metadata: {\n    stripe: { connectedAccountId: tenant.stripeAccountId }, // ← Connect destination\n  },\n});\n// paymentIntent.clientSecret → frontend Stripe Elements\n```\n\n## Hosted-checkout `methodKind` backfill\n\nFor hosted-checkout flows (Stripe Checkout, the customer picks their method on Stripe's UI) the host doesn't know the kind at intent creation. Pass `methodKind: 'other'` when creating the PaymentIntent; in your `payment_intent.succeeded` webhook handler, call `transactionRepository.backfillMethodKind(transactionId, stripePaymentIntentToKind(intent))` to record the customer's actual choice. The mapping helpers (`stripePaymentMethodToKind`, `stripePaymentIntentToKind`) collapse Stripe's full type catalogue (`card`, `us_bank_account`, `apple_pay`, `paypal`, `crypto`, …) onto the engine's canonical `PaymentMethodKind` enum so hosts never write the switch themselves; the provider's `handleWebhook` also auto-derives `methodKind` and surfaces it on `WebhookEvent.data.methodKind` for handlers that prefer to read it pre-mapped.\n\n## Migrating from `@classytic/revenue-manual`\n\n1. `npm install @classytic/revenue-stripe-connect stripe`\n2. Replace provider in your revenue config:\n   ```diff\n   - import { ManualProvider } from '@classytic/revenue-manual';\n   + import { StripeConnectProvider } from '@classytic/revenue-stripe-connect';\n   - .withProvider('manual', new ManualProvider())\n   + .withProvider('stripe', new StripeConnectProvider({ secretKey, webhookSecret }))\n   ```\n3. Send `gateway: 'stripe'` on checkout calls.\n4. Wire the webhook route (see below).\n\nThat's it. No DB migration, no engine change.\n\n## Connect Express onboarding\n\n```ts\nimport {\n  createExpressAccount,\n  createAccountLink,\n  getAccountStatus,\n} from '@classytic/revenue-stripe-connect';\n\n// 1. Create the connected account when a tenant signs up\nconst { accountId } = await createExpressAccount(stripeProvider.stripe, {\n  tenantOrgId: tenant._id,\n  email: founder.email,\n  businessName: tenant.name,\n  country: 'US',\n});\nawait tenantConfig.update(tenant._id, { stripeAccountId: accountId });\n\n// 2. Mint a Stripe-hosted KYC link, redirect the founder\nconst { url } = await createAccountLink(stripeProvider.stripe, {\n  accountId,\n  returnUrl: `https://app.example.com/onboarding/return`,\n  refreshUrl: `https://app.example.com/onboarding/refresh`,\n});\nreply.redirect(url);\n\n// 3. After return, inspect KYC state\nconst status = await getAccountStatus(stripeProvider.stripe, accountId);\nif (status.chargesEnabled) {\n  await tenantConfig.update(tenant._id, { paymentsReady: true });\n}\n```\n\n## Webhook endpoint\n\nFastify wiring (raw body parser is mandatory — Stripe signs the bytes):\n\n```ts\nimport { handleStripeWebhook } from '@classytic/revenue-stripe-connect/webhook';\n\nfastify.addContentTypeParser(\n  'application/json',\n  { parseAs: 'buffer' },\n  (_req, body, done) => done(null, body),\n);\n\nfastify.post('/webhooks/stripe', async (req, reply) => {\n  const sig = req.headers['stripe-signature'] as string;\n  try {\n    const { eventType, handled } = await handleStripeWebhook(\n      req.body as Buffer,\n      sig,\n      process.env.STRIPE_WEBHOOK_SECRET!,\n      {\n        onPaymentIntentSucceeded: async (_event, intent) => {\n          await revenue.payments.verify(intent.metadata?.transactionId);\n        },\n        onChargeRefunded: async (_event, charge) => {\n          // record refund on engine side\n        },\n        onAccountUpdated: async (_event, account) => {\n          await tenantConfig.updateByStripeAccount(account.id, {\n            paymentsReady: account.charges_enabled === true,\n          });\n        },\n      },\n      stripeProvider.stripe,\n    );\n    return reply.send({ received: true, eventType, handled });\n  } catch (err) {\n    req.log.warn({ err }, 'stripe webhook signature failed');\n    return reply.code(400).send({ error: 'signature_verification_failed' });\n  }\n});\n```\n\nSECURITY: the `try/catch` around `handleStripeWebhook` is load-bearing. Returning 400 on signature failure is required — never 200, or Stripe stops retrying real events.\n\n## Payment Links (AI-driven flows)\n\n```ts\nimport { generatePaymentLink } from '@classytic/revenue-stripe-connect';\n\nconst { url } = await generatePaymentLink(\n  { stripe: stripeProvider.stripe, defaultPlatformFeePercent: 1 },\n  {\n    lineItems: [{ price: 'price_detail_basic', quantity: 1 }],\n    connectedAccountId: tenant.stripeAccountId,\n    afterCompletion: { type: 'redirect', url: 'https://desertshine.app/thanks' },\n  },\n);\n// agent.sendWhatsApp(customer, `Pay here: ${url}`);\n```\n\n## Subscriptions\n\n```ts\nimport { createSubscription } from '@classytic/revenue-stripe-connect';\n\nconst sub = await createSubscription(stripeProvider.stripe, {\n  customerId: stripeCustomerId,\n  items: [{ price: 'price_monthly_membership' }],\n  connectedAccountId: tenant.stripeAccountId,\n  platformFeePercent: 1,\n  trialPeriodDays: 7,\n});\n```\n\n## Configuration reference\n\n| Field                  | Type                | Default | Notes                                                      |\n| ---------------------- | ------------------- | ------- | ---------------------------------------------------------- |\n| `secretKey`            | `string`            | —       | Required unless `stripe` client is supplied.               |\n| `webhookSecret`        | `string`            | —       | Required for `handleWebhook` / `verifyWebhookSignature`.   |\n| `platformFeePercent`   | `number`            | `1`     | Applied to Connect destination charges only.               |\n| `defaultCurrency`      | `string`            | `'USD'` | Lowercased before sending to Stripe.                       |\n| `apiVersion`           | `Stripe.LatestApiVersion` | SDK pin | Override when the SDK pin lags behind Stripe.        |\n| `stripe`               | `Stripe`            | —       | DI hook for tests + shared SDK clients.                    |\n\n## Stripe test mode\n\nReal-API integration tests live at `tests/unit/integration.test.ts` and are skipped unless `STRIPE_TEST_SECRET` is exported:\n\n```bash\nSTRIPE_TEST_SECRET=sk_test_xxx npm test\n```\n\nUse the [Stripe CLI](https://stripe.com/docs/stripe-cli) to forward webhooks locally:\n\n```bash\nstripe listen --forward-to localhost:3000/webhooks/stripe\n```\n\n## Capabilities\n\n```ts\nprovider.getCapabilities()\n// {\n//   supportsWebhooks: true,\n//   supportsRefunds: true,\n//   supportsPartialRefunds: true,\n//   requiresManualVerification: false,\n// }\n```\n\n## License\n\nMIT","readmeFilename":"README.md"}