Skip to main content
Charge your customers a fixed amount every day, week, month or year. The customer subscribes once on the Payviox payment page; the following periods are charged automatically, and you’re notified of each one by webhook.

How it works

  1. Your server creates a payment session with a subscription object, using your secret key. amount is your price for one period.
  2. The customer pays the first period on the Payviox payment page, with a card, Apple Pay or Google Pay. This payment goes through the usual fraud checks, the customer explicitly authorizes the recurring charge, and the card is saved for the renewals.
  3. When the first payment succeeds, Payviox creates the subscription (psub_...) and sends you a succeeded webhook with a subscription block.
  4. Payviox then sets up a Stripe Billing subscription on your own Stripe account, starting at the end of the paid period. Stripe charges each renewal automatically — the money lands on your Stripe account, as for your one-time Stripe payments.
  5. Each renewal reaches you as a new succeeded webhook, with order_id = {your order_id}-{cycle}. Failed renewals and cancellations have their own events.
  6. The customer can cancel at the end of the paid period from a self-service link; you can cancel or resume from your backend or from the dashboard.

Before you start

Connect Stripe with card or wallets

Subscriptions are charged with Stripe, on your account:
  • In the Payviox dashboard, Providers → Stripe must be connected (publishable key, secret key and webhook signing secret) — the same setup as for one-time Stripe payments.
  • At least one of these methods must be active: card (stripe_credit), Apple Pay (stripe_apple_pay), Google Pay (stripe_google_pay). They’re the only methods offered on the payment page of a subscription.
Renewals are Stripe Billing subscriptions on your Stripe account, so Stripe’s Billing pricing applies to them. Your Payviox fees apply to each renewal like any payment, at the rates in force when the customer subscribed. In your Stripe dashboard you’ll see the customers, a product named after your business (”… subscription”) and one Stripe subscription per Payviox subscription (metadata payviox_subscription_id).

Enable the Stripe renewal events

Renewals happen on Stripe, so Payviox learns about them through the Stripe webhook endpoint you set up for Payviox: https://api.payviox.com/payment/stripe/webhook. Add these five events to it:
1

Open your webhook endpoints in Stripe

In the Stripe Dashboard, go to Developers → Webhooks. Check the mode you’re in: test mode and live mode have separate endpoints, so repeat these steps in each mode you use.
2

Open the Payviox endpoint

Click the endpoint whose URL is https://api.payviox.com/payment/stripe/webhook — the one you created when you connected Stripe to Payviox. It must be enabled: a disabled endpoint counts as missing.
3

Add the five events

Edit the endpoint’s events (Edit destination or Update details, then Select events). Search for and tick invoice.paid, invoice.payment_failed, invoice.payment_action_required, customer.subscription.updated and customer.subscription.deleted.
Keep the payment_intent.* events already selected: one-time payments and the first payment of a subscription still rely on them.
4

Save

Save the endpoint. Its signing secret doesn’t change, so there’s nothing to update in Payviox.
Create one: Add endpoint, URL https://api.payviox.com/payment/stripe/webhook, select the payment_intent.* events plus the five events above, then copy its signing secret (whsec_...) into Providers → Stripe in the Payviox dashboard.
Payviox checks your endpoint with your Stripe secret key when you create a subscription session. If events are missing, session creation fails with subscription_setup_incomplete and the list of missing_events, and the Subscriptions page of your dashboard shows a warning. The result is cached for up to an hour.
If your Stripe key isn’t allowed to read webhook endpoints (restricted key), Payviox can’t run this check and lets the session through. Make sure the five events are enabled anyway: without them, renewals are still charged by Stripe but you won’t be notified.

Turn on the subscription webhooks in Payviox

In the Payviox dashboard, Developers → Webhooks, select the opt-in events subscription_payment_failed and subscription_canceled next to succeeded. See Webhook Integration if you don’t receive Payviox webhooks yet.

Create a subscription session

Subscriptions follow the recommended integration: your backend creates the session with the secret key, the browser opens it with the SDK. A subscription session can’t be created with the public key — the recurring price must never come from the browser.
1

