# Relay authorization requests The Authorization Relay service enables you to decide whether to accept or decline incoming authorization requests for your cardholders' payments. This supports you to do the following: - Make decisions based on your own business and fraud logic. - Perform additional third-party checks before making decisions. - Manage ledgers. - Receive authorization details in real time. If you do not enable this service, Checkout.com remains responsible for approving or declining authorization requests. --- ## How it works 1. When a cardholder makes a payment with their card, the card scheme initiates an authorization request and sends it to Checkout.com's Card Issuing service. 2. We send a message containing information about the authorization request to your client-side authorization relay service with an HTTPS request. 3. You validate the authorization request's authenticity, and process the message payload. 4. You decide to approve or decline the authorization, and respond to Checkout.com with your decision within the [timeout limit](#Request_timeout_before_decline), or the authorization is automatically declined. 5. We forward your authorization response to the merchant or acquirer. ### Flowchart ![Flow diagram showing the communication between the cardholder, the merchant/acquirer, Authorization Relay service, and your server.](https://www.checkout.com/docs/Issuing/Authorization-relay-service.png) > **Note** > > No authorization requests are relayed for the following types of transaction: > - Purchase account inquiry > - PIN change > - PIN unblock --- ## Before you start 1. To configure Authorization Relay in the Dashboard, you must have one of the following [user roles](https://www.checkout.com/docs/business-operations/use-the-dashboard/manage-users/user-permissions.md#Pre-defined_roles): - Admin - _Developer_ - A custom role with the `Edit Issuing authorization relay settings` permission 2. Expose a new endpoint on your API that our Card Issuing service can call to relay your authorization requests. The endpoint must be configured to: - Accept JSON input. - Have an open TCP port for HTTPS traffic on port 443, or a custom port of your choice. - Be idempotent so that, if Checkout.com relays the same request multiple times due to network failures or timeouts, your endpoint uses the IDs provided to avoid duplicate responses. - Handle [HMAC format](#Hash-based_message_authentication_code). ### Hash-based message authentication code Hash-based message authentication code (HMAC, or hash) provides a client-server pair with a private secret key known only to that pair. For each authorization request, Checkout.com generates a unique HMAC signature, using the SHA-256 algorithm and the secret key. In the request header, we hash the HTTP request data and all the information you need to [validate the header value](#1._Validate_the_HMAC_header_value). We then send it to the server, where you decode the message using your key. --- ## Configure Authorization Relay First configure and test Authorization Relay in your sandbox environment. When the service is working as expected, you can migrate it to your production environment. 1. Sign in to the [Dashboard](https://dashboard.checkout.com/). 2. Go to _Developers_ > _Authorization relay_, and then select _Configure_. 3. In the _Configure authorization relay_ page that opens, enter your endpoint URL and select _Confirm_. 4. Copy the _App ID_ and _Secret API key_ that are generated, and ensure they're on your clipboard.
**Caution**: For security reasons, the secret API key is never shown again. 5. Select _Done_. 6. In the _Authorization relay_ page that opens, add the keys to your code. 7. Enable Authorization Relay (disabled by default) using the toggle. ### Testing You can configure and test Authorization Relay in the sandbox environment. For instructions, see [Simulate an authorization](https://www.checkout.com/docs/card-issuing/simulate-issuing-transactions.md#Simulate_an_authorization_or_pre-authorization). ### Advanced settings To configure any of the following advanced settings, contact your account manager. #### Timeout before decline Specify the time limit for your server to respond to authorization requests before they are automatically declined: - Format – Milliseconds - Default – `2000` - Maximum value – `2500` You can increase the timeout limit above the usual maximum value while testing in the sandbox environment. When you migrate to the production environment, your configured limit applies. #### User agent in headers Request Checkout.com to specify in each request header the `User-Agent`. That is, our Card Issuing service `CKO-Issuing`. --- ## Configure stand-in mode If your integration is not responding to authorization requests within the [timeout limit](#Request_timeout_before_decline), you can configure stand-in mode to respond in the meantime. This helps maintain service availability and business continuity. You can configure stand-in mode to approve either all authorizations, or set a maximum number of transactions to authorize. When an authorization is handled by stand-in mode, you receive information about it through [webhooks](#Subscribe_to_webhooks). > **Information** > > To enable stand-in mode, contact your account manager or [request support](https://dashboard.checkout.com/support/new?topic=case_account_management_and_access&issue=issue_account_changes). ### Ledger management If you use Authorization Relay for ledger management, ensure that enabling stand-in mode is within your risk margin and financial exposure limits. Use the webhooks to update the ledger for transactions approved by stand-in mode. ### Set authorization count The authorization count is the number of authorizations you want stand-in mode to approve while your integration is not responding. The count is reset when your integration starts responding again and has approved at least one authorization. You can set either an unlimited count, or a maximum count. 1. Sign in to the [Dashboard](https://dashboard.checkout.com) and ensure you have the required [user permissions](#Before_you_begin). 2. Go to _Developers_ > _Authorization relay_ > _Configuration details_. 3. In the _Stand-in mode_ tile, select _Edit_. 4. In the _Stand-in_ window: - To set an unlimited count, turn on the _Unlimited authorizations_ toggle. - To set a maximum count, enter the number in the _Maximum number of authorizations_ field. 5. Select _Save_. To remove authorization count settings: 1. Sign in to the [Dashboard](https://dashboard.checkout.com). 2. Go to _Developers_ > _Authorization relay_ > _Configuration details_. 3. In the _Stand-in mode_ tile, select _Edit_. 4. In the _Stand-in_ window: - To remove an unlimited count, turn off the _Unlimited authorizations_ toggle. - To remove a maximum count, delete the number from the _Max number of authorizations_ field. 5. Select _Save_. When you set, edit, or remove the authorization count, your [user activity log](https://www.checkout.com/docs/business-operations/use-the-dashboard/user-activity.md#Issuing) records an _Updated stand-in mode settings_ event. --- ## Receive authorization requests ### 1. Validate the HMAC header value Use your secret API key to validate the HMAC signature in the authorization request header, which has the following format: `Authorization: ` | Field name | Description | | --- | --- | | ``
`string` | The format of the header.

