Skip to main content
POST
Submit SPT payments; card submissions must use the payment hostname and are refused here
Typed submissions require a jnk_ API key via X-API-Key (ApiKeyAuth) or Authorization: Bearer (BearerAuth), a tenant-bound booking scope, quote_id and Idempotency-Key, and return a PaymentAttemptOutcome (200 known outcome / 202 pending). OAuth/JWT bearer tokens are supported only for the legacy flat token body, which keeps its existing authorization response. Request bodies are limited to 16 KiB. Card submissions must be sent to the payment hostname (POST https://pay.<env-domain>/v1/agent_payment/submit); see the partner card payments guide. This route refuses card submissions with 400 CREDENTIAL_FORMAT_INVALID.

Authorizations

X-API-Key
string
header
required

Headers

Idempotency-Key
string

Required on a typed submission (a body with payment); without it the request is refused with 400 CREDENTIAL_FORMAT_INVALID. Ignored on the legacy body. 1–255 printable ASCII characters. Reuse only for the same payment submission: the same key with the same body replays the first outcome, with a different body it is refused.

Required string length: 1 - 255
Pattern: ^[ -~]+$(?![\s\S])

Body

application/json
trip_id
string
required
quote_id
string
required

The quote the traveler approved: the quote_id checkout returned. The payment is taken against this quote only; a quote that is no longer payable is refused with 410 QUOTE_EXPIRED and nothing is charged.

Pattern: ^[1-9][0-9]{0,17}$(?![\s\S])
Example:

"2097152"

payment
object
required

Response

Legacy authorization result or typed payment outcome

payment_attempt_id
string
required
trip_id
string
required

The trip this attempt pays, written with a trip_ prefix (trip_1048576); the trip answers carry the same id without it (1048576). Strip the prefix to compare the two.

Example:

"trip_1048576"

quote_id
string
required

The quote this payment is taken against.

Example:

"2097152"

quoted_cart_id
integer
required
deprecated

Deprecated: use quote_id instead. The same quote as an integer.

payment_status
enum<string>
required
Available options:
pending,
requires_authentication,
authorized,
captured,
declined,
cancelling,
cancelled,
expired,
failed
booking_status
string
required

The detailed status of the booking this payment started, not_scheduled until booking begins. booking_state on GET /v1/trip/{trip_id} is its summary.

payment_error
object | null
required

Why the payment has not gone through, or null. On the checkout_url payment page, a card the issuer declines (card_declined) or whose authentication fails (authentication_failed) is reported here while payment_status stays pending and recovery.action is poll: the payer can use another card on the same page until this payment's quote_expires_at. It returns to null when a card is authorized. CARD_ALIAS_EXPIRED: The submitted card details can no longer be used for this payment. Follow recovery.action; when it is retry_new_key: Submit the card again on the pay hostname with a new Idempotency-Key.

recovery
object
required
recovery_status
enum<string>
required
Available options:
automatic,
manual_review
fulfillment_cart_id
integer
deprecated

Deprecated: use booking_ref instead. An internal number for the booking this payment funds.

failure_reason
string | null

Why the booking failed, when it failed after payment and the cause is known: offer_unavailable, price_changed, booking_not_created (the supplier holds no booking; nothing was booked and no money was taken), booking_cancelled_at_provider, ticketing_refused. Null otherwise. For offer_unavailable, the supplier no longer sells the priced offer. Nothing was booked and the card authorisation was released. Search again and book a new offer. The booking.failed webhook carries the same reason with a sentence to show the traveller (failure_message).

Example:

"booking_not_created"

items
object[]
booking_ref
string

The booking reference. Absent until the booking has one; never null.

quote_expires_at
string<date-time>

Deadline for completing this payment (RFC 3339). It is the quote deadline the checkout response and the trip's quote call expires_at, unless they say payment_stays_open: then this payment has its own, later deadline.

retry_after_seconds
integer

Seconds to wait before reading the payment attempt again. Present only while recovery.action is poll; absent otherwise, never null.

authentication
object

Where the customer authenticates when recovery.action is authenticate: open url before expires_at. For a Shared Payment Token (spt), url is a Jinko-hosted page that needs the token's hashed value: read the issued token's next_action.use_stripe_sdk.value with your own Stripe secret key and open url + "#hv=" + <value>, passing the value unchanged. The value travels in the URL fragment, which keeps it out of server logs.

money
object