Complete guide to Stripe integration in OpenShop, including automatic synchronization, webhook setup, and payment processing.
OpenShop automatically synchronizes products with Stripe, creating products and prices in your Stripe account when you create them in the admin dashboard. This ensures seamless payment processing without manual configuration.
When you create a product in OpenShop:
- Stripe Product Created - A corresponding product is created in Stripe
- Stripe Price Created - A price is created for the product's base price
- Automatic Linking - The product and price IDs are stored in OpenShop for checkout
- Product edits: Updating name, description, or images syncs to the corresponding Stripe Product. Description is only updated if non-empty. Up to 8 images are sent to Stripe.
- Base price change: When the product base price changes, a new Stripe Price is created; existing Prices are preserved for historical data.
- Variant prices: Variants with
hasCustomPricecreate dedicated Stripe Prices. Variants without a custom price use the base price. Secondary variant set (if used) follows the same rules. - KV storage: Product records in KV are merged on update, and image fields are normalized to arrays to maintain consistency across the UI and Stripe sync.
OpenShop supports two types of checkout:
- Single Item Checkout - Direct checkout from product page
- Cart Checkout - Multi-item checkout from shopping cart
Both create secure Stripe Checkout Sessions that handle payment processing.
- Sign up for a Stripe account
- Navigate to Developers → API keys
- Copy your Secret key (for server-side use)
- Copy your Publishable key (for client-side use)
- Test Mode: Use
sk_test_andpk_test_keys for development - Live Mode: Use
sk_live_andpk_live_keys for production
Always test thoroughly in test mode before going live.
Add your Stripe keys during npm run setup or manually:
Local Development (.env file):
STRIPE_SECRET_KEY=sk_test_your_secret_key
VITE_STRIPE_PUBLISHABLE_KEY=pk_test_your_publishable_keyProduction (via Wrangler):
wrangler secret put STRIPE_SECRET_KEYThe publishable key should be set as an environment variable in your wrangler.toml or site configuration.
Webhooks allow you to track order completion and payment events in real-time.
- Stripe Dashboard → Developers → Webhooks
- Add Endpoint:
https://your-project.workers.dev/api/stripe-webhook - Select Events:
checkout.session.completed- Fired when a checkout session is completedpayment_intent.succeeded- Fired when a payment is successfully processed
Stripe webhooks include a signature that verifies the request came from Stripe. OpenShop validates this signature to ensure webhook security.
You can extend OpenShop to handle webhook events by modifying the webhook handler in src/routes/public/checkout.js. Common use cases:
- Update order status in your system
- Send confirmation emails
- Update inventory
- Trigger fulfillment processes
- Customer adds items to cart - Items stored in browser localStorage
- Customer clicks checkout - Creates Stripe Checkout Session
- Stripe Checkout - Customer enters payment details on Stripe's secure page
- Payment Processing - Stripe processes the payment
- Success Redirect - Customer redirected to success page
- Webhook Notification - (Optional) Your server notified of payment completion
Checkout sessions are configured with:
- Line Items: Products and quantities from cart
- Success URL: Where to redirect after successful payment
- Cancel URL: Where to redirect if customer cancels
- Currency: From product configuration (default: USD)
- Mode: Payment (one-time) or Subscription (recurring)
Use these test card numbers in Stripe test mode:
- Success:
4242 4242 4242 4242 - Decline:
4000 0000 0000 0002 - Requires Authentication:
4000 0025 0000 3155
Use any future expiry date, any 3-digit CVC, and any postal code.
- Successful Payment - Use success test card
- Declined Payment - Use decline test card
- 3D Secure - Use requires authentication card
- Refunds - Process refunds from Stripe Dashboard
- ✅ Never expose your secret key in client-side code
- ✅ Always use HTTPS in production
- ✅ Validate webhook signatures
- ✅ Use test mode during development
- ✅ Cache product data when possible
- ✅ Use Stripe's idempotency keys for retries
- ✅ Handle webhook events asynchronously
- ✅ Handle payment failures gracefully
- ✅ Provide clear error messages to customers
- ✅ Log payment errors for debugging
- ✅ Implement retry logic for transient failures
Issue: Products not syncing to Stripe
- Solution: Check that
STRIPE_SECRET_KEYis correctly set and has proper permissions
Issue: Checkout session creation fails
- Solution: Verify product has valid
stripePriceIdand price exists in Stripe
Issue: Webhooks not received
- Solution: Check webhook endpoint URL is correct and accessible, verify webhook signature validation
Issue: Payment succeeds but order not recorded
- Solution: Check webhook handler is properly configured and processing events
For more help, see the Troubleshooting Guide.