Skip to main content
Stripe is the standard for online payments. vly’s Stripe integration covers the full surface: one-time charges, subscriptions, marketplaces (Connect), billing portals, and webhook handling. You can add Stripe to any project in three lines of prompt.

Prerequisites

Setup

1

Get your Stripe API keys

In your Stripe dashboard, copy:
  • Publishable key (starts with pk_test_... or pk_live_...)
  • Secret key (starts with sk_test_... or sk_live_...)
Use test mode keys (pk_test_..., sk_test_...) for development.
2

Connect Stripe in vly

Two paths:
3

Define your products and prices in Stripe

In the Stripe dashboard → Products, create the products you want to sell. For subscriptions, configure recurring prices.Note the Price IDs (starts with price_...). You’ll reference these in vly.
4

Ask vly to wire up checkout

vly creates the checkout session action, the success/cancel routes, the webhook handler, and the user-facing button.
5

Set up the webhook endpoint

vly tells you the webhook URL after the previous step:
  1. In Stripe → Developers → Webhooks, click Add endpoint.
  2. Paste the URL above.
  3. Select events: checkout.session.completed, customer.subscription.updated, customer.subscription.deleted, invoice.payment_failed.
  4. Copy the signing secret (starts with whsec_...).
  5. Paste it back into vly’s integration settings as STRIPE_WEBHOOK_SECRET.
Test the webhook by clicking Send test webhook in the Stripe dashboard.
6

Test the flow end-to-end

  1. Open your preview deploy.
  2. Sign up as a test user.
  3. Click Upgrade to Pro.
  4. Use Stripe’s test card: 4242 4242 4242 4242, any future expiry, any CVC.
  5. After successful checkout, refresh — your user should now show the Pro plan.
Stripe has a full list of test cards for testing failures, 3D Secure, and other edge cases.

Configuration reference

string
required
Your Stripe publishable key. Safe to expose to the client. Starts with pk_test_ or pk_live_.
string
required
Your Stripe secret key. Server-only. Starts with sk_test_ or sk_live_.
string
required
Your Stripe webhook signing secret. Server-only. Starts with whsec_. Required to verify webhook authenticity.
string
The Stripe price IDs you’ll reference. Add one per product / tier — e.g., STRIPE_PRO_PRICE_ID, STRIPE_BUSINESS_PRICE_ID.

Code patterns

The patterns vly generates. You can hand-edit any of them in Code mode.

Creating a checkout session

convex/stripe.ts

Webhook handler

convex/http.ts

Customer billing portal

convex/stripe.ts
The portal handles upgrade, downgrade, payment method updates, invoices — all built by Stripe, no UI work on your side.

Going live

When you’re ready for real payments:
1

Activate your Stripe account

In the Stripe dashboard, complete account verification (business details, bank account, identity).
2

Get live mode keys

Switch the Stripe dashboard to live mode (top-right toggle). Copy pk_live_... and sk_live_....
3

Update vly's secrets for production

In vly, Settings → Environments → Production → Edit secrets. Replace the test keys with the live keys.
4

Register a production webhook

Add a webhook endpoint in Stripe (live mode), pointing to your production URL: https://yourapp.com/api/stripe-webhook. Copy the new signing secret into production secrets.
5

Switch test → live in your code

No code change needed if you’ve used process.env.STRIPE_* everywhere — the secrets just point to live keys now.
6

Test with a real card

Make a small charge on a real card (you can refund yourself). Confirms end-to-end live flow.

Common features

Recurring billing, trial periods, prorating on upgrade/downgrade. Use the billing portal for self-service.
Multi-party payments — buyers pay sellers, you take a cut. Use Stripe Connect with Express or Standard accounts. See the marketplace recipe.
Bill customers manually or send recurring invoices. Useful for B2B contracts.
Stripe Tax automatically calculates and remits sales tax / VAT. Enable in Stripe dashboard; vly’s checkout supports it out of the box.
stripe.refunds.create({ charge: chargeId }). Add an admin-only “Refund” action in your support tool.
Stripe sends webhook events when disputes are filed. Vly can wire these into a Slack notification or admin dashboard.

Troubleshooting

The STRIPE_WEBHOOK_SECRET doesn’t match the webhook endpoint. Each endpoint has its own secret — re-copy from the Stripe dashboard for the correct endpoint.
The price ID exists in test mode but you’re using live keys (or vice versa). Recreate the price in the right mode, or switch keys to match.
The portal change triggers a customer.subscription.updated webhook. Make sure your webhook handler is processing this event and updating your local database.
Confirm the webhook URL is reachable (not behind auth). For local development, use the Stripe CLI to forward events to localhost.

Marketplace recipe

Complete walkthrough — Stripe Connect, escrow, payouts.

Subscription billing recipe

Multi-tier, trials, billing portal.

Webhooks pattern

The general pattern for any webhook-based integration.
Last modified on April 18, 2026