ZuploZuplo
LoginSign Up
  • Documentation
  • API Reference
Introduction
Getting Started
    Develop using the Portal
      1 - Setup Your Gateway2 - Rate Limiting3 - API Key Auth4 - Deploy5 - Dynamic Rate LimitingMCP - Quick start
    Develop Locally
      1 - Setup Your Gateway2 - Rate Limiting3 - API Key Auth
Concepts
Development
Policies
Handlers
API Keys
MCP Server
MCP Gateway
AI Gateway
Developer Portal
Monetization
    OverviewQuickstart
    Concepts
    Guides
      Stripe IntegrationDeveloper PortalMonetization PolicySubscription LifecyclePrivate PlansTax CollectionGoing to Production
    Reference
    TroubleshootingThird-Party IntegrationsCustom Monetization
Deploying & Source Control
Observability
Networking & Infrastructure
Account Management
Programming API
Build with AI
Zuplo CLI
Migration Guides
Platform LimitsSecuritySupportTrust & ComplianceChangelog
powered by Zudoku
Guides

Stripe Integration

Zuplo uses Stripe to collect payments. Zuplo is the system of record for plans, subscriptions, features, entitlements, and metered usage; Stripe is the system of record for money — customers, invoices, and payment collection.

How it works

The integration flow:

  1. You define plans, features, and meters in Zuplo
  2. You connect your Stripe account via the Zuplo Portal
  3. Plans, features, and rate cards stay in Zuplo's catalog — Stripe is used only at billing time
  4. Customers subscribe through your Developer Portal via Stripe Checkout
  5. Stripe collects the payment method and Zuplo creates the subscription with an API key scoped to the plan's entitlements
  6. As the customer uses the API, the monetization policy meters usage in real time
  7. At the end of each billing period, Zuplo issues a Stripe Invoice for fixed fees and usage-based charges

Throughout this flow, Zuplo is the source of truth for access control, plans/rate cards, and metered usage. Stripe is the source of truth for payment state and tax. Stripe Subscriptions, Products, Prices, and Billing Meters are not used — Zuplo manages those concepts internally and only materializes them in Stripe at the moment a charge is needed (as invoice line items).

Connecting your Stripe account

Via the Zuplo Portal

  1. Open your project's Services page, select the Monetization Service, then go to Payment Provider
  2. Click Configure on the Stripe card
  3. Paste your Stripe API Key
  4. Click Save

The connection authorizes Zuplo to manage Stripe objects on your behalf — specifically Customers, Checkout Sessions, Customer Portal Sessions, Invoices, and Tax Calculations. See What Zuplo creates in Stripe for the full list.

Test mode vs. live mode

Connect with a Stripe test key (sk_test_...) first to validate your configuration end-to-end. Test mode uses Stripe's test card numbers (e.g., 4242 4242 4242 4242) and never charges real money.

When you're ready to go live, configure a separate Zuplo environment (e.g., Production) with your live key (sk_live_...).

Use one Stripe key type per Zuplo environment — do not replace a test key with a live key in the same environment. Test mode and live mode are separate environments in Stripe. Products, customers, and subscriptions created in test mode don't transfer to live mode and vice versa.

Using a Stripe restricted key

Zuplo accepts both secret keys (sk_test_*, sk_live_*) and restricted keys (rk_test_*, rk_live_*) when you connect Stripe. For production, use a restricted key — it follows the principle of least privilege and limits the blast radius if the credential is ever leaked.

A Monetization V3 restricted key needs the following eight permissions. Leave every other permission set to None.

Stripe permissionLevelWhy Zuplo needs it
Connect → AccountsReadVerifies the key on install and reads basic account details (country, currency)
Core → CustomersWriteCreates and updates Stripe Customers when developers subscribe
Core → Payment MethodsReadDisplays saved cards in the customer portal
Checkout → Checkout SessionsWriteCreates checkout sessions when developers add a payment method
Billing → Customer portalWriteCreates customer-portal sessions for self-service plan management
Billing → InvoicesWriteIssues, finalizes, and pays invoices for metered usage (also covers Invoice items)
Tax → Tax Calculations and TransactionsWriteCalculates tax via Stripe Tax when tax collection is enabled
Webhook → Webhook Endpoints and Event DestinationsWriteRegisters the webhook Zuplo uses to receive payment events

