Sandbox
Help

Build a fixed-rate subscription model

Charge the customer the same amount on every billing cycle - the simplest pricing model.

A fixed-rate subscription bills a flat price at a fixed cadence: £29.00 a month, £290.00 a year, and so on. The price never changes while the subscription runs, so once the customer is subscribed, your work is done - Revolut charges the saved payment method on every cycle and retries failed payments automatically.

This is the baseline scenario: every other pricing model - per-seat, usage-based, trials - is a variation on the same flow with a different plan configuration.

In this guide, you sell a Standard plan - £29.00 a month, with a yearly variation at £290.00 for customers who commit for a full year.

The example demonstrates how to model your own product or service palette as a subscription plan. One plan represents the service you offer, and each variation is one way a customer can buy it: the monthly option bills £29.00 every month, while the yearly option bills £290.00 once a year - a discount for the longer commitment.

Map your own catalogue the same way: every purchasing option for the same offering - a different cadence, commitment length, or price - becomes a variation, and each customer subscribes to exactly one of them.

Itemised pricing

If the product bundles distinct services, you can break the flat price into per-component items - see Itemised flat pricing.

How it works

This guide walks the full flow: all API calls run between your backend and the Merchant API, and only step 3 - collecting the first payment - reaches the customer's browser.

  1. Create a plan with a fixed price - each variation is a single phase that sets the price and cycle length. Offer monthly and yearly options as separate variations. Optionally, break the price into itemised flat components.
  2. Subscribe the customer - create the subscription, which starts in pending state until the first payment is collected.
  3. Collect the first payment - retrieve the setup order, hand the customer a payment widget or Revolut's Hosted Checkout Page, and confirm the subscription is active - Revolut bills automatically from there.
  4. Operate the subscription - retrieve the billing cycles as they accrue, and cancel the subscription when the customer leaves.

The plan you'll build in this guide looks like this:

Standard plan Monthly variation Yearly variation Phase 1 - £29.00/monthongoing Phase 1 - £290.00/yearongoing

Before you begin

Before you start, make sure you have the following:


Implement fixed-rate subscription

The steps below follow the Standard plan narrative: you create the plan with its two variations, subscribe a customer, collect the first payment, and confirm the subscription is active.

1. Create plan with fixed price

Your Standard plan offers two billing options: £29.00 a month, or £290.00 a year for customers who commit to the full 12 months. Each variation is a single phase - the phase's amount is the price charged on every cycle of cycle_duration - and each customer subscribes to exactly one of them.

The plan you create consumes these business details: the name your customers recognise, the monthly and yearly billing cadences, and the two prices - the yearly price works as a discount for the longer commitment.

Call Create a subscription plan, turning these business details into a plan your customers can subscribe to:

Request example
POST /api/subscription-plans HTTP/1.1
Host: merchant.revolut.com
Authorization: Bearer sk_abcdef12347890_...
Revolut-Api-Version: 2026-08-17
Content-Type: application/json

{
  "name": "Standard plan",
  "variations": [
    {
      "phases": [
        {
          "ordinal": 1,
          "cycle_duration": "P1M",
          "amount": 2900,
          "currency": "GBP"
        }
      ]
    },
    {
      "phases": [
        {
          "ordinal": 1,
          "cycle_duration": "P1Y",
          "amount": 29000,
          "currency": "GBP"
        }
      ]
    }
  ]
}
ParameterDescription
nameThe plan name - what your customers subscribe to
variationsPricing options for the plan - here, monthly and yearly billing
phasesSequential pricing stages within a variation, executed in ordinal order
ordinalExecution order of the phase, starting at 1
cycle_durationLength of the billing cycle, as an ISO 8601 duration, e.g., P1M or P1Y
cycle_countNumber of cycles the phase runs for - omit to run indefinitely
amountPrice per billing cycle, in minor units - 2900 is £29.00, 29000 is £290.00
currencyBilling currency, as an ISO 4217 code
Limited subscriptions

To run the subscription for a fixed number of cycles - e.g., a 12-month commitment that ends automatically - set cycle_count on the phase. When the last cycle completes, the subscription moves to finished and no further charges are made.

Itemised flat pricing

Itemised flat pricing is an optional extension of the standard fixed-rate model. Say your Standard plan bundles two services: the platform licence and a priority-support add-on.

Some customers want to know exactly what they're paying for - so instead of one opaque £29.00 charge, you bill each component separately under the same subscription: the platform licence at £19.00 a month, priority support at £10.00.

To do this, add subscription_items with type: flat to the phase - each flat item charges its amount multiplied by its quantity on every cycle. The phase-level amount and currency stay on the phase.

With the items, the plan configuration looks like this:

Standard plan Monthly variation Phase 1 - £29.00/month ongoing Subscription items Yearly variation Platform licenceflat item - £19.00 Priority supportflat item - £10.00 Phase 1 - £290.00/year ongoing

In terms of the API's fields and types - as the create response returns them - the same structure looks like this:

