A powerful Strapi plugin to easily manage and sync your Stripe Products, Prices, Coupons and more – directly in your project.
npm install @strawbinary-io/stripe-strapi-plugin
A powerful Strapi plugin to easily manage and sync your Stripe Products, Prices, Coupons and more – directly in your project.
Core Contributor: Strawbinary
Follow: @strawbinary
Website: Strawbinary
---
This Strapi plugin synchronizes Stripe products, prices, coupons, and promotion codes with dedicated content types. It imports the full catalog once during bootstrap, keeps everything up to date through Stripe webhooks, and can optionally run on a cron schedule. All data flows through the Strapi Document Service to respect draft/publish workflows.
- Provides the Stripe Products collection type (name, stripeProductId, description, image URL, tax code, active flag, and a flexible metadata component). Coupons and promotion codes reference products directly through relations.
- Provides the Stripe Prices collection type (relation to a Stripe product, stripePriceId, billing details, recurring configuration, tiers, currency, metadata, and lookup helpers).
- Provides the Stripe Coupons collection type (relation to many Stripe products, stripeCouponId, duration configuration, amount-or-percent off fields, redeem-by, metadata, validity flags, and live Stripe statistics).
- Provides the Stripe Promotion Codes collection type (relation to a Stripe coupon, stripePromotionCodeId, code, active flag, redemption/customer limits, restrictions, metadata, and live Stripe statistics).
- Performs an initial import of all Stripe products when the Strapi app starts and keeps the entire catalog aligned afterwards.
- Optional cron job (default: every 10 minutes) that keeps Strapi in sync with Stripe for products, prices, coupons, and promotion codes.
- Webhook endpoint POST /api/stripe-strapi-plugin/webhooks/stripe handling product., price., coupon., and promotion_code. events.
- Service API strapi.plugin('stripe-strapi-plugin').service('stripeSync') you can call from custom jobs or scripts (helpers for products, prices, coupons, promotion codes, and a combined syncAll).
- Strapi v5 with the Document Service enabled (the plugin relies on strapi.documents for upserts).
- Stripe secret key with permissions to read products, prices, coupons, and promotion codes (Stripe API Version: 2025-10-29.clover).
- Optional Stripe webhook secret for product, price, coupon, and promotion-code events.
- Node.js version that matches your Strapi project requirements.
``bash`
npm install @strawbinary-io/stripe-strapi-pluginor
yarn add @strawbinary-io/stripe-strapi-plugin
Register the plugin in config/plugins.ts:
`ts`
export default ({ env }) => ({
'stripe-strapi-plugin': {
enabled: true,
config: {
secretKey: env('STRIPE_SECRET_KEY'),
webhookSecret: env('STRIPE_WEBHOOK_SECRET'),
alwaysRunMigration: false,
sync: {
cron: {
enabled: true,
expression: '0 /10 *', // Default: every 10 minutes
},
},
},
},
});
Note: You can provide the key as secretKey, stripeSecretKey, or via the STRIPE_SECRET_KEY environment variable. webhookSecret can also come from STRIPE_WEBHOOK_SECRET.
| Option | Type | Description |
| ------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| secretKey / stripeSecretKey | string | Stripe secret key used for API calls. Falls back to process.env.STRIPE_SECRET_KEY when not explicitly set. |webhookSecret
| | string | Secret from the Stripe webhook configuration, required for signature verification. Falls back to process.env.STRIPE_WEBHOOK_SECRET. |alwaysRunMigration
| | boolean | Forces the initial product import to run on every bootstrap. Default: false (skips once the first run succeeded). |sync.cron.enabled
| | boolean | Enables or disables the automatic cron sync. Default: false. |sync.cron.expression
| | string | Cron expression (refer to Strapi Documentation). Default: 0 /10 *. |
The webhook controller needs access to the raw request body (includeUnparsed: true) to validate Stripe signatures. Update config/middlewares.ts accordingly:
`ts`
export default [
'strapi::cors',
'strapi::logger',
{
name: 'strapi::body',
config: {
includeUnparsed: true,
},
},
'strapi::session',
'strapi::favicon',
'strapi::public',
];
1. Create a webhook in Stripe pointing to https://.product.created
2. Subscribe to at least , product.updated, product.deleted, price.created, price.updated, price.deleted, coupon.created, coupon.updated, coupon.deleted, promotion_code.created, and promotion_code.updated.webhookSecret
3. Store the Stripe webhook secret () in the plugin configuration.
The endpoint validates every request via the stripe-signature header. If validation fails or the secret is missing, the controller responds with an error status.
- Initial import: During bootstrap the plugin checks the plugin store for a previous migration run. If none is found (or alwaysRunMigration is true), every Stripe product is imported once and published.await strapi.plugin('stripe-strapi-plugin').service('stripeSync').syncAll();
- Cron sync: When enabled, the cron job periodically calls Stripe's APIs and upserts products, prices, coupons, and promotion codes (in that order). The configured schedule is logged and cleaned up during shutdown.
- Webhooks: Stripe sends product, price, coupon, and promotion-code events that are immediately upserted or deleted through the Document Service. Unsupported events are logged at debug level.
- Manual sync: Custom jobs can call whenever needed (products + prices + coupons + promotion codes). Dedicated helpers syncProducts, syncPrices, syncCoupons, and syncPromotionCodes are also exposed.
- Deletion behaviour for Prices: Stripe only supports archiving prices. When you delete a Stripe Price entry in Strapi we archive the price in Stripe, but it still exists in your Stripe account and will therefore be recreated in Strapi on the next webhook or cron sync. Keep this in mind when cleaning up your catalog.
- plugin::stripe-strapi-plugin.stripe-product: Stores the product name, unique stripeProductId, optional description and image URL, required taxCode (Enum mapped to Stripe tax codes), boolean active flag, and the metadata component. Prices, coupons, and promotion codes link back to the product through relations.plugin::stripe-strapi-plugin.stripe-price
- : Stores every Stripe price (stripePriceId) including the related product, currency, billing scheme, recurring configuration, tiers, unit amounts, tax behavior, metadata and Stripe lookup keys.plugin::stripe-strapi-plugin.stripe-coupon
- : Stores Stripe coupons (stripeCouponId) including duration, amount/percent configuration, redeem-by timestamp, redemption counters, relations to the products the coupon applies to, metadata, and the live Stripe status flags.plugin::stripe-strapi-plugin.stripe-promotion-code
- : Stores promotion codes (stripePromotionCodeId) including the human-readable code, activation flags, redemption limits, per-customer restrictions, relations to the parent coupon, metadata, and live Stripe stats.stripe.price-custom-unit-amount
- Component : Mirrors Stripe's custom_unit_amount object (minimum/maximum/preset).stripe.price-recurring
- Component : Captures recurring settings (interval, interval count, meter, usage type).stripe.price-tier
- Component : Stores tier definitions (flat and unit amounts plus the upper bound).stripe.promotion-code-restrictions
- Component : Captures the promotion-code restriction values (first-time flag and optional minimum amount/currency).component.key-value-pairs`: Captures arbitrary Stripe metadata as key/value pairs and is kept in sync both ways.
- Component
Configure fine-grained permissions under Roles & Permissions → Plugins.
We welcome contributions, issues and feature requests!
- Report bugs or request features in the issue tracker