@ossy/integration-stripe
v1.3.3
Published
Stripe integration for the Ossy platform. Provides subscription billing via Stripe Checkout, customer portal access, webhook handling, and a subscription document schema.
Readme
@ossy/integration-stripe
Stripe integration for the Ossy platform. Provides subscription billing via Stripe Checkout, customer portal access, webhook handling, and a subscription document schema.
What this package provides
| Primitive | File | Id / export |
|---|---|---|
| Integration | stripe.integration.js | stripe |
| Action | checkout.action.js | @ossy/stripe/actions/create-checkout |
| Task | checkout.task.js | @ossy/stripe/tasks/create-checkout |
| Action | billing-portal.action.js | @ossy/stripe/actions/billing-portal |
| Task | billing-portal.task.js | @ossy/stripe/tasks/billing-portal |
| API | webhook.api.js | POST /api/v0/webhooks/stripe |
| Schema | subscription.schema.js | @ossy/integration-stripe/schema/subscription (subscriptionSchema) |
Required environment variables
| Variable | Required | Description |
|---|---|---|
| STRIPE_SECRET_KEY | Yes | Stripe secret key (sk_live_… or sk_test_…) |
| STRIPE_WEBHOOK_SECRET | Yes | Webhook signing secret from Stripe Dashboard |
| STRIPE_PRICE_ID | Yes | Default monthly subscription Price ID |
The integration is skipped at startup if any variable is missing.
Setting up Stripe products and prices
- Go to the Stripe Dashboard → Products.
- Create a product (e.g. "Ossy Pro").
- Add a recurring price (monthly or annual). Copy the Price ID (
price_…). - Set
STRIPE_PRICE_IDto that value.
Using the checkout action from the frontend
Call POST /actions with:
{
"action": "@ossy/stripe/actions/create-checkout",
"payload": {
"email": "[email protected]",
"successUrl": "https://app.example.com/billing/success",
"cancelUrl": "https://app.example.com/billing",
"priceId": "price_optional_override"
}
}Response:
{ "url": "https://checkout.stripe.com/pay/cs_…" }Redirect the user to url. On success, Stripe redirects to successUrl.
Opening the billing portal
Call POST /actions with:
{
"action": "@ossy/stripe/actions/billing-portal",
"payload": {
"email": "[email protected]",
"returnUrl": "https://app.example.com/billing"
}
}Response:
{ "url": "https://billing.stripe.com/session/…" }Redirect the user to url so they can manage their subscription, update payment methods, and download invoices.
Webhook setup
- In the Stripe Dashboard → Webhooks, add an endpoint:
- URL:
https://your-domain.com/api/v0/webhooks/stripe - Events to listen to:
checkout.session.completedcustomer.subscription.deletedinvoice.payment_failed
- URL:
- Copy the Signing secret and set it as
STRIPE_WEBHOOK_SECRET.
Note: The platform must provide the raw request body as
req.rawBodyfor signature verification to work. Stripe's SDK requires the exact bytes received from the network.
Handled events
| Event | Effect |
|---|---|
| checkout.session.completed | Subscription activated (logs workspace + subscription ID) |
| customer.subscription.deleted | Subscription cancelled (log + TODO: update workspace state) |
| invoice.payment_failed | Sends a payment failure warning email via the email integration |
The checkout.session.completed and customer.subscription.deleted handlers contain TODO comments — wire them up to your domain model (e.g. using Aggregate.Of from @ossy/event-store) to persist subscription state.
Subscription schema (ADR 0006)
The @ossy/integration-stripe/schema/subscription schema stores subscription metadata alongside workspace or user documents:
| Field | Type | Description |
|---|---|---|
| stripeCustomerId | text | Stripe Customer ID (cus_…) |
| stripeSubscriptionId | text | Stripe Subscription ID (sub_…) |
| status | text | active, cancelled, or past_due |
| currentPeriodEnd | number | Unix timestamp of current billing period end |
| priceId | text | Active Price ID |
Create a subscription document via the @ossy/resources/tasks/create action and pass type: '@ossy/integration-stripe/schema/subscription'.
import { subscriptionSchema } from '@ossy/integration-stripe'
subscriptionSchema.id
// => '@ossy/integration-stripe/schema/subscription'Migration from resource templates
| Before | After |
|---|---|
| stripe/actions/create-checkout | @ossy/stripe/actions/create-checkout |
| stripe/actions/billing-portal | @ossy/stripe/actions/billing-portal |
| (task shared action id) | @ossy/stripe/tasks/create-checkout |
| (task shared action id) | @ossy/stripe/tasks/billing-portal |
| @ossy/integration-stripe/subscription | @ossy/integration-stripe/schema/subscription |
| subscriptionResource export | subscriptionSchema |
Advanced: using the raw Stripe client
The integration exposes the underlying Stripe SDK instance as stripe.stripe for any API calls not covered by the built-in helpers:
export async function run({ integrations }) {
const { stripe } = integrations.get('stripe')
const invoices = await stripe.invoices.list({ limit: 10 })
}