plan PK id uuid the plan name name string active when created state string variations array variation save it - the customer subscribes to one PK id uuid phases array phase PK id uuid execution order, starting at 1 ordinal integer ISO 8601 duration, e.g. P1M cycle_duration string optional - omit to run indefinitely cycle_count integer price per cycle, minor units amount integer ISO 4217 code currency string subscription_items array subscription_item PK id uuid flat for a fixed per-cycle charge type string item name, e.g. Platform licence name string what the item bills unit string units billed per cycle quantity integer price per unit, minor units amount integer ISO 4217 code currency string variations phases subscription_items

This is the Create a subscription plan call from step 1, with the monthly variation's phase itemised:

Request example
POST /api/subscription-plans HTTP/1.1
Host: merchant.revolut.com
Authorization: Bearer sk_abcdef12347890_...
Revolut-Api-Version: 2026-08-17
Content-Type: application/json

{
  "name": "Standard plan",
  "variations": [
    {
      "phases": [
        {
          "ordinal": 1,
          "cycle_duration": "P1M",
          "amount": 2900,
          "currency": "GBP",
          "subscription_items": [
            {
              "type": "flat",
              "name": "Platform licence",
              "unit": "subscription",
              "quantity": 1,
              "amount": 1900,
              "currency": "GBP"
            },
            {
              "type": "flat",
              "name": "Priority support",
              "unit": "subscription",
              "quantity": 1,
              "amount": 1000,
              "currency": "GBP"
            }
          ]
        }
      ]
    },
    {
      "phases": [
        {
          "ordinal": 1,
          "cycle_duration": "P1Y",
          "amount": 29000,
          "currency": "GBP"
        }
      ]
    }
  ]
}
ParameterDescription
typeItem type - flat for a fixed per-cycle charge
nameThe item name, e.g., Platform licence
amountPrice per unit, in minor units - 1900 is £19.00
currencyItem currency, as an ISO 4217 code
unitWhat the item bills, e.g., subscription, licence
quantityUnits billed per cycle - each cycle charges quantity * amount

2. Subscribe customer

When a customer wants to subscribe to your Standard plan, you create a subscription. The subscription connects the customer - and their consent to use their payment details for recurring charges - to the monthly variation you chose in step 1.

Subscription creation is the same for every pricing model - the pricing lives entirely in the plan you built. Once created, the subscription starts in pending state - it becomes active once the customer completes the first payment.

Call Create a subscription with an idempotency key, so you can safely retry the request without creating duplicate subscriptions:

Request example
POST /api/subscriptions HTTP/1.1
Host: merchant.revolut.com
Authorization: Bearer sk_abcdef12347890_...
Revolut-Api-Version: 2026-08-17
Content-Type: application/json
Idempotency-Key: 4f1a9c2b-8e3d-4a67-9b5f-2c7d8e1f4a6b

{
  "plan_variation_id": "5dfb572c-d2d4-4522-8626-ed6ea2d2711f",
  "customer_id": "650e8400-e29b-41d4-a716-446655440001",
  "external_reference": "std_8f3a91",
  "setup_order_redirect_url": "https://example.com/subscription/complete"
}
ParameterDescription
plan_variation_idThe variation the customer subscribes to - the monthly variation id you saved in step 1
customer_idThe customer to bill
external_referenceOptional: your own identifier for the subscription, e.g., the customer's ID in your system - returned in responses and echoed in webhook events
setup_order_redirect_urlOptional: where the customer lands after completing payment on the hosted checkout page

3. Collect first payment

In step 2 you created the subscription. It is in pending state, and becomes active once the customer completes the first payment. That payment is collected through a setup order - an order that exists to start a subscription.

Revolut creates the setup order in the background when you create the subscription: it takes the first charge - £29.00 for the Standard plan - and saves the customer's payment method for the recurring cycles that follow. You already saved its setup_order_id.

3.1 Retrieve setup order

Retrieve the setup order with Retrieve an order, passing the setup_order_id you saved in step 2 as the order_id:

Request example
GET /api/orders/{order_id} HTTP/1.1
Host: merchant.revolut.com
Authorization: Bearer sk_abcdef12347890_...
Revolut-Api-Version: 2026-08-17
ParameterDescription
order_idThe ID of the setup order you saved in step 2

Like the calls in the previous steps, this is a server-side operation - it happens between your backend and the Merchant API.

3.2 Build your payment acceptance solution

Collecting the payment reaches beyond your backend: the customer pays in their browser or mobile app, so this part of the flow has client-side work alongside your server. The goal is to hand the customer a way to pay the first charge and save their payment method. Revolut supports two approaches, and both do this for you:

Payment widget
Embed the payment flow in your site: you build the customer experience, and the customer never leaves your page
Hosted Checkout Page
Redirect to a payment page Revolut hosts for you: no payment UI to build, and Revolut handles the payment experience

Choose the approach that fits your integration:

Keep the customer on your site with an embedded payment widget or a card-not-present method:

  1. Build your payment acceptance solution on your frontend with the widget or payment method of your choice, initialising it with the token from the response.
  2. Configure it to save the customer's payment method for merchant-initiated recurring transactions.
  3. The customer completes payment without leaving your site, and Revolut saves their payment method.

This step assumes you're familiar with a standard payment method integration, see Introduction to online payments.

