Skip to main content
Most subscription integrations need two round trips: enroll the card to get a vaulted_token, then call Create Subscription with that token. That works, but it splits signup across two calls — and it leaves you holding a stored credential before you know whether the customer’s card will actually authorize. The subscription block on Create Payment collapses that into one call. You send the instrument and the recurrence instructions together; Yuno charges the customer and, on the back of that same charge, creates the subscription. That payment is linked to the subscription and recorded as its first billing cycle, and nothing starts billing if the payment doesn’t go through.
Which route should you use?
  • One call (this page): the customer is signing up and paying right now, and you want the signup to succeed or fail as a single unit. Best for checkout flows.
  • Create Subscription: you already hold a vaulted_token for the customer — for example, they enrolled a card earlier. See the subscriptions overview for that flow. To move an existing subscriber onto another plan, use Change Subscription Plan — creating a second subscription leaves the first one active and billing.
  • Payment links: the subscription block is not supported on payment-link create — it is ignored rather than rejected, so the link returns 201 and no subscription is ever created. Take the payment on the link with vault_on_success, then call Create Subscription with the resulting vaulted_token.
Both routes produce a subscription you manage with the same endpoints — pause, resume, cancel, retrieve. They are not configured identically: the subscription block on Create Payment carries a smaller field set, and cannot set trial_period, soft_descriptor or a subscription name. metadata is read only together with plan_id, and a subscription created from a plan takes the plan’s retry configuration — see Create a subscription from a plan. When you send the subscription’s terms in the call instead (frequency, availability and amount, called inline terms on this page), retries and metadata are ignored, and Smart Retries are off on a subscription created this way — a declined renewal is not retried until you turn them on with Update Subscription.

How the one call works

These steps apply when you send the subscription’s terms in the call itself: frequency, availability and amount. If you send a plan_id instead, the order changes and Yuno creates the subscription before the charge. See Create a subscription from a plan.
  1. You call Create Payment with the payment you’d send anyway — amount, country, payment method, customer — plus a subscription object describing the recurrence.
  2. Yuno charges the customer. This is a normal card payment: it routes, it can decline.
  3. If the charge completes, Yuno creates the subscription and records that payment as its first billing cycle. The payment response comes back with subscription_code — the id of the new subscription.
  4. Yuno bills every following cycle on its own, on the cadence you set in frequency, until the subscription completes, is canceled, or runs out of billing cycles.
If the charge doesn’t complete, no subscription is created — you get a declined payment and that’s the whole outcome. When the charge does complete, the payment is linked to the new subscription as its first billing cycle; confirm that link from subscription_code on the payment response and from Retrieve Subscription rather than assuming it. Apply that check only once the payment reaches a terminal status. If the payment comes back PENDING, the subscription has not been created yet and the response comes back with subscription_code: null — wait for the terminal outcome before reconciling. On a payment that is already terminal and successful, subscription_code: null means the subscription was not created. See Errors.

Retrying the call

Create Payment requires an X-idempotency-key header — the request is rejected before the body is parsed if it is missing. Retrying with the same key returns the original payment and does not create a second subscription. Retrying with a new key charges the customer again. So if a payment succeeded without a subscription_code, replaying the call is not a fix: the same key gives you the original payment back, and a new key takes a second payment. Reconcile instead — see Errors.
Available payment methodsSee Subscriptions for the payment methods subscriptions support. To sign up a Pix Automático customer from a plan with the first payment, see Create a subscription from a plan.

The subscription block

Send subscription alongside the normal Create Payment fields. The block has three shapes, and you send exactly one of them: checkout.session is required on Create Payment unless you send "workflow": "DIRECT" or "workflow": "REDIRECT" — the subscription block does not change that. Create a session with Create checkout session and send its identifier as checkout.session.
With inline terms, the availability object itself is required, but both fields inside it are optional — send {} if you want the subscription to start now and run until you cancel it. With plan_id, availability is optional altogether — see Fields you can send with plan_id.
customer_payer is required for this flowA subscription always belongs to a customer, so a customer_payer object must be present when you send a subscription block. You can identify an existing customer with customer_payer.id, or send the customer inline (email, merchant_customer_id, document) and let Yuno create them — id is not required. Create the customer up front with Create Customer if you prefer to hold the identifier yourself.
billing_cycles and availability.finish_at affect each otherIf you set both, the subscription reaches COMPLETED at whichever comes first — the last billing cycle or finish_at. If you set neither, Yuno keeps charging until you cancel.

Complete example

Create Payment with a new subscription
payment_method.token is the one-time token the checkout session produces for the card the customer just entered — that is the signup instrument on this route. Use vaulted_token only when the card is already stored, as in Charging an existing subscription. The response is a normal payment object with one extra field populated:
Response (excerpt) — illustrative
Illustrative — no merchant-surface capture exists yet for this flow. The field names and nesting are the ones this route adds; the values are placeholders.
Keep subscription_code — it is the subscription’s id, and it’s what you pass to Retrieve, Pause, Resume, and Cancel.

