Vezmo App

Billing

Invoices

An invoice bills one of your clients for a list of line items. We email it to the client with a link to pay online, and its status tells you where it stands.

How an invoice works

Create an invoice → we email it to the client → the client pays online.

Test mode

An invoice takes the mode of the API key that made it. An invoice made with a TEST key is a sandbox invoice: it is paid with test cards only, no real money moves, and its pay page shows a Test mode badge. Invoices you make in the dashboard are live.

  • In test mode, emails go only to your team's addresses. A sandbox invoice is emailed only when its client's email is the address of you or a member of your team; it then has a TEST MODE — no money moved banner and [TEST] at the start of the subject. To any other client it is not emailed: Send invoice still answers success: true, with emailSkipped: "test_mode", the client's activity shows the skip, and the invoice still counts as sent (invoice.sent fires). A skipped email doesn't count toward your email limits. To see the email, use your own address as the client.
  • Receipts and other emails to the payer of a sandbox payment (paylinks, invoices, secure payments and subscriptions, on both tracks) follow the same rule.
  • A key only sees invoices of its own mode: lists leave the other mode's out, and reading, updating, sending, deleting or restoring one answers 404. For an invoice your business has in the other mode, the message says so: No such invoice: 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). Switch keys.
  • The invoice webhooks (invoice.created, invoice.sent, invoice.paid, invoice.cancelled) and the payment webhooks carry livemode; it is false for a sandbox invoice.
  • Each invoice carries environment: LIVE or TEST. It never changes.

Totals come from line items

Every invoice needs at least one line item. Each item is unitPrice × quantity, minus its discount (a percent, or a fixed amount when discountType is $), plus its tax percent. The invoice amount, discount and tax are the sums of the items. Amounts are in major units, such as 49.90, and come back as strings, such as "49.9".

Emails to your client

  • Creating an invoice emails it to the client right away, even when its status is DRAFT.
  • Updating an invoice emails the updated version.
  • Send invoice emails it again. Paid and cancelled invoices are never emailed.
  • An invoice is emailed at most once a minute. An edit inside that minute is saved but sends no email, and a second Send inside it answers 429.
  • Each business can send 500 invoice and proposal emails in 24 hours. See Email limits.

Statuses

  • You set DRAFT, PENDING (the default) or CANCELLED. Cancelling sends invoice.cancelled.
  • PAID comes only from a payment going through. A paid or cancelled invoice is final: it can't be changed.
  • OVERDUE is never stored. An unpaid invoice keeps its status after its due date; to find late invoices, list with status=OVERDUE.

Client projects

Attach an invoice to one of your client projects with clientProjectId, and list a project's invoices with GET /merchant/invoice?clientProjectId=….

Paying from your own page

The invoice's payment page (the link in the invoice email) does all of this for you. To take the payment on a page of your own, with your API key:

  • POST /merchant/invoice/{id}/checkout with method makes the payment for one way to pay, at its price, and answers the publishableKey and connectedAccountId to mount our payment form with. For a bank debit, Instant ACH or Cash App (ach, instantAch, cashapp; upi and pix for a customer paying in rupees or reais), confirm its clientSecret in the payment form and record it with POST /merchant/invoice/{id}/confirm.
  • Klarna, Affirm, Afterpay or Amazon Pay are paid by our server, like a card: their price depends on where the customer is, so it prices the very payment method first. Make it with the payment form's createPaymentMethod (its type, and billing_details with the customer's email and address, country included) and send it to POST /merchant/invoice/{id}/pay as paymentMethodId with returnUrl (your page's http(s) address; required for these). It answers requires_action with a clientSecret that only sends the customer to the method's page (the payment form's next-action step); back on returnUrl, record it with /confirm.
  • 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 /merchant/invoice/{id}/pay as paymentMethodId. It answers state: succeeded, processing, or requires_action with a clientSecret that only finishes 3D Secure (the payment form's next-action step). Then /confirm records it; after 3D Secure our server confirms the card there and may answer requiresAction again (run it, call /confirm again) or pending. A declined card is a 400 with errors[0].code and errors[0].paymentIntentId.
  • Checkout without a method, or with a pay-later one, answers 400 use_pay_route; method: "card" makes a card payment only our server can confirm (through /pay). method_unavailable: that way to pay isn't offered for this invoice. The same for a merchant-of-record business (since 27 October 2026; its fee is set when the payment settles).
  • These three routes take money, so they need the write scope invoice.update (a key with only invoice.read gets 403). They count toward your key's rate limit. Too many declined cards on one invoice, 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.
  • Cancelling an invoice or changing its amount while your client's bank payment on it is clearing or waiting on its micro-deposits answers 409 bank_payment_pending (or 400 “still clearing”) until it finishes; that payment is never cancelled. A payment already under way when you cancel that still goes through is recorded, and the invoice reads paid (the money moved).

Knowing an invoice is paid

Treat an invoice as paid when you receive the invoice.paid webhook, or payment.success with its invoiceId. Cancelling an invoice sends invoice.cancelled.

Deleting and restoring

Delete invoice moves an invoice to the trash. Restore invoice brings it back. A paid invoice, or one with a payment or a bank payment still clearing, can't be deleted.

Required API-key permissions

  • invoice.read: list and get invoices.
  • invoice.update: update an invoice, and take an invoice's payment from your own page (POST /merchant/invoice/{id}/checkout, …/pay, …/confirm).
  • invoice.send: Send invoice.
  • invoice.create, invoice.delete and invoice.restore: the matching endpoint.

Emailing your client on demand needs invoice.send. Keys that could create or update invoices when this scope was added were given it, and a new key gets every invoice scope. A key without it gets 403 “Insufficient API permissions” with required: ["invoice.send"] on Send.