Zuplo doesn't use Stripe Subscriptions, Products, Prices, Payment Intents, Setup Intents, Refunds, or Stripe Billing Meters — leave all of those at None.

Create the restricted key

  1. In the Stripe Dashboard, go to Developers → API keys → Create restricted key.
  2. Name the key something recognizable, for example Zuplo Monetization (test) or Zuplo Monetization (production).
  3. For each of the eight permissions above, set the level shown in the table.
  4. Click Create key, copy the value (rk_test_... or rk_live_...), and paste it into the Monetization Service's Payment Provider screen (open your project's Services page, then the Monetization Service) in your Zuplo project.

Use a test restricted key (rk_test_*) for preview and working-copy environments, and a live restricted key (rk_live_*) for production. Zuplo rejects a live key on a non-production environment and vice versa.

Troubleshoot permission errors

If you see an error like:

Code
The provided key 'rk_test_...' does not have the required permissions for this endpoint. Having the 'rak_accounts_kyc_basic_read' permission would allow this request to continue.

The key is missing one of the permissions in the table above. Stripe's internal name in the error (rak_<resource>_<action>) maps to a row in the table. The most common omissions:

  • rak_accounts_kyc_basic_read → enable Connect → Accounts at Read.
  • rak_tax_calculations_* → enable Tax → Tax Calculations and Transactions at Write.
  • rak_webhook_endpoints_* → enable Webhook → Webhook Endpoints and Event Destinations at Write.
  • rak_invoices_* → enable Billing → Invoices at Write.

Edit the key in the Stripe Dashboard, tick the missing permission, save, and retry the connection in Zuplo.

Rotate the key

You can replace the connected key from the same Payment Provider screen. The new key must:

  • Use the same prefix mode (test or live) as the existing key.
  • Belong to the same Stripe account.
  • Carry all eight permissions above.

What Zuplo creates in Stripe

Zuplo's catalog — plans, features, rate cards, and entitlements — is stored in Zuplo. Stripe is used only at the points where money or payment state is involved.

The objects that Zuplo creates or manages in your Stripe account:

ObjectWhen it's created
Stripe CustomerWhen a developer first subscribes — one Stripe Customer per Zuplo customer
Stripe Checkout SessionWhen a developer subscribes to a plan that requires a payment method
Stripe Customer Portal SessionWhen a developer opens Manage Billing in the Developer Portal
Stripe Invoice and Invoice ItemAt the end of each billing period for fixed and usage-based charges
Stripe Tax CalculationAt invoice time when tax collection is enabled
Stripe Webhook EndpointOnce on connection, so Zuplo can react to payment events

To see what Zuplo has created, look under Customers and Invoices in your Stripe dashboard.

Subscription flow

New subscription

When a customer clicks "Subscribe" in your Developer Portal:

  1. A Stripe Checkout Session is created so the customer can enter a payment method
  2. The customer is redirected to Stripe Checkout to enter payment details
  3. On successful payment, the subscription is created
  4. An API key is generated scoped to the subscription's plan entitlements
  5. The customer is redirected back to the Developer Portal, where they can immediately see their subscription, usage dashboard, and API key

Plan changes (upgrades/downgrades)

When a customer changes their plan through the Developer Portal:

  1. Zuplo records the plan change and recalculates the customer's entitlements
  2. Any prorated amount is reflected on the customer's next Stripe Invoice
  3. The customer's entitlements update immediately
  4. The API key remains the same; its associated quota changes in real time

Zuplo uses max_consumption_based proration so customers can't game mid-period upgrades and downgrades — see Subscription Lifecycle → Proration behavior for the detailed model and examples.

Cancellation

