Vezmo App

Billing

Paylinks

A paylink is a payment page for a fixed amount that you share as a link. Your customer opens it and pays online, with no invoice needed.

How a paylink works

Create a paylink → share its link → the customer enters their details and pays.

Test mode

A paylink takes the mode of the API key that made it. A paylink made with a TEST key is a sandbox paylink: it is paid with test cards only (for example 4242 4242 4242 4242, and 4000 0027 6000 3184 for a 3D Secure challenge), no real money moves, and its page shows a Test mode badge. A LIVE key's paylink takes real money. Paylinks you make in the dashboard are live.

  • A key only sees paylinks of its own mode: lists leave the other mode's out, and reading or updating one answers 404. For a paylink your business has in the other mode, the message says so: No such paylink: a similar object exists in live mode, but a test mode key was used to make this request. (or "exists in test mode, but a live mode key" the other way round).
  • Sandbox paylinks work before your account is approved, like every sandbox payment. The payment they produce carries livemode: false in payment.success / payment.failed and in GET /merchant/payment with your TEST key.
  • A TEST key can't make a subscribe link from a product (productId): products are sold at live prices. Use a live key, or test subscriptions with the Subscriptions API.
  • Each paylink carries environment: LIVE or TEST.

The link to share

Create paylink returns a shortCode. The payment page is https://user.vezmo.com/checkout/payments-links/{shortCode}.

Payer details

If you don’t attach one of your clients with clientId, the page asks the payer for their name and email (phone, company and country are optional) before they pay.

  • isActive: false stops payments. Set it with Update paylink; true turns the link back on.
  • A link takes payments only while its status is PENDING. Setting EXPIRED or CANCELLED stops it too.
  • PAID is set only by a payment, and then it's final: a paid link can't be paid again or have its status changed.
  • A deleted link can't be paid.

Expiry (dueDate)

dueDate is the link's Expire At: the moment it stops taking new payments. Leave it out and the link never expires.

  • A full time (2026-03-31T18:00:00Z) closes the link at that moment. A date with no time (2026-03-31) lasts to the end of that day, UTC. Links made in the dashboard close at the end of the chosen day in the merchant's own time zone.
  • After it, the link reads status: EXPIRED in every response (lists, Get paylink, updates). Nothing is written to the link, so moving dueDate later, or setting it to null, opens it again straight away.
  • Listing with status=EXPIRED includes these links, and status=PENDING leaves them out.
  • A payment the customer started before the Expire At still completes, and you get payment.success as usual. Expiry only refuses new payments.
  • The payment page tells the customer the link has expired, with your business name. A switched-off link says it is no longer active.

Starting a payment on a closed link (POST /merchant/paylinks/{code}/checkout, and the payment page's own calls) answers 400. The reason is in errors[0].code:

errors[0].codemessageWhen
PAYLINK_EXPIREDThis payment link has expired.Past its dueDate, or status set to EXPIRED.
PAYLINK_INACTIVEThis payment link is no longer active.isActive is false.
PAYLINK_PAIDThis payment link has already been paid.A one-time link that was paid.
PAYLINK_CLOSEDThis payment link can no longer be paid.status set to CANCELLED.

A subscription link refuses the same way, with PAYLINK_EXPIRED ("This subscribe link has expired.") or PAYLINK_INACTIVE ("This subscribe link is no longer active."). A deleted link answers 404.

Paying from your own page

The link's payment page does all of this for you. To take the payment on a page of your own, mount our payment form with the publishableKey and connectedAccountId from Get paylink's checkout, then:

  • A card (typed, Apple Pay or Google Pay) is paid by our server, which prices the very card first (an American Express card or a card from abroad has its own price). Make a payment method with the payment form's createPaymentMethod and send it to POST /paylinks/{code}/pay as paymentMethodId (with promoCode and localOffer, as for checkout). It answers state: succeeded, processing, or requires_action with a clientSecret that only finishes 3D Secure (the payment form's next-action step).
  • Then POST /paylinks/{code}/confirm with the paymentIntentId records the payment. After 3D Secure, our server confirms the card there. It may answer requiresAction with a new clientSecret (run it, then call /confirm again) or pending (our server finishes it; you still get payment.success). A card the customer authenticated is charged even if /confirm never comes.
  • A decline is a 400 with the reason in message, errors[0].code and errors[0].paymentIntentId (send it to /confirm to record the declined attempt).
  • Klarna, Affirm, Afterpay or Amazon Pay are paid through /pay too: their price depends on where the buyer is, so our server prices the very payment method and confirms it. Make it with the payment form's createPaymentMethod (its type, and billing_details with the buyer's email and address, country included) and send it as paymentMethodId with returnUrl (your page's http(s) address; required for these, else 400 return_url_required). It answers requires_action with a clientSecret that only sends the buyer to the method's page (the payment form's next-action step). They come back to returnUrl with payment_intent; record it with /confirm.
  • Any other way to pay: POST /merchant/paylinks/{code}/checkout (or the public POST /paylinks/{code}/checkout) with method (ach, instantAch, cashapp, upi or pix) makes an intent for that way to pay alone, at its price. Confirm it with the payment form and record it with /confirm.
  • Checkout without a method, or with a pay-later one, answers 400 use_pay_route: a card or a pay-later payment is never confirmed in a browser. method_unavailable: that way to pay isn't offered for this link. The same for a merchant-of-record business (since 27 October 2026; its fee is set when the payment settles).
  • Too many declined cards on one link, from one IP address, or the same card declined too often anywhere, and /pay answers 429 too_many_declines (see declined cards). A card on your blocklist is never charged.
  • Switching a link off, cancelling it or changing its price first closes its open checkouts; a card that finished 3D Secure on a link no longer payable is let go, never charged (/confirm answers 400 with the link's code, such as PAYLINK_INACTIVE). A customer's bank payment that is clearing or waiting on its micro-deposits is never cancelled: switching the link off leaves it to finish (it then pays the link); cancelling the link or changing its price answers 409 bank_payment_pending until it finishes.

Knowing a paylink is paid

When the payment goes through, the paylink’s status becomes PAID and you receive the payment.success webhook with its paylinkId.

Subscription links

Pass the productId of a recurring product to make a reusable subscribe link: everyone who opens it becomes a new subscriber at that product’s price.

  • Everyone who subscribes from a subscription link or a product's subscribe page confirms their email with a 6-digit code first, including customers you already know.
  • The product must be active and public.
  • A checkout that waits more than 30 days for its first payment ends.
  • The customer's manage link stops working 30 days after the subscription ends.

Required API-key permissions

  • paylink.read: list and get paylinks.
  • paylink.create: create a paylink.
  • paylink.update: update a paylink, and take its payment with your key (POST /merchant/paylinks/{code}/client, …/checkout and …/confirm). A key with only paylink.read gets 403 on these three while this rule is on (it is, by default).

Every call counts toward your key's rate limit.