Connect a payment provider
Set up Stripe or Polar so vantezzen/pay can create checkout and receive payment events.
vantezzen/pay does not move money itself. Stripe or Polar owns checkout, payment methods, invoices, taxes, subscriptions, and refunds. vantezzen/pay owns products, prices, wallets, credits, and webhook fulfillment.
Use a dedicated Stripe or Polar account for vantezzen/pay-managed products when you can. vantezzen/pay creates and syncs catalog objects automatically, so a dedicated account keeps those products separate from anything you manage by hand.
Before you start
- Open the vantezzen/pay dashboard and go to Providers.
- Make sure
NEXT_PUBLIC_APP_URLpoints to the public URL of this vantezzen/pay instance. Provider webhooks must reach that URL in production. - Use test or sandbox credentials while developing, then repeat the setup with production credentials before launch.
The dashboard setup wizard shows the exact webhook URL for each provider account. It looks like:
https://pay.example.com/api/webhooks/stripe/<provider-account-id>Stripe
1. Save a Stripe restricted key
In vantezzen/pay, choose Providers → Connect provider, select Stripe, and paste a Stripe restricted API key.
Use a restricted key (rk_test_... or rk_live_...) instead of an unrestricted
secret key when possible. In Stripe's restricted-key editor, grant:
- Products: Read and Write.
- Prices: Write.
- Checkout Sessions: Write.
- Billing Portal Sessions: Write.
- Promotion Codes: Read, only when your app passes
discountCode. - Webhook Endpoints: Write, optional but recommended for automatic webhook provisioning.
An unrestricted sk_test_... or sk_live_... key also works when a restricted
key is impractical. Keep it only in vantezzen/pay; never put it in a consuming
app. If your host has stable egress, restrict the key to that IP range or
network policy in Stripe.
2. Confirm the Stripe event destination
When the key has Webhook Endpoints: Write, vantezzen/pay creates the event destination and saves its signing secret automatically. Continue to the test step below.
If your restricted key deliberately omits that permission, vantezzen/pay shows a webhook URL. Create the destination manually:
In the Stripe Dashboard, open the Stripe Developer Workbench from the bottom of the screen. In Workbench, open Webhooks, then create a new event destination.
Use these settings:
- Event source: your Stripe Account events.
- Destination type: Webhook endpoint.
- Endpoint URL: the webhook URL copied from vantezzen/pay.
- Events:
checkout.session.completedinvoice.paidcharge.refundedcustomer.subscription.deleted
Save the destination, then copy its signing secret.
3. Save the Stripe signing secret (manual fallback)
Paste the signing secret back into vantezzen/pay. Stripe signing secrets usually
start with whsec_.
For local development, the Stripe CLI can forward events to the webhook URL and print a temporary signing secret:
stripe listen --forward-to https://pay.example.com/api/webhooks/stripe/<provider-account-id> --events checkout.session.completed,invoice.paid,charge.refunded,customer.subscription.deletedUse that CLI signing secret in your local vantezzen/pay instance.
4. Test Stripe
Create a product and price in vantezzen/pay, start checkout from your app, and complete payment in Stripe test mode. The order should become paid and the wallet should receive credits. Then trigger a refund in Stripe and confirm the webhook log records it.
Stripe supports customer-entered promotion codes through
allowPromotionCodes: true. For app-owned offer buttons, pass
discountCode: "LAUNCH10" and vantezzen/pay applies the matching active Stripe
promotion code to Checkout.
Polar
1. Choose sandbox or production
Polar sandbox and production are separate environments. Use the Polar sandbox for local development and test purchases, then create a separate production provider account in vantezzen/pay before launch.
Sandbox credentials come from sandbox.polar.sh and use the sandbox API.
Production credentials come from your production Polar organization.
2. Save a scoped Polar access token
In Polar, create an organization access token with these scopes:
products:readandproducts:writecheckouts:writecustomer_sessions:writewebhooks:write(optional but recommended for automatic webhook provisioning)
In vantezzen/pay, choose Providers → Connect provider, select Polar, pick the matching environment, and paste the organization access token.
3. Confirm the Polar webhook endpoint
When the token includes webhooks:write, vantezzen/pay creates the endpoint
and saves its secret automatically. Continue to the test step below.
Without that optional scope, vantezzen/pay shows a webhook URL. Create the endpoint manually:
In Polar, open the organization settings and add a webhook endpoint with that URL. Subscribe to:
order.paidorder.refundedsubscription.canceledsubscription.revoked
Save the endpoint, then copy its webhook secret back into vantezzen/pay.
For local Polar testing, expose your local vantezzen/pay app through a public tunnel and use that tunnel URL for the webhook endpoint. Polar needs a URL it can call directly.
4. Test Polar
Create a product and price in vantezzen/pay, start checkout from your app, and complete payment in Polar sandbox. The order should become paid and the wallet should receive credits. Then test a refund or subscription cancellation and confirm the webhook log records it.
Polar supports customer-entered discount codes through
allowPromotionCodes: true. For app-owned offer buttons, pass
discountCode: "LAUNCH10" and vantezzen/pay pre-fills that code on the Polar
checkout URL.
Troubleshooting
- Checkout cannot start: the product needs an active synced price attached to a connected provider account.
- Checkout returns a provider error: confirm the provider service is running
and that the web app/provider service share the same
PAY_PROVIDER_SERVICE_SECRET. - Events do not arrive: confirm the provider webhook URL matches the vantezzen/pay account URL exactly.
- Events fail signature validation: copy the webhook signing secret again from the provider and save it in vantezzen/pay.
- Sandbox credentials fail: make sure the provider account environment in vantezzen/pay matches the provider token or key.
- Catalog changes disappear: edit products and prices in vantezzen/pay, not in the provider dashboard. vantezzen/pay is the catalog source of truth.
For a side-by-side feature list, see Provider capability matrix.