Your server creates the session

Add subscription to a regular Create Session request. amount and items describe one period.
interval is day, week, month or year; interval_count (default 1) multiplies it — { "interval": "month", "interval_count": 3 } bills every quarter. A period can’t exceed 3 years.
  • Put your own IDs (user, plan) in metadata: it’s sent with every webhook of the subscription, renewals included. The webhook customer field holds the payer’s billing details, not your ID.
  • Renewals reuse your order_id with a suffix (-2, -3, …). Use a dedicated prefix for subscription order IDs (like sub_ above) so they can’t clash with your other orders.
2

The browser opens it with the SDK

No browser in your flow? Send the customer to https://secure.payviox.com/{session_id} yourself.
On the payment page, the customer sees what they pay today, the recurring price and the date of the first renewal, and confirms an authorization such as “By subscribing, you authorize Acme to charge your card $10.29 every month, starting November 13, 2026, until you cancel…”. When the payment succeeds right away, the success screen shows their next payment date and a link to manage the subscription.
The customer is charged your amount plus the fees your account adds for the customer, exactly as for a one-time payment. The amount charged today can be slightly higher than the renewals: one-time add-on fees (such as fraud screening) only apply to the first payment. The renewal price is fixed at signup and returned as unit_amount on the Subscription object.

Handle the webhooks

The customer coming back to your site isn’t a confirmation — webhooks are. Keep one rule: give access until the end of the last period you were paid for.
Node.js
  • Idempotency: deduplicate on order_id + type, as for one-time payments. Each cycle has its own order_id (order_12345, order_12345-2, …), so renewals never collide.
  • Fraud review: the first payment can be pending_review before succeeded — don’t give access yet. Renewals aren’t reviewed: they arrive directly as succeeded.
  • Failed renewals: you get one subscription_payment_failed per cycle, even if Stripe retries several times. Its subscription.current_period_end is the end of the period that wasn’t paid — don’t extend access from it. If a retry succeeds, you receive succeeded with the same order_id. The retry schedule, and what happens when all retries fail, are set in your Stripe Billing settings (failed payments / revenue recovery): we recommend canceling the subscription, so you receive subscription_canceled. If Stripe leaves it unpaid instead, it stays past_due in Payviox and no further event is sent.
  • authentication_required: the bank wants the customer to approve the renewal (3D Secure), which Stripe retries alone can’t solve. Payviox doesn’t contact the customer: enable Stripe’s emails with a hosted confirmation link for payments that require 3D Secure in your Stripe Billing settings, or ask the customer to subscribe again.
  • Cancellation: scheduling a cancellation (by you or the customer) sends no event — subscription_canceled arrives when the subscription actually ends. It’s attached to the signup payment (order_id = your original one, cycle = 1): identify the subscription with subscription.id. When you cancel immediately yourself, it’s your call whether access ends now or at the end of the paid period.
See Subscription events for the full payloads.

Let customers manage their subscription

Every subscription has a management_url (in the webhook subscription block and on the Subscription object). It opens a Payviox page where the customer can:
  • see the price, the next payment date and the card used;
  • cancel at the end of the paid period — they keep what they paid for;
  • undo their own cancellation before the period ends. If you scheduled the cancellation, the page tells them to contact you instead.
Send it yourself: put subscription.management_url from the succeeded webhook in your confirmation email, and show it in your account page. That’s the reliable channel — Payviox doesn’t email it, and the checkout success screen only shows it when the payment succeeds right away: if the signup payment goes to fraud review (pending_review), the subscription and its link only exist once the payment is succeeded, after the customer has left the page. Customers can’t change their card, switch plans or cancel immediately from this page.
Treat the link like a password: it doesn’t expire, and anyone who has it can cancel the subscription.

Cancel or resume from your backend

