Build recurring billing with subscriptions

Prerequisites

A subscription charges a buyer's saved card on a fixed schedule (daily, weekly, monthly, quarterly or yearly) for a set number of iterations or until you cancel it. PayMe runs the schedule, retries failed charges and reports each step with a callback. You create the subscription, keep your records in sync from the callbacks, and pause, reprice or cancel it through the API.

Each iteration is charged separately; nothing is authorized up front. Wallets such as Apple Pay, Google Pay and Bit aren't offered for subscriptions.

This guide follows a subscription from creation to its last charge. The fields of each call are on the endpoint pages linked in each step.

Before you start

Choose how the buyer signs up

Model How Use it when
Payment link Create the subscription and send the buyer to its sub_url to enter a card. You don't have the buyer's card yet.
Saved card Save a permanent card first, then create the subscription with its buyer_key. The buyer already paid you, or you collect cards in your own checkout.
Template link Create one subscription with sub_type 10 and share its sub_url. Each buyer who pays it gets their own subscription. One public sign-up link for many buyers, for example on social media.

How to save a permanent card: Save a card and charge it later.

Charge now, then every month. Charge the first payment as a regular sale with capture_buyer: 1, which also saves the card. Then create the subscription with that buyer_key and sub_start_date one period later (for a monthly plan, a day from 1 to 28). Nothing is charged before sub_start_date, so the buyer isn't charged twice.

1. Create the subscription

Call generate-subscription:

{
  "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567",
  "sub_price": 5000,
  "sub_currency": "ILS",
  "sub_description": "Monthly plan",
  "sub_iteration_type": 3,
  "sub_iterations": 12,
  "sub_start_date": "01/12/2026",
  "subscription_id": "order-1001",
  "sub_callback_url": "https://www.example.com/payment/callback",
  "sub_return_url": "https://www.example.com/payment/success",
  "language": "en"
}

The response returns the subscription in status 1 (Initial), with its sub_url, sub_payme_id and sub_payme_code. Store sub_payme_id: every other subscription call uses it. PayMe sends sub-create.

With a saved card, add a permanent buyer_key and skip sub_url. The subscription is created in status 2 (Active) at once, and PayMe also sends sub-active. A single-use token returns error 376. A template can't take a buyer_key.

2. The buyer pays and the subscription starts

On sub_url the buyer enters a card. PayMe checks the card and saves it; nothing is charged yet. The subscription moves to status 2 (Active), PayMe sends sub-active, and the buyer is sent to sub_return_url if you set one. If you are PCI DSS Level 1 certified and collect the card in your own form, send it with pay-subscription instead.

A background job that runs once a minute makes every charge, including the first. The first charge runs within about a minute after sub_start_date, once a card is attached.

If the card check fails, the subscription moves to status 4 (Failed) and PayMe sends sub-failure. PayMe doesn't retry it and doesn't cancel it. The buyer can open sub_url again and enter another card, or you can send one with pay-subscription.

3. Each charge

When sub_next_date arrives, PayMe charges the saved card, with no CVV and no 3D Secure. Every attempt creates a sale of type 3 (SaleFromSubscription). When the charge succeeds:

After the last iteration the status becomes 6 (Completed) and PayMe sends sub-complete.

A renewal sale doesn't name its subscription, and its own sale callbacks don't go to sub_callback_url (only to your partner's default callback URL, if one is set). Link charges in one of two ways:

  1. From the callback. When sub-iteration-success arrives, store its payme_sale_id against the sub_payme_id. Refunds and reports work on the sale.
  2. From a query. Call get-sales with sale_type 3 and sale_parent_code set to the subscription's sub_payme_code. The result also lists failed attempts (sale_status failed); send sale_status to narrow it.
{
  "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567",
  "sale_type": 3,
  "sale_parent_code": 477004
}

The sub-iteration-success fields you need:

Field Example Use
notify_type sub-iteration-success What happened.
sub_payme_id SUB16885-68336QPL-UQSSS1CC-SYKXI53N The subscription.
subscription_id order-1001 Your reference, if you sent one.
payme_sale_id SALE1700-000000AA-EXAMPLE1-SALE0001 The sale this charge created.
payme_sale_code 12345678 The same sale's numeric code.
sub_price 5000 The amount charged, in minor units.
sub_prev_date 2026-12-01 00:01:00 When the charge ran.
sub_next_date 2027-01-01 00:00:00 When the next charge is due.
sub_iterations_completed, sub_iterations_left 1, 11 Progress.

5. Handle failed charges

What failed Status Callback What PayMe does next
The card check when the buyer pays 4 Failed sub-failure Nothing: the buyer must pay again.
A scheduled charge, with a retry left 7 Failed, retry pending sub-failure Moves sub_next_date one day ahead and tries again.
A scheduled charge of a daily subscription, or the seventh failure in a row 5 Canceled sub-cancel, without sub-failure Nothing: the subscription is over, and sub_next_date becomes null.

6. Pause, resume and cancel

Call Allowed in status Result Callback
Pause: POST /pause-subscription 2, 4, 7 Status 3. Nothing is charged. sub-pause
Resume: PATCH /subscriptions/{sub_payme_id}/resume 3 Status 2. The next charge runs at sub_next_date. None
Cancel: POST /cancel-subscription 1, 2, 4, 7 Status 5. Final. sub-cancel

7. Change the price

Call PATCH /subscriptions/{sub_payme_id}/set-price with the new sub_price, for example PATCH https://sandbox.payme.io/api/subscriptions/SUB16885-68336QPL-UQSSS1CC-SYKXI53N/set-price:

{
  "seller_payme_id": "MPLDEMO-MPLDEMO-MPLDEMO-1234567",
  "sub_price": 7500
}

Mid-cycle upgrade. There is no proration. Work out the difference yourself, for example (new price − old price) × days left ÷ days in the cycle. Charge it once with generate-sale and the subscription's buyer_key (read it with get-buyer-key and sub_payme_id), then call set-price. The next cycle charges the full new price on the same billing day. Don't cancel and re-create the subscription: that resets sub_start_date and the counters.

8. Change the card

If you can't wait, move the buyer to a new subscription: save the new card as a permanent token, create a subscription with that buyer_key and sub_start_date set to the old subscription's sub_next_date, then cancel the old one before that date. The new subscription has its own sub_payme_id and counters, so set sub_iterations to the iterations left. Cancelling the old one sends sub-cancel and emails the buyer.

A template (sub_type 10) is one payment link for many buyers. Send the number 10: the text template is rejected with error 24.

Callbacks

notify_type When
sub-create The subscription was created.
sub-active A card was attached and the subscription is active.
sub-iteration-success A charge succeeded. Carries payme_sale_id and payme_sale_code.
sub-failure The card check failed (status 4), or a scheduled charge failed and will be retried (status 7).
sub-pause The subscription was paused.
sub-iteration-skipped An iteration date passed while the subscription was paused.
sub-complete The last iteration was charged or skipped.
sub-cancel The subscription was canceled, by the seller or automatically.

Subscription callbacks are form-encoded POST requests to sub_callback_url. They carry no payme_signature: before acting on one, confirm the state with get-subscriptions and sub_payme_id. They never contain the buyer_key. The same callback can arrive more than once, so process each one once; for sub-iteration-success, de-duplicate on payme_sale_id. Dates are Asia/Jerusalem local time. Every field: Callbacks → Subscriptions.

Test it in the sandbox

More cards: Test Cards and Payment Methods.

See also