This value is always `HMAC`. | | ``

`string` | A colon-delimited field with the following format:
`{AppId}:{RequestSignatureBase64}:{Nonce}:{RequestTimeStamp}` | | `{AppId}`

`string` | The app identifier you copied from the Dashboard. | | `{RequestSignatureBase64}`

`Base64` | The [request signature](#2._Calculate_the_RequestSignatureBase64_value). | | `{Nonce}`

`integer` | A random number generated per request.
Format – UUID | | `{RequestTimeStamp}`

`string` | The timestamp for the request.
Format – UNIX timestamp | #### 2. Calculate the RequestSignatureBase64 value 1. To get the signature you need to calculate the final value of `RequestSignatureBase64`, concatenate the following values in this exact order: a. App ID
b. HTTP method
c. Request absolute URI, as a URL-encoded, lower-case string representation
d. Request timestamp
e. Nonce
f. Standard Base64 string representation of the HTTP request content, hashed using SHA-1
2. Retrieve your secret API key bytes using UTF8 encoding. 3. Hash the signature's bytes using the HMAC SHA-256 algorithm and your secret API Key. 4. Convert the result to a standard Base64 string, which is the `RequestSignatureBase64` value from the authorization header. ### Relayed message format The relay message Checkout.com sends to your endpoint contains the following: #### Additional headers | Field name | Description | | --- | --- | | `cko-correlation-id`
`string` | Checkout.com's unique correlation identifier.

Use this as a reference for the authorization request if contacting your account manager. | | `User-Agent`

`string`
`optional` | The [user agent](#User_agent_in_headers) for the request.

This value is always `CKO-Issuing`. | #### Body | Field | Description | | --- | --- | | `id`
`string` | The card scheme's unique identifier for the authorization request, prefixed with `msg`.

Format – 30-character alphanumeric string | | `card_id`

`string` | The unique identifier for the card used for the transaction, prefixed with `crd_`. | | `cardholder_id`

`string` | The unique identifier for the cardholder, prefixed with `crh_`. | | `transaction_id`

`string` | The unique identifier for the transaction, which links together all related authorization, reversal, and clearing messages. | | `entity`
`object` | The information about your entity. | | `entity.id`
`string` | The unique identifier for your Checkout.com entity, prefixed with `ent_`. | | `client`
`object` | The information about you from the card scheme. | | `client.id`
`string` | Your unique identifier as a Checkout.com client, prefixed with `cli_`. | | `transaction_type`

`enum` | The transaction type. This can be one of:

- `balance_inquiry` – An inquiry by the cardholder about the available balance on the card
- `cashback` – A cashback transaction
- `purchase` – A payment for a purchase
- `refund` – A full or partial refund for a purchase
- `remittance_funding` – An amount sent to a third party, usually in another country
- `withdrawal` – A withdrawal of funds from the card | | `transaction_amount`

`uint64` | The transaction amount, in the [minor currency unit](https://www.checkout.com/docs/payments/accept-payments/format-the-amount-value.md). | | `transaction_currency`

`string` | The acquirer's local currency or the local currency where the transaction took place.

Format – [ISO 4217 code](https://www.checkout.com/docs/developer-resources/testing/codes/currency-codes.md) | | `billing_amount`

`uint64` | The authorization's billing amount, in the [minor currency unit](https://www.checkout.com/docs/payments/accept-payments/format-the-amount-value.md).

Currency conversion, if required, is based on current Mastercard rates. | | `billing_currency`

`string` | The currency for billing the cardholder.

Format – [ISO 4217 code](https://www.checkout.com/docs/developer-resources/testing/codes/currency-codes.md)

Example – `USD` | | `billing_conversion_rate`

`double` | The Mastercard conversion rate used to convert the transaction amount to the billing amount. | | `transmission_date_time`

`date-time` | The date and time when the authorization request was entered into the card scheme network in UTC.
Format – ISO 8601
Example – `yyyy-mm-ddThh:mm:ss.sss` | | `ecb_conversion_rate`

`double` | The European Central Bank (ECB) comparative rate that is communicated to the cardholder if currency conversion is required. | | `digital_card`
`object` | The information about the digital card used for the transaction. | | `digital_card.id`
`string` | The unique identifier for the digital card, prefixed with `dcr_`. | | `digital_card.wallet_type`
`string`
`optional` | The type of wallet. This can be one of:
- `applepay`
- `googlepay`
- `other`
- `remote_commerce_programs` | | `digital_card.device_type`
`string`
`optional` | The type of device the cardholder used to initiate the transaction. This can be one of:
- `card`
- `other`
- `pc`
- `phone`
- `tablet`
- `vehicle`
- `wearable` | | `pos`
`object` | The information about the conditions at the point of sale at the time of the transaction. | | `pos.country_code`
`string` | The country where the point of sale (PoS) is located.

Format – [ISO-3 country code](https://www.checkout.com/docs/developer-resources/testing/codes/country-codes.md) | | `pos.postal_code`
`string` | The postal code where the PoS is located. | | `pos.card_present`
`string` | Indicates if the card was present to initiate the transaction. This can be one of:

- `not_present`
- `present`
- `unspecified` | | `pos.cardholder_present`
`string` | Indicates if the cardholder was present to initiate the transaction. This can be one of:

- `not_present`
- `present`
- `unspecified` | | `pos.entry_mode`
`string` | The way the card initiated the transaction at the PoS terminal. This can be one of:

- `contact_chip`
- `contactless_chip`
- `contactless_magstripe`
- `ecommerce`
- `magstripe`
- `manual`
- `optical_character_recognition`
- `optical_code`
- `server`
- `other` | | `merchant`
`object` | The information about the merchant. | | `merchant.name`
`string` | The merchant's company name. | | `merchant.city`
`string` | The city where the merchant is located. | | `merchant.country`
`string` | The country where the merchant is located.

Format – [ISO-3 country code](https://www.checkout.com/docs/developer-resources/testing/codes/country-codes.md) | | `merchant.state`
`string` | For US merchants, the state where they are located.

For merchants not located in the US, this value is `null`. | | `merchant.category_code`
`string` | The merchant's four-digit [category code](https://www.checkout.com/docs/developer-resources/testing/codes/merchant-category-codes.md) (MCC).

Merchants can have multiple category codes. For example, "0763, 0780". | | `merchant.merchant_id`
`string`
`optional` | The unique identifier for the merchant at the point of interaction.

This may vary per acquirer. | | `merchant.`

`payment_facilitator_id`
`string`
`optional` | The unique identifier for the payment facilitator that processed the transaction.

Only present if a payment facilitator processed the transaction. | | `merchant.sub_merchant_id`
`string`
`optional` | The unique identifier that the payment facilitator assigned to the sub-merchant.

Only present if a payment facilitator processed the transaction. | | `merchant.tax_id`
`string`
`optional` | The merchant's tax identification number. | | `merchant.website_url`
`string`
`optional` | The URL of the merchant's website. | | `three_d_secure`

`object` | The information about 3D Secure (3DS). | | `three_d_secure.`

`requested_exemption_or_exclusion`
`string` | The exemption or exclusion from Strong Customer Authentication (SCA). This can be one of:
- `acquirer_transaction_risk_analysis`
- `authentication_outage_exception`
- `low_value_payment`
- `merchant_initiated_transaction`
- `other`
- `recurring_payment`
- `secure_corporate_payment`
- `strong_customer_authentication_delegation`

For definitions, see [Possible SCA exemptions](https://www.checkout.com/docs/business-operations/ensure-regulatory-compliance/sca-compliance.md#SCA_exemptions). | | `three_d_secure.`

`sca_not_required_reason`
`string` | The reason for not requiring Strong Customer Authentication. This can be one of:

- `acquirer_transaction_risk_analysis`
- `authentication_outage_exception`
- `issuer_secure_corporate_payment`
- `low_value_payment`
- `mail_order_telephone_order`
- `merchant_initiated_transaction`
- `one_leg_out`
- `other`
- `recurring_payment`
- `secure_corporate_payment`
- `strong_customer_authentication_delegation`
- `zero_amount_asi` | | `authorization_type`

`enum` | The authorization type. This can be one of:

- `authorization`
- `deferred_authorization` – An authorization request that is processed after the transaction is completed. This is used for offline sales, where real-time connectivity is unavailable. For example, in-flight shopping. If you decline a deferred authorization, you may still receive the presentment.
- `final_authorization`
- `incremental_pre_authorization`
- `pre_authorization` | | `address_verification`
`string` | The [Address Verification Service (AVS)](https://www.checkout.com/docs/business-operations/prevent-fraud/address-verification-service.md) information, which can be any combination of the following values:

- `address` – The first line of the address.
- `postal_code` – The zip or postal code.
- `address_verification_result` – The outcome of the address verification. This can be one of:
- `no_match`
- `postal_code_match` | | `transit_information`

`object` | Information used to identify transit card transactions. | | `transit_information.transaction_type`

`string` | The type of transit card transaction. | | `transit_information.transportation_mode`

`string` | The type of transit used. | | `point_of_sale_transaction_date`

`string` | The date when the customer performed the transaction at the point of sale (PoS).

Format – YYYY-MM-DD | #### Relayed message example ```json { "id": "msg_aayaps43eoaweagmyhzomsfada", "card_id": "crd_eejbb5ohopoehdd7tevu7bxg3i", "cardholder_id": "crh_urdihafyo75evcr55s62jmwwhy", "transaction_id": "trx_zupv6ou4tyfevapshlrpwd5nb4", "entity":{ "id": "ent_urdihafyo75evcr55s62jmwwhy" }, "client":{ "id": "cli_urdihafyo75evcr55s62jmwwhy" }, "transaction_type": "Purchase", "transaction_amount": 100, "transaction_currency": "GBP", "billing_amount": 90, "billing_currency": "EUR", "billing_conversion_rate": 0.9, "transmission_date_time": "2020-01-01T16:51:47Z", "ecb_conversion_rate": 0.34, "digital_card": { "id": "dcr_urdihafyo75evcr55s62jmwwhy", "device_type": "phone", "wallet_type": "applepay" }, "pos": { "country_code": "GBR", "postal_code": "SE100ER", "card_present": "present", "cardholder_present": "not_present", "entry_mode": "ecommerce" }, "merchant": { "name": "Software Company", "city": "London", "state": "", "country": "GBR", "category_code": "5734", "merchant_id": "031860687", "street_address": "261 Example Street", "payment_facilitator_id": "12345678901", "sub_merchant_id": "987654321", "tax_id": "123456789", "website_url": "https://www.example.com" }, "three_d_secure": { "requested_exemption_or_exclusion": "recurring_payment", "sca_not_required_reason": "recurring_payment" }, "authorization_type": "final_authorization", "address_verification": { "address": "West Street", "postal_code": "90150", "address_verification_result": "no_match" }, "transit_information": { "transaction_type": "authorized_aggregated_split_clearing", "transportation_mode": "urban_bus" }, "point_of_sale_transaction_date": "2023-04-25" } ``` --- ## Respond to authorization requests When you receive an authorization request, you must respond to approve or decline it within the [timeout limit](#Request_timeout_before_decline). If you do not respond within the timeout limit, the authorization is automatically declined. To change this behavior, configure [stand-in mode](#Configure_stand-in_mode) with your own business logic. If the request times out or you receive an error response code from Checkout.com, the authorization is automatically declined. Your response must contain a relevant HTTP response code and response body: | HTTP code | Description | | --- | --- | | `200` | You have all the data you need to provide a decision about the authorization. | | `4XX` | You cannot provide a decision because you do not have the required data from Checkout.com. | | `5XX` | You cannot provide a decision because of an issue at your end. For example, a server error. | ### Approve an authorization To approve an authorization, respond with an HTTP `200 OK` response code and set the `approved` field to `true`. #### Approval example ```json { "approved": true, "address_verification_result" : "PostalCodeAndAddressMatch" } ``` #### Response fields | Field | Description | | --- | --- | | `approved`

`boolean`
`required` | Your decision on the authorization request.
Set to `true`. | | `address_verification_result`

`enum`
`optional` | The result of the Address Verification Service (AVS) check.
Set to one of the following values:

- `AddressMatch`
- `PostalCodeAndAddressMatch`
- `PostalCodeMatch`
- `NoMatch` | | `balance_amount`

`uint64`
`optional` | The available balance on the card, in the [minor currency unit](https://www.checkout.com/docs/payments/accept-payments/format-the-amount-value.md).

This field is required for `balance_inquiry` transactions. For other transaction types, it's optional. | | `balance_currency`

`string`
`optional` | The currency for the available balance on the card.

Format – [ISO 4217 code](https://www.checkout.com/docs/developer-resources/testing/codes/currency-codes.md)

This field is required for `balance_inquiry` transactions. For other transaction types, it's optional. | | `metadata`

`key/value pair`
`optional` | Any additional information. | ### Decline an authorization To decline an authorization, respond with an HTTP `200 OK` response code and set the `approved` field to `false`. #### Decline example ```json { "approved": false, "reason_code": "InsufficientFunds", "address_verification_result" : "NoMatch", "metadata": [{"reference": "xYhUq"}] } ``` #### Response fields | Field | Description | | --- | --- | | `approved`

`boolean`
`required` | Your decision on the authorization request.
Set to `false`. | | `address_verification_result`

`enum`
`optional` | The result of the Address Verification Service (AVS) check.
Set to one of the following values:

- `AddressMatch`
- `PostalCodeAndAddressMatch`
- `PostalCodeMatch`
- `NoMatch` | | `metadata`

`key/value pair`
`optional` | Any additional information. | | `reason_code`

`enum`
`optional` | The reason for declining the transaction. This can be one of:

- `FailedControl`
- `InsufficientFunds`
- `Other`

If you provide an invalid value or no value, Checkout.com returns to the card scheme the default scheme reason code `Do Not Honour (05)`. | --- ## Subscribe to webhooks You can set up webhooks to be notified of authorization decisions made by your server or stand-in mode: 1. [Configure your webhook server](https://www.checkout.com/docs/developer-resources/event-notifications/receive-webhooks/configure-your-webhook-server.md). 2. Subscribe to the following webhooks, which include an `authorization_relay` object: - [Authorization approved](https://www.checkout.com/docs/developer-resources/event-notifications/event-types/authorization_approved.md#Authorization_relay_object) - [Authorization declined](https://www.checkout.com/docs/developer-resources/event-notifications/event-types/authorization_declined.md#Authorization_relay_object) --- ## Update your API key > **Note** > > When you generate a new key, Authorization Relay is disabled. > This ensures that authorizations are not automatically declined while you're implementing new keys. > Until you re-enable the service, Checkout.com decides whether to approve or decline authorizations. 1. Sign in to the [Dashboard](https://dashboard.checkout.com/). 2. Go to _Developers > Authorization relay_, and select _Replace keys_. 3. In the _Generate replacement keys_ popup that opens, select the key you want to replace, and then select _Generate new keys_. 4. Copy the _App ID_ and _Secret API key_ that are generated – ensure they are on your clipboard – and select _Done_.
For security reasons, the secret API key is never shown again. 5. In the _Authorization relay_ page that opens, add the keys to your code. 6. Re-enable Authorization Relay using the toggle.