Use the Subscriptions API with your secret key, or the Subscriptions page of your dashboard (team members need the Cancel and resume subscriptions permission).
  • Cancel now (at_period_end: false) also voids the subscription’s unpaid Stripe invoices, so no pending retry can charge the customer afterwards. There’s no automatic refund.
  • Resume only works on a cancellation scheduled on your side (cancel_requested_by api, manager, or null for one scheduled from your Stripe dashboard). A cancellation scheduled by the customer (payer) can only be undone by the customer, from their management link; one scheduled by Payviox (admin, system) requires support. Both return 403. The customer’s cancellation withdraws their consent to be charged: renewing anyway would be an unauthorized charge, the typical cause of “canceled recurring payment” disputes.

List Subscriptions

Filter by status (active, past_due, canceled, canceling) or customer

Get Subscription

Current status, next renewal, cancellation details

Cancel Subscription

At period end (default) or immediately

Resume Subscription

Undo a scheduled cancellation
Manage subscriptions through Payviox, not directly in your Stripe dashboard. A subscription canceled on Stripe is synced (canceled_by: "provider"), but changing its price there isn’t supported, and if you resume a customer’s cancellation in Stripe, Payviox re-applies the cancellation.

Limits

  • USD only, like every Payviox session. Minimum 100 cents per period.
  • Card, Apple Pay and Google Pay through Stripe only. Other providers and local methods aren’t offered for subscriptions.
  • No free trial: the first period is charged when the customer subscribes.
  • No plan catalog: price and interval are set per session. To change a customer’s price or interval, cancel at period end and have them subscribe again with a new session — there’s no upgrade or proration.
  • Intervals up to 3 years: 1095 days, 156 weeks, 36 months or 3 years per period.
  • The customer can’t update their card. If it expires or keeps being declined, renewals fail; once the subscription is canceled, invite the customer to subscribe again.
  • Fraud screening applies to the signup payment only, not to renewals.

Test your integration

  1. Connect Stripe in Payviox with your Stripe test-mode keys and test-mode webhook signing secret, and enable the five events on the test-mode endpoint.
  2. Create a subscription session with { "interval": "day", "interval_count": 1 } so the first renewal happens one day later.
  3. Pay with a Stripe test card:
    • 4242 4242 4242 4242 — signup and renewals succeed.
    • 4000 0027 6000 3184 — requires authentication on every charge: the signup succeeds after you complete the test authentication, and the renewal fails with failure_reason: "authentication_required".
  4. Check that you received succeeded with subscription.cycle: 1, then fetch the subscription with Get Subscription: provider_subscription_id is filled within about a minute, and the subscription shows up in your Stripe dashboard (test mode).
  5. Open the management_url, cancel, then undo — and check cancel_at_period_end with the API.
Stripe test clocks can’t be used: they only apply to Stripe customers created on a test clock, and Payviox creates the Stripe customer itself. Use a daily interval to test renewals.

Troubleshooting

The session was created with your public key (for example with the SDK’s createSession()). Create it from your server with your secret key, then open it with openSession().
Your Stripe endpoint https://api.payviox.com/payment/stripe/webhook is missing, or lacks the events listed in missing_events. Add them in the right mode (test or live). The check is cached for up to an hour, so the error can persist briefly after you fix it.
Card, Apple Pay and Google Pay (Stripe) are all inactive on your account, or your Stripe publishable or secret key is missing in Providers → Stripe. Activate at least one of these methods and complete the Stripe keys. If you pass paymentMethodId, it must be one of these methods.
The cancellation was scheduled by the customer (cancel_requested_by: "payer") — only they can undo it, from their management link — or by Payviox (admin, system) — contact support.
After the first payment, Payviox couldn’t create the subscription on your Stripe account (for example, Stripe keys changed in between). The customer paid for the first period, then the subscription was canceled automatically (canceled_by: "system", cancellation_reason setup_failed:<code>) and you received subscription_canceled. Contact support@payviox.com with the subscription ID.
Check that the five events are enabled on the Stripe endpoint of the right mode, that the webhook signing secret in Providers → Stripe is the one of that endpoint, and that succeeded is selected in your Payviox webhook settings.