Skip to main content
Your customers have been paying somewhere for a while. Connecting the gateway does not move them here on its own, and this page is why, and what to do about it.

Why they do not arrive by themselves

Every subscription this system holds is a mirror of one at your gateway, and the ordinary way a row comes to exist is a checkout started here: the row is created first, its id travels to the gateway as the checkout’s client reference, and the completed checkout is what ties the two together. A subscription created before any of that — years ago, or last week in Stripe’s own dashboard — never went through that door. Its webhooks do arrive, and they are stored, and they settle with a note saying nothing here is linked to sub_…. Which is correct: a gateway’s answer names a payer the gateway invented, and which of your teams that is is not something it can tell us. That is the only missing piece, and this is where you supply it.

Do the catalogue first

An adopted subscription needs a plan, and the plan is resolved from the price it is billed on — so the gateway’s price has to be mapped into your catalogue before the subscription can be adopted. If you have not done that yet:
That reads your gateway’s products and prices into plans and prices here, with the mapping. If you priced your product here first instead, publish your prices onto the gateway — same mapping, opposite direction. Also make sure the connection’s health check has run at least once. A price mapping is keyed on the merchant account, and the account is only known after something has asked the gateway who the keys belong to.

Then give those plans their features

This is the step that gets skipped, and it fails quietly. The import brings over plans and prices, and nothing else — no features, no matrix. A gateway knows what it charges; it has no idea what your product lets somebody do. So a subscription adopted onto an imported plan resolves to a plan with no features: the customer is on Pro, pays for Pro, and is entitled to nothing. Nothing errors, and the first report of it is a support ticket. Set the features on each plan before you adopt anything — in the panel under Catálogo, or through the catalogue API. If you already adopted, fixing the plan fixes every subscription pointing at it; entitlements resolve through the plan, not through a copy taken at adoption time.

Adopting one

201 means a row now exists that did not. Nothing in that answer came from your request except the customer. The status, the period, the trial, a scheduled cancellation and the line’s quantity are all read from the gateway; the plan comes from the price mapping. Nothing was charged and nothing changed at the gateway — what changed is that this system now holds the subscription. From then on it behaves like any other: webhooks find it, the nightly reconciliation re-reads it, entitlements resolve through its plan, and it can be changed or cancelled from here.

Naming the customer

By customer_id, or by customer_external_idyour id for the team, which is what makes this scriptable: your backend already knows which account maps to which cus_, and it should not have to hold a map of our uuids too. Send one or the other; a request carrying both holds two beliefs about who is paying. The customer has to exist. This endpoint will not create one, because a team conjured to hang money off would be a team with no members — use POST /v1/customers on the machine surface, which is the call that knows the team’s name.

Running it over a list

A migration of any size is a script, so the same act is on the machine surface under a uk_sk_ key — where the environment is the key’s and no field can move it:
Two layers answer two different retries, and it is worth knowing which is which:
  • the Idempotency-Key replays the same response, bytes and status, for a repeated request — that is what a client’s backoff needs, and it is what stops a lost answer from becoming a second call;
  • adopting the same subscription for the same customer again, under a new key, answers 200 with the row and writes nothing — that is what a batch re-run a week later needs.
The same subscription for a different customer is refused either way: it is the one repeat that means somebody made a mistake. So a script that dies halfway can simply be run again. Read your own map of account to cus_, resolve each one’s subscriptions at the gateway, and call this once per row — the refusals below tell you which rows to look at, and the rest are done.

What it refuses to guess

There is no un-adopt. A subscription is never deleted here, and its gateway reference is only ever written into an empty column — so a wrong link is permanent, and anything that would have to be assumed is refused instead. customer_mismatch only fires when there is something to compare against. We store no cus_ of our own, so a customer’s payer reference is discovered by reading a subscription they already hold — and a customer you are about to migrate usually has none. Silence is not a mismatch, and refusing on it would refuse the whole migration.

What it will not do for you

It will not find the subscriptions. There is no “import everything” here, and that is deliberate: which team each sub_ belongs to is the one fact this system cannot derive, and a bulk endpoint would have to guess it for every row at once. Your backend has the map; this is the call that records it. It will not backfill the invoices. What is adopted is the subscription and its current state. Payments made before it existed here stayed at the gateway, which is still where that history lives; invoices from the next payment onward arrive by webhook as usual.

Last: point the gateway’s webhook here

Adoption records the subscription as it is right now. Everything after that — a renewal, a failed payment, a cancellation, a plan change made at the gateway — arrives as a webhook, and only if the gateway knows where to send it. The address is on the payment provider’s screen in the panel, under URL do webhook, once the connection exists. Paste it into your gateway’s dashboard and store the signing secret back here. Skip this and everything you just migrated freezes in the state it arrived in, with nothing to indicate it. A subscription that was cancelled last month still reads as active, and the customer keeps their access.