When a customer cancels through the Developer Portal, the timing of the cancellation depends on whether the current phase has billable items:

  • Paid phases — the portal sends timing: "next_billing_cycle". The subscription is scheduled to cancel at the end of the current billing period, the customer retains access until then, and the API key stops working at period end.
  • Free phases — the portal sends timing: "immediate". With nothing to invoice at period end, there's no billing period to wait out, so the subscription cancels and access is revoked right away. Two situations fall into this branch:
    • The customer is on a free trial phase (the first phase of a plan with a later paid phase) and cancels before the trial converts.
    • The customer is on a free plan — a plan whose only phase has no billable rate cards (every rate card's price is null).

For programmatic cancellation, see Cancellation in the Subscription Lifecycle guide — the API endpoint accepts a timing parameter to control this same behavior explicitly.

Usage-based billing

For plans with usage-based pricing (per-unit, tiered, pay-as-you-go), usage is tracked in real time by the MonetizationInboundPolicy. Each API request increments the meter immediately. At the end of the billing period, Zuplo generates a Stripe Invoice with line items for the period's fixed fees and metered usage, and Stripe collects payment.

You don't need to implement usage reporting or run any batch jobs — and Zuplo does not call Stripe Billing Meters; metered usage is materialized as invoice line items directly.

Handling failed payments

When Stripe fails to collect payment, access is determined by the subscription's payment status. By default, a 3-day grace period allows continued access while Stripe retries the payment.

Payment statusDefault behavior
paidFull access
not_requiredFull access (free plans)
pendingFull access (within grace period)
failedAccess blocked after grace period (configurable)
uncollectibleAccess blocked

The grace period is configurable via customer or plan metadata, with customer metadata overriding plan metadata. Default is 3 days. See Subscription and payment validation for the full resolution order.

Customer portal

Stripe provides a hosted Customer Portal where customers can update their payment method, view invoices, and manage their subscription. The Developer Portal links to this from the subscription management page.

To enable the Stripe Customer Portal:

  1. Configure the Customer Portal in your Stripe Dashboard → Settings → Billing → Customer Portal
  2. Enable the features you want (update payment method, view invoices)
  3. The Developer Portal automatically includes a "Manage Billing" link that opens the Stripe Customer Portal

Testing

Test card numbers

Use Stripe's test card numbers to simulate different scenarios:

Card numberScenario
4242 4242 4242 4242Successful payment
4000 0000 0000 3220Requires 3D Secure authentication
4000 0000 0000 0341Attaches to customer but fails on charge
4000 0000 0000 9995Declined (insufficient funds)

Verifying the integration

After connecting Stripe and publishing plans:

  1. Open your Developer Portal
  2. Subscribe to a plan using test card 4242 4242 4242 4242
  3. Verify in Stripe Dashboard:
    • Customers — a customer was created with correct metadata and test card attached
    • Developers → Webhooks — the Zuplo-managed webhook endpoint is registered and recent events show 200 responses
  4. Make API requests and verify:
    • Requests succeed within quota
    • 403 Forbidden returned when quota exceeded (hard-limit plans)
    • Usage visible in the Developer Portal dashboard
  5. Wait for the next billing cycle (or trigger a manual invoice in test mode) and verify:
    • Invoices — a Stripe Invoice was created with line items matching your plan's fixed fees and metered usage
  6. Cancel the subscription in the Developer Portal and verify:
    • Access is revoked after the billing period ends
    • The Zuplo subscription shows canceled in the API and Developer Portal (Stripe doesn't track this — there is no Stripe Subscription to look at)
Edit this page
Last modified on May 24, 2026
Billing ModelsDeveloper Portal
On this page
  • How it works
  • Connecting your Stripe account
    • Via the Zuplo Portal
    • Test mode vs. live mode
  • Using a Stripe restricted key
    • Create the restricted key
    • Troubleshoot permission errors
    • Rotate the key
  • What Zuplo creates in Stripe
  • Subscription flow
    • New subscription
    • Plan changes (upgrades/downgrades)
    • Cancellation
  • Usage-based billing
  • Handling failed payments
  • Customer portal
  • Testing
    • Test card numbers
    • Verifying the integration