Create a checkout
POSThttps://app.shuttleglobal.com/c/api/instances/{instance_key}/checkouts
Create a hosted checkout session. The checkout accepts all parameters from the
Create Payment API (except payment_method), plus additional options that control
the checkout UX.
The response includes a checkout id (nonce) which you embed on your page via shuttle.js:
<div data-shuttle-checkout="CHECKOUT_ID" data-shuttle-style="INLINE"></div>
<script src="https://app.shuttleglobal.com/shuttle-1.4.X.js"></script>
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”object
object
Checkout options. Includes all fields from the Create Payment API (except payment_method)
plus UX-specific options for the hosted checkout experience.
object
The currency in ISO format (e.g., USD, EUR, GBP)
The payment amount as a string without commas, using ‘.’ as decimal separator.
Required in the standard case. Optional when charges is provided — if omitted,
it is derived from the sum of charges[].amount; if supplied, it must equal that sum.
Your unique reference for the payment (e.g., order ID)
Descriptive text for the payment
Unique string to prevent duplicate submissions within 24 hours
"PAYMENT"Payment action type.
PAYMENT— take the payment immediately.AUTH— reserve the funds without capturing. Capture later via the Activity view or the Capture API.TOKENISE— store the customer’s payment details without taking a payment. No transaction and no contract are created; the result is a payment method you can charge later via the Create Payment API.
Note the spelling: the value is TOKENISE, not TOKENIZE.
When using TOKENISE, omit amount and all scheduling fields (frequency,
occurrences, start_date, start_days, scheduled_date, scheduled_days,
charges) — the checkout takes no payment, so there is nothing to schedule.
save_card is redundant, as storing the card is the whole operation. Keep
currency: it determines which payment methods are offered. The stored payment
method is delivered on the PAYMENT_METHOD.ACTIVE webhook.
Only payment methods capable of the requested action are displayed. For example
Apple Pay does not support TOKENISE, and ACH does not support AUTH.
"ECOMMERCE"Source of the payment. Use MOTO if staff is entering details on behalf of customer
Existing account ID or CRM key
Account/customer details. You can provide an existing account ID or CRM key, or create a new account by providing customer details. If an account with the same CRM key already exists, it will be used.
object
Existing account ID
Your identifier for the customer (CRM key). If an account with this key exists, it will be used
Alias for crm_key
Customer’s first name
Customer’s last name
Customer’s full name (alternative to first_name/last_name)
Company name
Customer’s email address
Customer’s phone number
CSV of tags/references for the account
Customer’s address
object
Country code
Address line 1
Address line 2
Address line 3
City / Town
Postcode / ZIP
State / Region
Gateway ID to process the payment through
"ONEOFF"Payment frequency for recurring payments. Cannot be used together with charges;
to use scheduled charges, omit frequency or set it to ONEOFF.
Number of payments for recurring payments (blank = forever)
When to take first payment for recurring payments
Days from now for first recurring payment
When to process one-time payment
Days from now for one-time payment
Explicit schedule of charges for the contract. Use this when charge amounts or due dates vary between charges. All charges are created upfront at contract creation and the customer sees the full schedule in the hosted checkout.
When each charge is taken:
due: "now"or a past timestamp (within the last 24 hours) — taken synchronously as part of contract creation. A decline blocks the whole contract creation.dueset to a future timestamp — taken asynchronously by the scheduler on the due date. The contract is created regardless of that later payment’s outcome.
To have the first charge run asynchronously, set its due to a future timestamp
(even a few minutes ahead).
Constraints:
- Cannot be combined with
frequency(must be omitted orONEOFF). - Not supported with
action: AUTH. - Each charge’s
duecannot be more than 24 hours in the past. - The top-level
amountis optional whenchargesis provided. If you do provideamount, it must equal the sum ofcharges[].amount.
A single charge on an explicitly scheduled contract. Each charge carries its own amount and due date, allowing schedules with varying amounts and irregular dates.
object
Optional — your unique reference for this charge (e.g., instalment number or invoice line id). URL friendly string, max 64 chars (a-z0-9_-)
The charge amount as a string without commas, using ‘.’ as decimal separator. Must be greater than zero.
When this charge is due. Accepts either the literal string "now", or an ISO 8601 timestamp.
"now"or a past timestamp (within the last 24 hours) — taken synchronously during contract creation. A decline blocks the whole contract creation.- Future timestamp — taken asynchronously by the scheduler on the due date. The contract is created regardless of that later payment’s outcome.
A timestamp more than 24 hours in the past is rejected.
Optional. Only relevant when the checkout creates a contract (a recurring frequency or a charges schedule). When set to a future date, the contract stays active until this date even after its final scheduled payment is collected, so mid-term amendments can still be applied. Once the date has passed and no balance is outstanding, the contract completes normally.
Contract ID for one-time payment on existing contract
Legal entity ID or code processing the payment
Event date associated with the payment
Custom key-value pairs stored on the contract
object
Shipping address for the order
object
Country code
Address line 1
Address line 2
Address line 3
City / Town
Postcode / ZIP
State / Region
The order basket. Optional, but required by BNPL providers and by some acquirers to
qualify for Level 2 / Level 3 interchange rates on commercial cards. Include every line
that makes up the payment amount, including shipping and tax lines.
A single line in the order basket.
Line items are optional, but supplying them unlocks several things depending on the gateway and payment method in use:
- Level 2 / Level 3 interchange data for commercial and purchasing cards — required by some acquirers to qualify for lower interchange rates.
- Buy Now Pay Later — BNPL providers require a basket before they will underwrite the order.
- Express checkout / wallets — the basket is shown in the wallet sheet.
- Fraud screening — basket contents are passed to the fraud provider.
Amounts and units
All monetary values are in major currency units (e.g. 29.99, not 2999) and should be
sent as JSON numbers, not strings. unit_price and total_amount are gross — they
include the tax reported in total_tax.
How the line total is derived
Most gateways treat the difference between the extended price and the line total as a discount:
discount = (quantity x unit_price) - total_amount
So for a line with no discount, set total_amount to quantity x unit_price. Where a
gateway accepts an explicit discount, total_discount is used instead.
Consistency with the payment amount
Shuttle does not reject a basket that fails to add up to the payment amount, but gateways
may. Where the basket totals less than the payment amount, some gateways (PayPal, for
example) add a balancing “Miscellaneous” line automatically. Send a complete basket
wherever possible, including shipping and tax lines.
Where line items are used for Level 2 / Level 3 interchange data, the card networks
require the breakdown to reconcile exactly — sum(total_amount) must equal the payment
amount. Where it does not (a part payment, an instalment, an amount override, a discount
that is not itemised), the interchange data is simply not sent and the payment goes through
unchanged. Line items never cause a payment to fail.
Not every field reaches every gateway. Fields are mapped to whatever the target gateway
supports and silently dropped otherwise. name, quantity, unit_price and
total_amount are the fields understood everywhere, so populate at least those.
object
Display name of the item. Shown to the customer in wallet sheets and BNPL baskets, and used as the item description for Level 2/3 data. Some gateways truncate this aggressively (Authorize.Net to 31 characters, Fat Zebra to 40), so keep it short.
Your product code / SKU for the item.
PayPal only: a line item whose sku is shipping, handling or insurance
(case-insensitive) is removed from the basket and its total_amount is reported in the
corresponding PayPal order breakdown field instead of as a basket line.
Longer description of the item, where name is not enough. Only used by gateways that
accept a separate description field; those gateways fall back to name when this is
omitted.
Number of units of this item.
Unit that quantity is expressed in — for example each, hours, metres. Used in
Level 3 interchange data, where the card networks require it. Alphanumeric, maximum 12
characters; a longer or malformed value is replaced with each, as is an absent one.
Gross price of a single unit, in major currency units, including tax.
Gross total for the line, in major currency units, including tax and after any discount. See the discount formula above.
Tax included in total_amount for this line, in major currency units. Send 0 for a
tax-free line rather than omitting the field — several gateways sum this across the
basket to report an order-level tax total.
Explicit discount applied to this line, in major currency units. Only used by gateways
that accept a discount amount per line (CyberSource, Worldpay). Other gateways derive
the discount from (quantity x unit_price) - total_amount.
Express the discount this way rather than as a negative line item. A negative line is not forwarded as Level 2/3 data.
Tax rate applied to this line, passed through unchanged. Only used by gateways that
accept an explicit rate (currently CyberSource, which expects a decimal fraction —
0.2 for 20%). Where it is omitted, gateways that need a rate derive one from
total_tax and total_amount.
Discount rate applied to this line, passed through unchanged. Only used by gateways that accept an explicit rate (currently CyberSource).
HTTPS URL of the product page for this item. Displayed by BNPL providers (Klarna, Affirm) in the basket they present to the customer.
HTTPS URL of a product image for this item. Displayed by BNPL providers (Klarna, Affirm) in the basket they present to the customer.
Hotel-specific data passed through to the payment gateway
object
Label displayed in the header of the checkout dialogue
Additional text displayed below the amount to describe the payment
Default currency when currency is selectable (omit currency to allow selection)
Default amount when amount is enterable (omit amount to allow entry)
Default state of the “save card” checkbox
Force saving (true) or not saving (false) the card. Overrides user choice
Remove the confirmation step during checkout
Dismiss dialogue on successful payment instead of showing a receipt
Only allow new payment methods, do not show saved payment methods
Force creation of a new payment method even if a matching one exists
Hide the “save card” checkbox from the user
2-letter language code or full locale (e.g., en or en_US). Defaults to browser locale
IANA timezone name to use for date/time display (e.g., America/New_York)
HTTPS URL of a custom logo. Set to false to disable the logo
Display the logo larger, vertically centered around the top of the popup
Restrict available payment types (e.g., ["CARDS"] or ["ACH", "SEPA"])
"DEFAULT"DEFAULT presents a modal popup, INLINE renders within a specified div
URL to redirect the user to after successful payment. Query parameters will be appended with payment details
URL to redirect the user to if payment is abandoned
Ids of the contracts the payment method captured by this checkout is attached to once it is active.
Examples
Basic checkout
{ "checkout": { "options": { "currency": "EUR", "amount": "100", "alt_key": "1234", "description": "Invoice 1234", "account": { "crm_key": "A00001", "first_name": "Jane", "last_name": "Doe", "email": "jane.doe@email.com" } } }}Inline checkout with branding
{ "checkout": { "options": { "currency": "USD", "amount": "49.99", "title": "Complete your purchase", "style": "INLINE", "logo_url": "https://example.com/logo.png", "account": { "email": "customer@example.com" } } }}Checkout with an order basket
Supply line_items to enable Buy Now Pay Later, wallet baskets and Level 2 / Level 3 interchange data. Include shipping as its own line so the basket adds up to amount.
{ "checkout": { "options": { "currency": "USD", "amount": "44.99", "alt_key": "ORDER-1234", "description": "Order 1234", "account": { "crm_key": "A00001", "first_name": "Jane", "last_name": "Doe", "email": "jane.doe@email.com" }, "shipping": { "line1": "1 Lyric Square", "line4": "London", "line5": "W6 0NB", "country": "GB" }, "line_items": [ { "sku": "SHOE-10-BLK", "name": "Running shoes", "description": "Black running shoes, UK size 10", "quantity": 2, "unit_price": 20, "total_amount": 40, "total_tax": 4, "item_url": "https://example.com/products/shoe-10-blk", "image_url": "https://example.com/images/shoe-10-blk.jpg" }, { "sku": "SHIPPING", "name": "Standard delivery", "quantity": 1, "unit_price": 4.99, "total_amount": 4.99, "total_tax": 0 } ] } }}Responses
Section titled “Responses”Checkout session created
object
The checkout session ID (same as checkout.id)
object
Checkout session ID (same as the nonce)
The nonce for this checkout session
The payment options passed when creating the checkout
object
Current status of the checkout session
Bad request - invalid parameters
Every error has a code and a message. Some add more fields alongside them, with detail about the error.
object
The error code, for example VALIDATION_ERROR, INVALID, INVALID_REQUEST, UNAUTHORIZED, FORBIDDEN or NOT_FOUND. Program against this, not the message.
What went wrong, in words, for logs and support.
Unauthorised: the API key is missing or not valid
Every error has a code and a message. Some add more fields alongside them, with detail about the error.
object
The error code, for example VALIDATION_ERROR, INVALID, INVALID_REQUEST, UNAUTHORIZED, FORBIDDEN or NOT_FOUND. Program against this, not the message.
What went wrong, in words, for logs and support.
Example
{ "code": "UNAUTHORIZED", "message": "Unauthorised"}Was this page helpful?
What went wrong?
Thanks for telling us.