execution decides who bills

frequency.execution tells Yuno who is responsible for generating each recurring charge. With inline terms it is required — there is no default. With plan_id it defaults to YUNO.
  • YUNO — Yuno’s engine owns the schedule. It generates every charge after the first one and emits the per-cycle payment.purchase webhooks. This is what you want for this flow.
  • MERCHANT — you own the schedule. Yuno stores the subscription as a record of the arrangement but never charges on it; you send each rebill yourself as a merchant-initiated payment. The lifecycle operations that only make sense against a Yuno-run schedule — Pause, Resume, Update, Retry, and Change plan — are rejected with 400 BAD_REQUEST.
Retries are the one exception to “same subscription object”With inline terms, the subscription block on Create Payment reads no retries object, so a subscription created this way starts with retry_on_decline: false — a declined renewal is not retried, on either execution value. With plan_id, see Create a subscription from a plan. Turn Smart Retries on afterwards with Update Subscription.
MERCHANT subscriptions never bill on their ownIf you send "execution": "MERCHANT" expecting Yuno to charge the customer next month, nothing will happen — the subscription is created, it looks healthy, and no charge is ever generated. If Yuno should be doing the billing, send "execution": "YUNO".If you genuinely want to drive the recurrence yourself, you don’t need a subscription at all — use Stored Credentials and send each rebill as a payment with stored_credentials.reason = SUBSCRIPTION.

Authentication on the first charge

The first charge is a customer-initiated transaction (CIT) on the payment surface, so it is eligible for 3DS in a way a Create Subscription rebill is not — that endpoint takes a vaulted_token and starts a schedule, with no customer session attached and no surface on which to present a challenge.
Frictionless only, for nowThis route is documented for frictionless authentication only. A payment that requires a 3DS challenge completes asynchronously after the customer authenticates, and the one-call + challenge round trip has not been validated end to end — do not build a subscription signup on it yet. Keep the first charge frictionless, or use the two-call flow (Create Payment, then Create Subscription with the resulting vaulted_token) when a challenge is expected. See 3DS configuration and testing.
Credential usage on the rebillsThe first charge is a CIT. Every charge Yuno generates afterwards is a merchant-initiated transaction against the same stored credential. Yuno sets this up for you on this route — but if you ever build the two-call flow by hand (CIT payment first, then Create Subscription with the resulting token), you must set the credential usage yourself on that CIT payment — payment_method.detail.card.stored_credentials.usage (payment_method.detail.wallet.stored_credentials.usage for an Apple Pay or Google Pay CIT), and on the Create Subscription call the flat payment_method.card.usage: "USED" (see Create Subscription) — or the rebills will be sent as CITs and declined. See Stored Credentials.

Finding the first charge later

The payment you made in the one call is not a loose transaction sitting next to the subscription — it is recorded as the subscription’s first billing cycle. That matters for reporting: if it weren’t linked, your recurring-revenue numbers would miss every subscription’s first month. Two ways to follow the link:
  • From the payment: subscription_code on the payment object is the subscription’s id. It’s on the Create Payment response and on Retrieve Payment.
  • From the subscription: List Subscription Payments returns the subscription’s charge history, and the payment from the one call is linked there as the subscription’s first billing cycle, carrying the same payment id you got back from the call.
Renewal webhookssubscription.active fires once, when the subscription first becomes active. It is not re-sent on later renewals. Track each renewal through the per-cycle payment.purchase webhook instead. See Subscriptions.

Create a subscription from a plan

If you already have a plan, you can sign a customer up to it in the same call that takes their first payment. Send the plan’s id as subscription.plan_id on Create Payment. The subscription takes its price, cadence and trial from the plan, so you don’t send amount or a cadence inside the subscription block. This works with any payment method the plan allows, including cards and Pix Automático:
  • Card: send the card payment as in the complete example, with plan_id as the only field in the subscription block. The plan can’t have a trial or other phases: on a payment method other than Pix Automático, a plan with phases is rejected with 400 INVALID_PARAMETERS.
  • Pix Automático: the payment is the mandate setup, and the plan decides what the customer approves. Plans with a free trial are supported.
With a plan, the subscription exists before the customer paysWith plan_id, Yuno creates the subscription before the charge, as soon as the plan checks pass. The first response already carries subscription_code, even while the payment is still pending. The rule on the rest of this page, “no subscription unless the charge completes”, does not apply here. See If the first payment fails for what to clean up.

The request

