Skip to main content

Creating Payment Links as a Partner

Payment links work the same way orders do: authenticate with the merchant’s merchant_key from the store_onboarded webhook and call the standard POST /v1/links endpoint.
The merchant key is what authorizes this call and what decides which store the link belongs to. You may add your X-API-Key/X-API-Secret for attribution, but they never change the target store. See Partner Authentication.

Example

The response and behavior are identical to standard payment links. See Payment Links for fixed vs. dynamic links and redirect configuration.

order_key is the order identifier, not a free reference

This is the field partners most often get wrong, so it is worth stating here as well as in Order key semantics. order_key identifies the order on your platform: one order_key = one order = one link = one payment. It is an idempotency key scoped to (store, order_key), and resending it does not reliably create a new link — that is the anti-double-charge guarantee. When a link already exists for that (store, order_key): No field in the response says “reused”, and you should not try to infer it. On POST /v1/links the reuse path today happens to omit expires_at and wallet_id, which a fresh creation includes — but that is an incidental by-product of the code path, not a documented contract, and both fields are often null on a genuine creation anyway. On POST /links/tiendanube the two responses are byte-identical and there is no difference to detect at all. Build your integration so it does not need to know: a 200 means this order_key now has exactly one link. An explicit 409 PAYMENT_LINK_ALREADY_EXISTS is planned behind the LINKS_CONFLICT_409_ENABLED flag and is not live today — do not depend on it.
Generate a unique order_key per buyer. Keying it on a product, a plan, or an event breaks as soon as two buyers of the same merchant pay the same amount at the same time — for example, a race sending "order_key": "race-10k" for every registration to the 10K distance. The first registration wins the link; once it is paid, every later request gets that same link back. Use "race-10k-reg-84213" instead: one key per registration.Dropping order_key altogether is not a workaround. Links are keyed on the store plus a hash of the request body, so identical bodies collapse onto the same link.
order_key is not the link’s hash, and the hash cannot be derived from it — the hash comes from the whole request body. Never construct a checkout URL from an order_key; use the link the API returns.
Links you create through the API have source: "api". When one is paid, you receive order_payment and link_paid on your partner webhook URL. Links a merchant creates from the Wava dashboard have source: "wava" and emit no partner webhooks.