Hosted Checkout Redirects
A headless shop does not have to build the whole purchase flow itself. It can run its own event pages and cart, create the checkout through the API, and hand the buyer over to the vivenu checkout for details and payment. With a redirectUrl on the checkout, the buyer is sent back to your shop once the checkout ends, instead of landing on vivenu's confirmation page.
This saves you from rebuilding the details form, payment methods and gateway integrations described in Creating Custom Checkout Experiences, while the buyer still starts and ends the journey on your site.
Before you start
The hosted checkout only redirects to hosts that have been approved for your seller.
The allow-list can only be set by the vivenu team. Reach out to your contact
at vivenu with the hosts you want to use, for example tickets.example.com.
- Entries are hosts, not URLs: no scheme, no path. Add the port if your shop does not run on the default
443, e.g.staging.example.com:8443. - The match is exact. There are no wildcards, so
shop.example.comandwww.example.comare two separate entries. - With an empty list, every checkout carrying a
redirectUrlis rejected.
Have your staging host added first and test against a test seller before going live.
How it works
- You create the checkout server side with your API key and pass the
redirectUrl. vivenu checks it against the allow-list. - You send the buyer to the hosted checkout for that checkout.
- vivenu redirects back to your
redirectUrlwhen the checkout ends, with the checkout's id, secret and a status hint attached. - You verify the checkout through the API before showing a confirmation or fulfilling anything.
Creating the checkout
Create the checkout with POST /api/checkouts. The endpoint requires an API key with the TransactionsCreate permission, so call it from your backend and never expose the key to the browser.
{
"type": "transaction",
"eventId": "<eventId>",
"salesChannelId": "<salesChannelId>",
"items": [
{ "type": "ticket", "ticketTypeId": "<ticketTypeId>", "amount": 2 }
],
"redirectUrl": "https://tickets.example.com/checkout/return?order=42"
}
The redirectUrl has to be:
- an absolute
httpsURL of at most 2048 characters, - free of credentials (no
user:password@), - on a host from the allow-list.
The URL is stored per checkout, so you can carry your own reference along in its query string, like order=42 above. The value is returned as redirectUrl on the checkout object.
redirectUrl is only accepted on POST /api/checkouts. The public POST /api/checkout endpoint used by storefronts rejects it with a 400, so a
buyer cannot point a checkout at a host of their choosing.
Sending the buyer to the checkout
The response contains the checkout's _id and secret. Redirect the buyer to the checkout page of your vivenu shop with both:
https://<your shop domain>/booking/details?checkoutId=<_id>&secret=<secret>
Use your custom domain if your seller has one configured, see Domains.
Handling the return
The hosted checkout redirects the buyer to your redirectUrl with three query parameters appended. An existing query string is kept, so the example above returns as:
https://tickets.example.com/checkout/return?order=42&checkoutId=<_id>&secret=<secret>&status=complete
Avoid using checkoutId, secret or status as your own parameter names in the redirectUrl.
status | When |
|---|---|
complete | The payment succeeded and the checkout completed, including payments that went through a redirect gateway first. |
expired | The reservation time ran out or the checkout was aborted while the buyer had it open. |
open | The buyer left through the seller logo in the checkout header. The checkout is still running and can be resumed until it expires. |
When the buyer leaves with open, you can send them back to the same checkout URL to continue, as long as the checkout has not expired.
Verifying the checkout
The status parameter is a hint to route the buyer, not proof of payment. Anyone can open your return page with status=complete in the URL. Before you show a confirmation or fulfil anything, fetch the checkout and check its actual status:
GET /api/checkout/{checkoutId}?secret={secret}
Checkout status | Meaning |
|---|---|
COMPLETE | Paid. The transactions have been created. |
NEW | Still running. The buyer has not finished yet. |
ABORTED | Expired or aborted. No transactions were created. |
Also make sure the checkoutId belongs to a checkout your shop created, for example by matching it against the id you stored when calling POST /api/checkouts.
The redirect only happens while the buyer has the checkout open in their browser. If they close the tab after paying, or the reservation runs out while the page is closed, nobody comes back to your redirectUrl. Do not rely on the redirect for fulfilment — use Webhooks or poll the checkout to learn about completed purchases.
The secret grants read access to the checkout. Do not log it, and set a
Referrer-Policy on your return page so it is not passed on to third-party
resources loaded there.
Errors
POST /api/checkouts rejects an invalid redirectUrl with a 400:
- A validation error on
redirectUrl— the URL is not absolute, does not usehttps, or is longer than 2048 characters. redirectUrl must not contain credentials— the URL contains a username or password.redirectUrl host is not allowed for this seller— the host, including its port, is not on the seller's allow-list, or the list is empty.