Create Payment from a plan
The payment’s amount must equal the plan’s price for the payment’s country, in the same currency. Yuno resolves that price in this order: the regular phase’s price for the country, then the plan’s country_prices entry for the country, then the plan’s base_amount. On a free-trial plan you still send the regular price; the trial decides what is charged first.

Fields you can send with plan_id

Retries come from the plan. The subscription takes the plan’s retry configuration, so retries is not a field of this call: sending it is rejected with 400 INVALID_PARAMETERS. On a Pix Automático subscription that Yuno executes, for organizations with Pix Automático scheduling enabled, the Pix retry ladder applies (retry_on_decline: true).

Fields you cannot send with plan_id

The plan already defines these fields, so each one is rejected with 400 INVALID_REQUEST, even when its value is null: id, amount, frequency.type, frequency.value, billing_date, trial, trial_period, phases The error message names the field:
plan_id with a forbidden field
For frequency.type and frequency.value the message reads “Only ‘subscription.frequency.execution’ can be sent with ‘subscription.plan_id’”.

What the response adds

The payment response carries three fields for this route:
  • subscription_code: the id of the new subscription.
  • plan_id: the subscription’s plan when this payment was created.
  • plan_assigned_at: when the plan was assigned to the subscription.
The same three fields are on Retrieve Payment and on payment webhooks. The renewal payments Yuno generates for the subscription carry plan_id and plan_assigned_at too. On a payment made without a plan, plan_id and plan_assigned_at are absent, not null. On a free-trial plan the payment shows the regular price in amount.value, while its transaction is 0.00: that is the mandate setup, which collects nothing. A refund of that payment is rejected with 400 INVALID_PARAMETERS, because nothing was collected.

If the first payment fails

  • Free-trial plan: see Pix Automático. A refused setup cancels the subscription automatically.
  • Plan without a trial: a refused first payment leaves the subscription CREATED. It is never billed, but it is not canceled either: cancel it with Cancel Subscription. An expired first payment is different: the customer’s bank can still deliver an approval after the QR code expires, which completes the payment and activates the subscription. Cancel it only if you don’t want that.

Errors from a plan

The request checks fail with 400 before anything is created. The plan checks fail with 400 before the provider is called: no money moves, no subscription is created, and the payment is stored with status ERROR.

Charging an existing subscription

The same subscription block has a third shape: send id with the UUID of a subscription that already exists, and the payment is attached to that subscription instead of creating a new one. In that shape you omit frequency, availability, and amount — the subscription already defines them.
Create Payment for an existing subscription
billing_date is silently ignored when you create a subscriptionThe payments-surface block accepts a billing_date object, but only alongside id for a subscription that already exists. If you send it while creating a new subscription, it is not rejected — it is accepted, dropped, and the new subscription is created without it. You get a 201, and nothing tells you the billing day you asked for was discarded.Set the billing day on the subscriptions surface with Create Subscription or Update Subscription — not in the payments-side block that creates one. That surface uses its own field shape and its own set of type values, which differ from the payments-side object; don’t copy a billing_date object from a payment into a subscription call.

Errors

This section covers a subscription whose terms you send in the call (frequency, availability and amount). For plan_id, see Errors from a plan. A bad subscription block can fail at two different moments, and the difference matters: one of them happens before the customer is charged, the other after.

Rejected before any charge

These are caught when the request is validated, so the call fails with a 400, no money moves, and no subscription is created:
  • frequency.execution missing, or any value other than YUNO / MERCHANT.
  • frequency.type set to anything other than MONTH.
  • amount.type set to anything other than FIXED / VARIABLE.
  • amount.value or amount.currency missing, or a currency that isn’t a valid ISO 4217 code.
  • subscription.amount.currency different from the payment’s amount.currency.
  • subscription.amount.type = FIXED with a subscription.amount.value different from the payment’s amount.value.
  • frequency, availability, or amount missing while creating a new subscription (all three are required unless you send id or plan_id).
  • customer_payer missing — a payment always needs a payer, so this is refused before anything is charged.

Validated when the subscription is created

These are checked at subscription-creation time, which happens after the charge:
  • availability.start_at in the past, or finish_at at or before start_at.
  • billing_cycles.total set to 0 or a negative number.
  • frequency.value missing, or set to a fractional number.
By this point the payment may already have succeededIf one of these fails, the charge is not rolled back. The payment stands and the subscription is not created — you have a successful one-off payment and no recurrence. The payment response comes back with subscription_code: null.Apply this check only once the payment reaches a terminal status. If the payment comes back PENDING, the subscription has not been created yet and subscription_code is null because the outcome is still open — wait for the terminal status before doing anything.On a payment that is terminal and successful, treat subscription_code: null as a signal to reconcile: either refund the payment, or create the subscription separately with Create Subscription. Do not retry the original call — see Retrying the call. Checking these fields on your side before you send the call narrows the window, so it’s worth doing.
See HTTP Response Codes for the full list.