4. Verify subscription state

When the customer completes the first payment in step 3, the subscription becomes active. There's no webhook event for activation, so retrieve the subscription to confirm it's live.

Check the subscription details with Retrieve a subscription, passing the subscription id from step 2 as the subscription_id:

Request example
GET /api/subscriptions/{subscription_id} HTTP/1.1
Host: merchant.revolut.com
Authorization: Bearer sk_abcdef12347890_...
Revolut-Api-Version: 2026-08-17
ParameterDescription
subscription_idThe ID of the subscription you saved in step 2

Once the subscription is active, your fixed-rate subscription is live - Revolut takes over from here: it charges the customer's saved payment method £29.00 (2900) a month or £290.00 (29000) a year, and retries failed payments automatically - see Failed payments and retries.

You've completed the fixed-rate subscription flow! The Standard plan is live with its two variations, and Revolut bills the customer automatically from here. Next, operate the subscription: retrieve the billing cycles as they accrue, and cancel it when the customer leaves.


Operate fixed-rate subscription

With the subscription active, Revolut bills the saved payment method automatically. Two operations remain yours while it runs: retrieving the billing cycles - for entitlement checks, billing history, and reconciliation - and cancelling the subscription when the customer leaves.

Retrieve billing cycles

While the subscription is active, Revolut creates a billing cycle for every billing period - one a month on the monthly variation. Each cycle carries its period, state, and the order_id of the order that charged it, so a complete billing history builds up as the subscription runs.

The subscription's runtime resources look like this:

Subscription 11883317 - state: active Cycle b3688550 - current, state: active Cycle 031f6f77 - state: finished Order d5086d86 - charges £29.00 Order 5c5d4c09 - charged £29.00

The examples below cover two common use cases - a billing-history view and an entitlement check - but they're just a starting point. Explore how the same calls can serve your own business cases: the cycle data can power reconciliation, customer-facing billing pages, dunning workflows, and anything else your product needs.

Retrieve cycle list

The cycle list gives you the subscription's billing history in one call - every cycle so far, its state, and the order that charged each period. Use it for reconciliation and billing-history views, and to discover the current cycle's id if you don't have it saved.

Call Retrieve a subscription cycle list, passing the id of the subscription you created in step 2 as the subscription_id:

Request example
GET /api/subscriptions/{subscription_id}/cycles HTTP/1.1
Host: merchant.revolut.com
Authorization: Bearer sk_abcdef12347890_...
Revolut-Api-Version: 2026-08-17

Run entitlement check

A common pattern is gating platform access on the subscription's state: each time the customer logs in, retrieve the current cycle - its id is the current_cycle_id from the subscription response - and grant access while its state is active.

The check runs on every login, so keep it lightweight: retrieve just the current cycle instead of pulling the whole list. Call Retrieve a subscription cycle, passing the current cycle's id as the cycle_id:

Request example
GET /api/subscriptions/{subscription_id}/cycles/{cycle_id} HTTP/1.1
Host: merchant.revolut.com
Authorization: Bearer sk_abcdef12347890_...
Revolut-Api-Version: 2026-08-17

Cancel subscription

When the customer wants to leave, cancel the subscription - Revolut stops billing and cancels any pending orders. You can cancel in any state except cancelled or finished.

Call Cancel a subscription, passing the id of the subscription you created in step 2 as the subscription_id:

Request example
POST /api/subscriptions/{subscription_id}/cancel HTTP/1.1
Host: merchant.revolut.com
Authorization: Bearer sk_abcdef12347890_...
Revolut-Api-Version: 2026-08-17

The subscription moves to cancelled - a final state: it can't be reactivated, so if the customer returns, create a new subscription for them. A SUBSCRIPTION_CANCELLED webhook event is sent whether the cancellation came from you or the customer - see Subscription states and Track subscriptions with webhooks.

If you run the entitlement check, this is where it stops granting access: end access immediately, or - if you let customers finish what they paid for - stop at the current cycle's end_date. Cancelling stops future charges only - it doesn't refund completed cycles.


Implementation checklist

Confirm your fixed-rate integration works end to end. Run the checks in the Sandbox environment first - set the base URL of your API calls to sandbox-merchant.revolut.com - then repeat them in production before going live:

  • Created a plan with a fixed phase amount and saved the variation id - or added flat subscription items for itemised pricing
  • Subscribed a customer, collected the first payment, and confirmed the subscription is active
  • Retrieved the cycle list and the current cycle - confirmed each cycle's number, state, and order_id
  • If using cycle_count - confirmed the subscription moves to finished after the last cycle
  • Cancelled a test subscription - 204 response, no new cycles created, SUBSCRIPTION_CANCELLED event received

For verifying the payment solution itself - widget behaviour, test cards, webhook receipt for the order - use the implementation checklist in the payment method guide you followed.


What's next

Build a per-seat subscription
Bill per seat, with a stable or changing seat count.
Build a usage-based subscription
Meter usage, report it via the API, and settle charges at cycle end.
Build a subscription with trials and introductory pricing
Offer free trials and promotional pricing phases.
Track subscriptions with webhooks
Receive real-time events when subscription states change.
Rate this page