---
title: "Read a payment attempt outcome"
method: GET
path: "/v1/trip/{trip_id}/payment_attempts/{payment_attempt_id}"
tags: ["Pricing & booking"]
---

# Read a payment attempt outcome

`GET /v1/trip/{trip_id}/payment_attempts/{payment_attempt_id}`

## Request

- Base URL: `https://api.gojinko.com`
- URL: `https://api.gojinko.com/v1/trip/{trip_id}/payment_attempts/{payment_attempt_id}`
- Auth: one of:
  - API key in header `X-API-Key`
  - HTTP bearer

## Path parameters

- `trip_id` string, required
- `payment_attempt_id` string, required

## Response `200`

Payment attempt outcome

- PaymentAttemptOutcome
  - `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.
  - `quote_id` string, required: The quote this payment is taken against.
  - `quoted_cart_id` integer, required: Deprecated: use `quote_id` instead. The same quote as an integer.
  - `fulfillment_cart_id` integer: Deprecated: use `booking_ref` instead. An internal number for the booking this payment funds.
  - `payment_status` 'not_started' | 'pending' | 'requires_authentication' | 'authorized' | 'captured' | 'declined' | 'cancelling' | 'cancelled' | 'expired' | 'failed', required
  - `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.
  - `failure_reason` string, nullable: 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`).
  - `items` object[]
    - `booked_item_id` string: The booked item, as get_booking and the servicing routes name it. Absent only when the item cannot be named yet.
    - `item_id` integer, required: Deprecated: use `booked_item_id` instead. The booked item as an integer.
    - `outcome` string, required
    - `failure_reason` string, nullable: 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`).
  - `booking_ref` string: The booking reference. Absent until the booking has one; never null.
  - `payment_error` object, nullable, 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 the quote expires. It returns to null when a card is authorized. `CARD_ALIAS_EXPIRED`: The card alias expired before the booking was dispatched. Follow `recovery.action`; when it is `retry_new_key`: Submit the card again on the pay hostname with a new Idempotency-Key.
    - `code` 'CREDENTIAL_FORMAT_INVALID' | 'PAYMENT_TYPE_NOT_ENABLED' | 'PAYMENT_CREDENTIAL_INVALID' | 'TRIP_OWNED_BY_OTHER_PAYMENT' | 'IDEMPOTENCY_KEY_REUSED' | 'ATTEMPT_IN_PROGRESS' | 'CARD_DECLINED' | 'CARD_ALIAS_EXPIRED' | 'PAYMENT_CREDENTIAL_REJECTED' | 'AUTHENTICATION_REQUIRED' | 'AUTHENTICATION_FAILED' | 'AUTHENTICATION_ABANDONED' | 'QUOTE_EXPIRED' | 'ATTEMPT_TERMINAL' | 'PAYMENT_OUTCOME_UNKNOWN' | 'FULFILLMENT_DISPATCH_DELAYED' | 'RECONCILIATION_REQUIRED' | 'TEMPORARILY_UNAVAILABLE', required
    - `message` string, required
  - `recovery` object, required
    - `action` 'poll' | 'authenticate' | 'retry_same_key' | 'retry_new_key' | 'recheckout' | 'contact_support' | 'stop', required: The next step. `authenticate`: when `authentication` is present, open `authentication.url` before `authentication.expires_at`. For a Shared Payment Token (`spt`), first read the token's `next_action.use_stripe_sdk.value` with your own Stripe secret key and append it unchanged: open `authentication.url + "#hv=" + <value>`, or call `stripe.handleNextAction({ hashedValue })` with Stripe.js on your own page. Then poll `GET /v1/trip/{trip_id}/payment_attempts/{payment_attempt_id}` until `payment_status` is none of `requires_authentication`, `cancelling` or `pending`.
    - `replacement_credential_required` boolean, required
  - `recovery_status` 'automatic' | 'manual_review', required
  - `quote_expires_at` string, date-time: Deadline for completing this payment (RFC 3339): the quote deadline the checkout response and the trip's `quote` call `expires_at`.
  - `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.
    - `url` string, required
    - `expires_at` string, date-time, required
  - `money` object
    - `authorized` Money: A money figure in one of two scales. New integrations read the `*_money` field beside it (a `MoneyValue`) where there is one, and `value` on objects that carry it; the rule below applies only to the deprecated forms. When `decimal_places` is present, `value` (or the deprecated `amount`) is an INTEGER in minor units: divide by 10 ** decimal_places. When it is absent, the deprecated `amount` is already in MAJOR units. Branch on whether decimal_places is present in the response you received, never on the currency code or the field name. `display` is the same figure as a string to show.
      - `amount` number: Deprecated: use `value` instead (the same integer) where this object carries decimal_places. Where it does not, the figure is in MAJOR units and the field holding this object is itself deprecated: read its `*_money` sibling. The two-scale rule applies only to deprecated fields. Alternative to `value` on some endpoints (the two never appear together); its scale depends on decimal_places. When this object carries decimal_places, amount is an INTEGER in minor units — divide by 10 ** decimal_places (e.g. select_ancillaries total_with_ancillaries). When there is no decimal_places field, amount is a decimal in MAJOR units, safe to display as-is (e.g. trip and checkout totals).
      - `value` integer: Integer amount in MINOR units, always paired with decimal_places — divide by 10 ** decimal_places to display. Example: value 15977 with decimal_places 2 is 159.77 USD. Rendering this field directly shows prices 100x too high for 2-decimal currencies.
      - `currency` string: ISO 4217 currency code.
      - `decimal_places` integer: Scale of the integer value/amount: display = integer / 10 ** decimal_places. Always sent alongside minor-unit amounts. Usually the ISO 4217 digits of the currency (2 for USD/EUR/GBP, 0 for JPY/KRW, 3 for BHD/JOD/KWD) but currency-converted prices can carry a different scale — ALWAYS use the decimal_places sent with the amount, never a hardcoded 2. Only if the field is genuinely absent on a value-shaped object, fall back to the ISO digits for the currency.
      - `display` string: The same figure as a string ready to show: the ISO 4217 code, a space, then the amount, e.g. "USD 159.77". With decimal_places it is written at exactly that scale (value 1561500, JPY, decimal_places 2 is "JPY 15615.00"); without, at the ISO digits of the currency. Show this; compute with the number. Absent when the figure is not money (a cancellation step expressed as a percent or a number of nights) or could not be read unambiguously.
    - `captured` Money: A money figure in one of two scales. New integrations read the `*_money` field beside it (a `MoneyValue`) where there is one, and `value` on objects that carry it; the rule below applies only to the deprecated forms. When `decimal_places` is present, `value` (or the deprecated `amount`) is an INTEGER in minor units: divide by 10 ** decimal_places. When it is absent, the deprecated `amount` is already in MAJOR units. Branch on whether decimal_places is present in the response you received, never on the currency code or the field name. `display` is the same figure as a string to show.
      - `amount` number: Deprecated: use `value` instead (the same integer) where this object carries decimal_places. Where it does not, the figure is in MAJOR units and the field holding this object is itself deprecated: read its `*_money` sibling. The two-scale rule applies only to deprecated fields. Alternative to `value` on some endpoints (the two never appear together); its scale depends on decimal_places. When this object carries decimal_places, amount is an INTEGER in minor units — divide by 10 ** decimal_places (e.g. select_ancillaries total_with_ancillaries). When there is no decimal_places field, amount is a decimal in MAJOR units, safe to display as-is (e.g. trip and checkout totals).
      - `value` integer: Integer amount in MINOR units, always paired with decimal_places — divide by 10 ** decimal_places to display. Example: value 15977 with decimal_places 2 is 159.77 USD. Rendering this field directly shows prices 100x too high for 2-decimal currencies.
      - `currency` string: ISO 4217 currency code.
      - `decimal_places` integer: Scale of the integer value/amount: display = integer / 10 ** decimal_places. Always sent alongside minor-unit amounts. Usually the ISO 4217 digits of the currency (2 for USD/EUR/GBP, 0 for JPY/KRW, 3 for BHD/JOD/KWD) but currency-converted prices can carry a different scale — ALWAYS use the decimal_places sent with the amount, never a hardcoded 2. Only if the field is genuinely absent on a value-shaped object, fall back to the ISO digits for the currency.
      - `display` string: The same figure as a string ready to show: the ISO 4217 code, a space, then the amount, e.g. "USD 159.77". With decimal_places it is written at exactly that scale (value 1561500, JPY, decimal_places 2 is "JPY 15615.00"); without, at the ISO digits of the currency. Show this; compute with the number. Absent when the figure is not money (a cancellation step expressed as a percent or a number of nights) or could not be read unambiguously.
    - `released` Money: A money figure in one of two scales. New integrations read the `*_money` field beside it (a `MoneyValue`) where there is one, and `value` on objects that carry it; the rule below applies only to the deprecated forms. When `decimal_places` is present, `value` (or the deprecated `amount`) is an INTEGER in minor units: divide by 10 ** decimal_places. When it is absent, the deprecated `amount` is already in MAJOR units. Branch on whether decimal_places is present in the response you received, never on the currency code or the field name. `display` is the same figure as a string to show.
      - `amount` number: Deprecated: use `value` instead (the same integer) where this object carries decimal_places. Where it does not, the figure is in MAJOR units and the field holding this object is itself deprecated: read its `*_money` sibling. The two-scale rule applies only to deprecated fields. Alternative to `value` on some endpoints (the two never appear together); its scale depends on decimal_places. When this object carries decimal_places, amount is an INTEGER in minor units — divide by 10 ** decimal_places (e.g. select_ancillaries total_with_ancillaries). When there is no decimal_places field, amount is a decimal in MAJOR units, safe to display as-is (e.g. trip and checkout totals).
      - `value` integer: Integer amount in MINOR units, always paired with decimal_places — divide by 10 ** decimal_places to display. Example: value 15977 with decimal_places 2 is 159.77 USD. Rendering this field directly shows prices 100x too high for 2-decimal currencies.
      - `currency` string: ISO 4217 currency code.
      - `decimal_places` integer: Scale of the integer value/amount: display = integer / 10 ** decimal_places. Always sent alongside minor-unit amounts. Usually the ISO 4217 digits of the currency (2 for USD/EUR/GBP, 0 for JPY/KRW, 3 for BHD/JOD/KWD) but currency-converted prices can carry a different scale — ALWAYS use the decimal_places sent with the amount, never a hardcoded 2. Only if the field is genuinely absent on a value-shaped object, fall back to the ISO digits for the currency.
      - `display` string: The same figure as a string ready to show: the ISO 4217 code, a space, then the amount, e.g. "USD 159.77". With decimal_places it is written at exactly that scale (value 1561500, JPY, decimal_places 2 is "JPY 15615.00"); without, at the ISO digits of the currency. Show this; compute with the number. Absent when the figure is not money (a cancellation step expressed as a percent or a number of nights) or could not be read unambiguously.
    - `refunded` Money: A money figure in one of two scales. New integrations read the `*_money` field beside it (a `MoneyValue`) where there is one, and `value` on objects that carry it; the rule below applies only to the deprecated forms. When `decimal_places` is present, `value` (or the deprecated `amount`) is an INTEGER in minor units: divide by 10 ** decimal_places. When it is absent, the deprecated `amount` is already in MAJOR units. Branch on whether decimal_places is present in the response you received, never on the currency code or the field name. `display` is the same figure as a string to show.
      - `amount` number: Deprecated: use `value` instead (the same integer) where this object carries decimal_places. Where it does not, the figure is in MAJOR units and the field holding this object is itself deprecated: read its `*_money` sibling. The two-scale rule applies only to deprecated fields. Alternative to `value` on some endpoints (the two never appear together); its scale depends on decimal_places. When this object carries decimal_places, amount is an INTEGER in minor units — divide by 10 ** decimal_places (e.g. select_ancillaries total_with_ancillaries). When there is no decimal_places field, amount is a decimal in MAJOR units, safe to display as-is (e.g. trip and checkout totals).
      - `value` integer: Integer amount in MINOR units, always paired with decimal_places — divide by 10 ** decimal_places to display. Example: value 15977 with decimal_places 2 is 159.77 USD. Rendering this field directly shows prices 100x too high for 2-decimal currencies.
      - `currency` string: ISO 4217 currency code.
      - `decimal_places` integer: Scale of the integer value/amount: display = integer / 10 ** decimal_places. Always sent alongside minor-unit amounts. Usually the ISO 4217 digits of the currency (2 for USD/EUR/GBP, 0 for JPY/KRW, 3 for BHD/JOD/KWD) but currency-converted prices can carry a different scale — ALWAYS use the decimal_places sent with the amount, never a hardcoded 2. Only if the field is genuinely absent on a value-shaped object, fall back to the ISO digits for the currency.
      - `display` string: The same figure as a string ready to show: the ISO 4217 code, a space, then the amount, e.g. "USD 159.77". With decimal_places it is written at exactly that scale (value 1561500, JPY, decimal_places 2 is "JPY 15615.00"); without, at the ISO digits of the currency. Show this; compute with the number. Absent when the figure is not money (a cancellation step expressed as a percent or a number of nights) or could not be read unambiguously.
    - `externally_reimbursed` Money: A money figure in one of two scales. New integrations read the `*_money` field beside it (a `MoneyValue`) where there is one, and `value` on objects that carry it; the rule below applies only to the deprecated forms. When `decimal_places` is present, `value` (or the deprecated `amount`) is an INTEGER in minor units: divide by 10 ** decimal_places. When it is absent, the deprecated `amount` is already in MAJOR units. Branch on whether decimal_places is present in the response you received, never on the currency code or the field name. `display` is the same figure as a string to show.
      - `amount` number: Deprecated: use `value` instead (the same integer) where this object carries decimal_places. Where it does not, the figure is in MAJOR units and the field holding this object is itself deprecated: read its `*_money` sibling. The two-scale rule applies only to deprecated fields. Alternative to `value` on some endpoints (the two never appear together); its scale depends on decimal_places. When this object carries decimal_places, amount is an INTEGER in minor units — divide by 10 ** decimal_places (e.g. select_ancillaries total_with_ancillaries). When there is no decimal_places field, amount is a decimal in MAJOR units, safe to display as-is (e.g. trip and checkout totals).
      - `value` integer: Integer amount in MINOR units, always paired with decimal_places — divide by 10 ** decimal_places to display. Example: value 15977 with decimal_places 2 is 159.77 USD. Rendering this field directly shows prices 100x too high for 2-decimal currencies.
      - `currency` string: ISO 4217 currency code.
      - `decimal_places` integer: Scale of the integer value/amount: display = integer / 10 ** decimal_places. Always sent alongside minor-unit amounts. Usually the ISO 4217 digits of the currency (2 for USD/EUR/GBP, 0 for JPY/KRW, 3 for BHD/JOD/KWD) but currency-converted prices can carry a different scale — ALWAYS use the decimal_places sent with the amount, never a hardcoded 2. Only if the field is genuinely absent on a value-shaped object, fall back to the ISO digits for the currency.
      - `display` string: The same figure as a string ready to show: the ISO 4217 code, a space, then the amount, e.g. "USD 159.77". With decimal_places it is written at exactly that scale (value 1561500, JPY, decimal_places 2 is "JPY 15615.00"); without, at the ISO digits of the currency. Show this; compute with the number. Absent when the figure is not money (a cancellation step expressed as a percent or a number of nights) or could not be read unambiguously.
    - `resolution_status` 'pending' | 'resolved' | 'manual_review' | 'external_reimbursement_pending' | 'externally_reimbursed'
    - `refund_reference` string

## Other responses

- `400`: Bad request
- `401`: Authentication required
- `402`: Payment required — organization balance exhausted
- `403`: Payment attempt access forbidden. **`FORBIDDEN`** — The credential is valid, and this request is refused anyway. Do not rotate the key — it is working. Check that it is entitled to this operation, and on this environment.
- `404`: Resource not found
- `409`: The operation conflicts with the current state of the resource
- `410`: The resource this request names no longer exists
- `422`: Validation error
- `429`: Rate limit or quota exceeded
- `502`: The travel provider rejected the request, or an upstream call failed
- `503`: No travel provider can serve the request right now
- `504`: The travel provider did not answer in time

---

[API](https://skmtc.dev/gojinko/apis/jinko-public-api.md) - [All operations](https://skmtc.dev/gojinko/apis/jinko-public-api/llms.txt) - [OpenAPI document](https://skmtc.dev/gojinko/apis/jinko-public-api/revisions/ac5046767e4c?raw)
