Stripe Integration Service Reference
Service Overview
StripeIntegrationService connects verified Stripe webhook events to Subscrio customers and subscriptions. Your infrastructure is responsible for signature verification—call processStripeEvent only after Stripe’s SDK validates the payload. The built-in handlers now cover customer lifecycle, subscription lifecycle, successful invoices, and a helper for bootstrapping Subscrio subscriptions that reference Stripe customers/prices.
- Store the Subscrio customer key in Stripe metadata (
subscrioCustomerKey) whenever you create a Stripe customer or subscription—this allows webhooks to backfillCustomer.externalBillingIdautomatically. - Persist Stripe customer IDs in
Customer.externalBillingId. If it’s missing, the webhook handler will backfill it using the metadata described above. - Persist Stripe price IDs in
BillingCycle.externalProductIdso events can map to billing cycles (and therefore plans). Once the price is mapped, Subscrio can create and update subscriptions with no additional customization.
Accessing the Service
import { Subscrio } from '@subscrio/core';
const subscrio = new Subscrio({ database: { connectionString: process.env.DATABASE_URL! } });
const stripeService = subscrio.stripe;
Method Catalog
| Method | Description | Returns |
|---|---|---|
processStripeEvent | Entry point for verified Stripe webhook events | Promise<void> |
createStripeSubscription | Helper to create a Subscrio subscription tied to Stripe metadata | Promise<Subscription> |
createCheckoutSession | Generate Stripe Checkout URL with automatic customer creation and subscription linking | Promise<{ url: string; sessionId: string }> |
(Handlers invoked internally by processStripeEvent are described for completeness.)
Method Reference
processStripeEvent
Description
Routes a verified Stripe.Event to the appropriate handler (subscription lifecycle or invoice events).
Signature
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
event | Stripe.Event | Yes | Stripe webhook payload that your endpoint already verified. |
Returns
Promise<void>
Expected Results
- Switches on
event.typeand handles: customer.createdcustomer.updatedcustomer.deletedcustomer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deletedinvoice.payment_succeeded- Unhandled event types are ignored (logged in development).
- Missing entities (customer, plan, billing cycle, subscription) throw so you can fix data mapping.
Potential Errors
| Error | When |
|---|---|
NotFoundError | Customer, billing cycle, plan, or subscription cannot be resolved. |
ValidationError | Required data such as externalBillingId is missing. |
Example
import Stripe from 'stripe';
const event = stripe.webhooks.constructEvent(body, sig, webhookSecret);
await stripeService.processStripeEvent(event);
Internal Handlers
handleCustomerCreated/Updated- Resolves existing customers by
externalBillingIdorsubscrioCustomerKeymetadata and backfills the Stripe customer ID. handleCustomerDeleted- Clears
externalBillingIdwhen Stripe deletes a customer. handleSubscriptionCreated- Resolves the customer, billing cycle (via
externalProductId), and owning plan. - Subscription Linking Behavior:
- First checks if a subscription with the Stripe subscription ID already exists (already linked).
- If metadata contains
subscrioSubscriptionKey, looks up the existing Subscrio subscription by key. - If found and belongs to the customer, updates the existing subscription (links Stripe ID, updates plan/billing cycle, preserves feature overrides).
- If no existing subscription found, creates a new subscription.
- Sets
stripeSubscriptionId, period dates, and metadata on the subscription. handleSubscriptionUpdated- Syncs plan/billing-cycle changes, period dates, and cancellation status for an existing subscription.
handleSubscriptionDeleted- Calls
subscription.expire()when Stripe marks the subscription deleted so the computed status becomesexpired. handlePaymentSucceeded- Updates the subscription’s
currentPeriodStart/currentPeriodEndfrom the invoice line’s billing period after a successful payment.
createStripeSubscription
Description
Bootstraps a Subscrio subscription linked to Stripe metadata (customer/billing-cycle) while you build deeper automation.
Signature
createStripeSubscription(
customerKey: string,
planKey: string,
billingCycleKey: string,
stripePriceId: string
): Promise<Subscription>
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
customerKey | string | Yes | Customer key (must have externalBillingId). |
planKey | string | Yes | Plan being subscribed to. |
billingCycleKey | string | Yes | Billing cycle governing the cadence. |
stripePriceId | string | Yes | Stripe price identifier (stored for reference). |
Returns
Promise<Subscription> – the saved domain subscription (with placeholder stripeSubscriptionId).
Expected Results
- Validates entities and ensures customer has
externalBillingId. - Generates a subscription key (or use one you pass in metadata), sets activation/current period timestamps, and saves the subscription.
- Leaves a placeholder
stripeSubscriptionIdfor later reconciliation—webhooks will attach the real Stripe subscription once you pass the metadata described above.
Potential Errors
| Error | When |
|---|---|
NotFoundError | Customer, plan, or billing cycle missing. |
ValidationError | Customer lacks externalBillingId. |
Example
const sub = await stripeService.createStripeSubscription(
'cust_123',
'pro-plan',
'pro-plan-annual',
'price_ABC123'
);
console.log(sub.key);
createCheckoutSession
Description
Generates a Stripe Checkout Session URL for subscription purchases. This helper method: - Automatically creates Stripe customers if they don't exist (sets proper metadata) - Supports linking to existing Subscrio subscriptions via subscriptionKey parameter - Provides full access to Stripe Checkout options including quantity, trial periods, and custom metadata - Sets all required metadata for webhook reconciliation
When a customer completes checkout, the webhook handler will: - If subscriptionKey was provided: update the existing subscription (link Stripe ID, update plan/billing cycle) - If no subscriptionKey: create a new subscription
Signature
createCheckoutSession(params: {
customerKey: string;
billingCycleKey: string;
subscriptionKey?: string; // Optional: existing subscription key to update
stripeSecretKey?: string; // Optional: override config Stripe key
successUrl: string;
cancelUrl: string;
// Convenience options
quantity?: number;
customerEmail?: string;
customerName?: string;
allowPromotionCodes?: boolean;
billingAddressCollection?: 'auto' | 'required';
paymentMethodTypes?: Stripe.Checkout.SessionCreateParams.PaymentMethodType[];
trialPeriodDays?: number;
metadata?: Record<string, string>; // Additional custom metadata
// Full Stripe API access
stripeOptions?: Partial<Stripe.Checkout.SessionCreateParams>;
}): Promise<{ url: string; sessionId: string }>
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
customerKey | string | Yes | Subscrio customer key. Stripe customer will be created if missing. |
billingCycleKey | string | Yes | Billing cycle key (must have externalProductId set to Stripe price ID). |
subscriptionKey | string | No | Existing Subscrio subscription key to link/update. If provided, webhook will update this subscription instead of creating new. |
stripeSecretKey | string | No | Stripe secret key (overrides config.stripe.secretKey). |
successUrl | string | Yes | URL to redirect after successful checkout. |
cancelUrl | string | Yes | URL to redirect if checkout is cancelled. |
quantity | number | No | Subscription quantity (default: 1). |
customerEmail | string | No | Pre-fill customer email in checkout. |
customerName | string | No | Pre-fill customer name in checkout. |
allowPromotionCodes | boolean | No | Enable promotion code input in checkout. |
billingAddressCollection | 'auto' \| 'required' | No | Control billing address collection. |
paymentMethodTypes | PaymentMethodType[] | No | Restrict allowed payment methods. |
trialPeriodDays | number | No | Set trial period duration in days. |
metadata | Record<string, string> | No | Additional custom metadata to pass through. |
stripeOptions | Partial<SessionCreateParams> | No | Full Stripe API access for any checkout option. |
Returns
Promise<{ url: string; sessionId: string }> – Checkout URL to redirect user and session ID for tracking.
Expected Results
- Stripe Customer Creation: If customer doesn't have
externalBillingId, creates Stripe customer automatically withsubscrioCustomerKeymetadata. - Metadata Setup: Sets
subscrioCustomerKeyand optionallysubscrioSubscriptionKeyin both session and subscription metadata. - Subscription Linking: If
subscriptionKeyprovided, validates subscription exists and belongs to customer. Webhook will update this subscription when checkout completes. - Full Stripe Support: All Stripe Checkout options accessible via convenience parameters or
stripeOptionsfor complete API access.
Potential Errors
| Error | When |
|---|---|
ConfigurationError | Stripe secret key not provided (neither in config nor parameter). |
NotFoundError | Customer, billing cycle, or subscription (if key provided) not found. |
ValidationError | Billing cycle missing externalProductId, invalid URLs, etc. |
ConflictError | Subscription key provided but doesn't belong to customer. |
Example: New Subscription
// Create checkout for new subscription
const { url, sessionId } = await subscrio.stripe.createCheckoutSession({
customerKey: 'customer_123',
billingCycleKey: 'pro-monthly',
successUrl: 'https://yourapp.com/success',
cancelUrl: 'https://yourapp.com/cancel',
quantity: 2,
allowPromotionCodes: true,
customerEmail: 'user@example.com'
});
// Redirect user to url
window.location.href = url;
Example: Update Existing Subscription
// Create checkout to update existing subscription (change plan/billing cycle)
const { url, sessionId } = await subscrio.stripe.createCheckoutSession({
customerKey: 'customer_123',
billingCycleKey: 'pro-annual', // New billing cycle
subscriptionKey: 'sub_456', // Existing subscription to update
successUrl: 'https://yourapp.com/success',
cancelUrl: 'https://yourapp.com/cancel'
});
// When checkout completes, webhook will update subscription 'sub_456'
// with new plan/billing cycle and link Stripe subscription ID
Example: Full Stripe API Access
// Use stripeOptions for any Stripe Checkout parameter
const { url } = await subscrio.stripe.createCheckoutSession({
customerKey: 'customer_123',
billingCycleKey: 'pro-monthly',
successUrl: 'https://yourapp.com/success',
cancelUrl: 'https://yourapp.com/cancel',
stripeOptions: {
consent_collection: {
terms_of_service: 'required'
},
phone_number_collection: {
enabled: true
},
custom_fields: [
{
key: 'company_name',
label: { type: 'custom', custom: 'Company Name' },
type: 'text'
}
]
}
});
Related Workflows
- Webhook verification – Your HTTP endpoint must verify Stripe signatures with
stripe.webhooks.constructEvent(or equivalent) before callingprocessStripeEvent. - Customer metadata – Attach
subscrioCustomerKey(and optionallysubscrioSubscriptionKey) to every Stripe customer and subscription you create so Subscrio can reconcile records automatically. - Billing-cycle mapping – Store Stripe price IDs in
BillingCycle.externalProductIdto map subscriptions/billing cycles accurately. - Reference guide – See
docs/reference/how-to-integrate-with-stripe.mdfor an end-to-end walkthrough that covers setup, metadata, and webhook handling.