# Redirect Payment Guide


<b>Documentation version 4.02, 29.09.2026</b>

Here at Inbank we strive to help our partners sell more by simplifying purchases and making financing more accessible to customers. For exactly this reason we offer a number of sales financing solutions. Our most known credit offering is hire-purchase, also known as payment by installments.

There are several methods of how partners can integrate with Inbank, this document covers our <b>e-POS solution</b>. With Inbank e-POS, partners only need to add Inbank as a payment method and redirect clients to our environment, Inbank will take care of all the rest. After a successful financing process we will redirect the customer back to you.

<p align="center">
<img src="/static/redirect-payment/epos-introduction.svg" width="400"/>
</p>

Inbank e-POS is supplemented with Inbank Partner Portal where merchants can see detailed overview of submitted credit applications, create applications for customers and conduct contract withdrawals.

If you would like to make a partial return for a Hire Purchase or a Split into parts contract, please refer to the [Partial Returns Guide](/api/partial-return-flow).

For any questions regarding the e-POS integration process, contact Inbank at:

- <b>Estonia</b>: <a href="mailto:integration@inbank.ee">integration@inbank.ee</a>
- <b>Latvia</b>: <a href="mailto:integration@inbank.lv">integration@inbank.lv</a>
- <b>Poland</b>: <a href="mailto:integration@inbank.pl">integration@inbank.pl</a>
- <b>Czechia</b>: <a href="mailto:integration@inbank.cz">integration@inbank.cz</a>
- <b>Lithuania</b>: <a href="mailto:integration@inbank.lt">integration@inbank.lt</a>

We will be happy to help.

In general, the flow looks like this:

<p>
<img src="/static/redirect-payment/epos-general-flow.svg" style="width: 600px;"/>
</p>

Inbank also sends server-to-server notification messages to ensure delivery of information about the payment session even if the customer does not return to the e-shop.

Inbank will provide you with everything you need to start using our Partner API. This includes the necessary keys, product configuration, etc. 

# Demo Environment

Inbank provides a separate environment for development and integration testing. The demo environment remains available during the later life cycle of our cooperation, after the integration on production environment has been launched. The demo and production environments are different, each having individual data sets.

Note that the access credentials and product codes are different in the production environment. You will be provided production specific information later on.

For testing purposes, the demo environment returns preconfigured decisions:

- Positive decision is given for amounts 0 - 500, 15 000 - 16 000.

The credit application process may include an OTP code exchange via SMS. The demo environments do not send out SMS messages. The SMS message is hardcoded to value 0000.

# Guidelines for Integration Implementation

## API Connectivity

Before you can initiate a session, Partner API connectivity must be configured.

Inbank will provide you an API key, used for authentication, and a unique identifier of your shop, required for building API URLs (for example `POST /shops/yourShopUuid/pos-sessions`). <b>The keys should remain private at all times.</b>

## Authentication

The authentication process consists of the following two steps:

1. Merchant places the API key in the Authorization header of the request.
1. API server verifies the API key authenticity.

## Authorization Header

Authorization header must have the `Bearer` scheme and value of your API key, for example:

`Authorization: Bearer e93174d3b9158a01c861c65fab0e7f96`

In case of unsuccessful authorization, the system will return the following response:

|<b>HTTP code</b>|<b>Description</b>|
| :- | :- |
|401|Unauthorized|

```json
{
    "error": [
        "unauthorized"
    ]
}
```

## Content-Type

The HTTP header Content-Type application/json is expected in all requests, unless otherwise specified in the endpoint description. Example:

```
Content-Type: application/json
```

## URLs

<b>Estonia:</b>

|<b>Environment</b>|<b>API</b>|<b>Partner Portal</b>|
| :- | :- | :- |
|<b>Test</b>|<a href="https://demo-api.inbank.ee/partner/v3/" target="_blank">https://demo-api.inbank.ee/partner/v3/</a>|<a href="https://demo-partner.inbank.ee/" target="_blank">https://demo-partner.inbank.ee/</a>|
|<b>Production</b>|<a href="https://api.inbank.ee/partner/v3/" target="_blank">https://api.inbank.ee/partner/v3/</a>|<a href="https://partner.inbank.ee/" target="_blank">https://partner.inbank.ee/</a>|

<b>Latvia:</b>

|<b>Environment</b>|<b>API</b>|<b>Partner Portal</b>|
| :- | :- | :- |
|<b>Test</b>|<a href="https://demo-api.inbank.lv/partner/v3/" target="_blank">https://demo-api.inbank.lv/partner/v3/</a>|<a href="https://demo-partner.inbank.lv/" target="_blank">https://demo-partner.inbank.lv/</a>|
|<b>Production</b>|<a href="https://api.inbank.lv/partner/v3/" target="_blank">https://api.inbank.lv/partner/v3/</a>|<a href="https://partner.inbank.lv/" target="_blank">https://partner.inbank.lv/</a>|

<b>Poland:</b>

|<b>Environment</b>|<b>API</b>|<b>Partner Portal</b>|
| :- | :- | :- |
|<b>Test</b>|<a href="https://demo-api.inbank.pl/partner/v3/" target="_blank">https://demo-api.inbank.pl/partner/v3/</a>|<a href="https://demo-partner.inbank.pl/" target="_blank">https://demo-partner.inbank.pl/</a>|
|<b>Production</b>|<a href="https://api.inbank.pl/partner/v3/" target="_blank">https://api.inbank.pl/partner/v3/</a>|<a href="https://partner.inbank.pl/" target="_blank">https://partner.inbank.pl/</a>|

<b>Czechia:</b>

|<b>Environment</b>|<b>API</b>|<b>Partner Portal</b>|
| :- | :- | :- |
|<b>Test</b>|<a href="https://demo-api.inbank.cz/partner/v3/" target="_blank">https://demo-api.inbank.cz/partner/v3/</a>|<a href="https://demo-partner.inbank.cz/" target="_blank">https://demo-partner.inbank.cz/</a>|
|<b>Production</b>|<a href="https://api.inbank.cz/partner/v3/" target="_blank">https://api.inbank.cz/partner/v3/</a>|<a href="https://partner.inbank.cz/" target="_blank">https://partner.inbank.cz/</a>|

<b>Lithuania:</b>

|<b>Environment</b>|<b>API</b>|<b>Partner Portal</b>|
| :- | :- | :- |
|<b>Test</b>|<a href="https://demo-api.inbank.lt/partner/v3/" target="_blank">https://demo-api.inbank.lt/partner/v3/</a>|<a href="https://demo-partner.inbank.lt/" target="_blank">https://demo-partner.inbank.lt/</a>|
|<b>Production</b>|<a href="https://api.inbank.lt/partner/v3/" target="_blank">https://api.inbank.lt/partner/v3/</a>|<a href="https://partner.inbank.lt/" target="_blank">https://partner.inbank.lt/</a>|

<span id="statemodel"></span>

# Payment Session State Model

For the easiest integration we have designed the session status model to be similar to other payment channels that the e-shop integrates with.

<br>
<p align="center">
  <img src="/static/epos-payment-session-state-model.svg" style="width: 440px;"/>
</p>
<br>

|<b>Status</b>|<b>Description</b>|
| :- | :- |
|<p>pending</p><p></p>|A session is created;<br>Credit application may be or not be in progress;<br>Positive but not accepted credit decisions also remain in this status until they expire.|
|cancelled |The customer has cancelled the process.|
|<p>granted </p><p></p>|Credit has been granted to the customer, there are no obstacles from the Inbank side for sales completion.<br>The process is now waiting for merchant's approval, if configured so.<br>If the flow is configured not to wait for merchant's approval, this state may be omitted (see note below).|
|<b>completed</b> |This is the target state: credit contract between customer and Inbank has been activated, merchant is liable for the delivery of goods/services.|
|declined|Credit was declined by Inbank.|
|expired|The session was not completed during the defined time period.|

The integration flow can be configured to require a final merchant-side confirmation step, before the credit application process is completed. This is somewhat similar to the credit card flows where the amount is first reserved on the credit card account (transaction is approved), and is later 'captured' after the merchant has completed the transaction.

This may be handy if the stock is limited and the merchant does not allocate stock items before it is ensured that the customer can get the credit. If the merchant does not send the final approval (i.e. items are out of stock, order can not be completed), the granted credit is not completed.

# Credit Contract State Model

Inbank will send callbacks about changes to the credit contract status. Contracts can have the following statuses:

<br>
<p align="center">
  <img src="/static/epos-credit-contract-state-model.svg" style="width: 440px;"/>
</p>
<br>

|<b>Status</b>|<b>Description</b>|
| :- | :- |
|<p>unsigned</p><p></p>|A contract has been created, but has not yet been signed by the customer and/or Inbank.|
|signed|<p>The contract has been signed by both the customer and Inbank.</p><p></p><p>For the flow which includes merchant approval, this state indicates that the credit has been granted by Inbank and the system is now awaiting approval from the partner to activate the contract.</p>|
|<b>activated</b>|This is the target state: credit contract between customer and Inbank has been activated, merchant is liable for the delivery of goods/services.|
|cancelled|<p>The credit contract has been cancelled. This state applies only to contracts which previously were `unsigned` or `signed`.</p><p></p><p>For the flow which includes merchant approval, `signed` contracts get the status `cancelled` when the merchant has not approved the contract.</p>|
|terminated|An existing credit contract has been terminated. This state can only be applied to contracts which previously were `activated`.|

# Callbacks

When initiating a payment session through Inbank Partner API, the e-shop provides three URLs:

- <b>redirectUrl</b> - the URL to which the customer's browser is redirected after completing the credit application flow, regardless of its outcome.
- <b>cancelUrl</b> - the URL to which the customer's browser is redirected if the customer chooses to cancel the flow, or if the credit application or contract is cancelled before the flow is completed.
- <b>callbackUrl</b> - the URL to which Inbank sends server-to-server callback notifications.

Once the financing process is finalized, Inbank sends the final callback through the customer's browser to `redirectUrl` and server-to-server to `callbackUrl`. The browser callback is not guaranteed to arrive if the customer does not press the "<b>back to merchant</b>" button, or if connectivity or technical problems occur on the customer's device or browser. The browser and server-to-server callbacks may arrive in either order.

If the same callback event is delivered more than once, process only the first delivery. Distinct callback events for the same payment session must be processed separately.

The e-shop should process incoming callbacks as follows:

- Validate the callback using the [Callback authenticity validation](#callbackauthenticityvalidation) procedure.
- Identify the POS session using the `uuid` from the callback.
- Inspect the callback status and update the order accordingly. When necessary, retrieve the latest POS session, credit application, or credit contract details and verify the purchase reference.

## Callback Lists

Inbank supports two callback modes for Redirect Payment integrations: `standard` and `extended`. The `extended` callback list is a superset of the standard callback list and includes additional credit application and contract events. The `standard` mode is used by default.

To receive the extended callback list, set `integrationInfo.callbackMode` to `extended` when initiating the payment session with the [POST /pos-sessions](/api/epos-flow/other/postpossessions) request. If `callbackMode` is omitted or set to `standard`, the standard callback list is used.

The additional callback events available only in `extended` mode are sent server-to-server to `callbackUrl`. They are not sent to `redirectUrl`.

Both callback lists use the same callback request and message format.

<br>

<span id="standardcallbacklist"></span>

<b>Standard Callback List</b>

|<span style="display: inline-block; min-width: 140px;"><b>Callback status</b></span>|<b>Description</b>|
| :- | :- |
|cancelled|The customer has cancelled the financing process or the credit contract has been cancelled.|
|declined|The credit application has been declined by Inbank.|
|granted|Financing has been granted and is awaiting merchant approval. Applicable when merchant approval is required.|
|completed|The credit contract has been activated and financing of the purchase is complete.|

<span id="extendedcallbacklist"></span>

<b>Extended Callback List</b>

|<b>Callback status</b>|<b>Description</b>|
| :- | :- |
|positive|The credit application received a positive decision.|
|declined|The credit application received a negative decision.|
|failed|The decision process encountered an error and a decision could not be made. If this status persists, contact Inbank.|
|income_proof_required|Income proof documents are required before a decision can be made.|
|unsigned|A credit contract has been created, but has not yet been signed by the customer and/or Inbank.|
|signed|The credit contract has been signed by the customer and/or Inbank.|
|completed|The credit contract has been activated and financing of the purchase is complete.|
|cancelled|The credit application, credit contract, or POS session has been cancelled.|
|terminated|A previously activated credit contract has been terminated.|
|granted|Financing has been granted and is awaiting merchant approval. Applicable when merchant approval is required.|
|down_payment_paid_by_customer|The customer has successfully paid the required down payment. Applicable when the flow includes a down payment.|

The additional credit application decision statuses `positive`, `failed`, and `income_proof_required` can be verified using [GET /applications](/api/full-api-flow/credit-applications/getapplication) with the `creditApplicationUuid` returned by [GET /pos-sessions](/api/epos-flow/other/getpossession).

The additional credit contract statuses `unsigned`, `signed`, `terminated`, and `down_payment_paid_by_customer` can be verified using [GET /contracts](/api/epos-flow/other/getcontract) with the `creditContractUuid` returned by [GET /pos-sessions](/api/epos-flow/other/getpossession).

These additional callback values describe credit application or contract states. They are not additional POS session statuses returned by `GET /pos-sessions`.

## Request Structure

Both of the callbacks are sent as http POST requests,
("Content-Type" => "application/x-www-form-urlencoded"). The POST form has the following structure:

|<b>Parameter</b>|<b>Example value</b>|<b>Description</b>|
| :- | :- | :- |
|message|%7B%22uuid%22%3A%22e4b5b81a-6d99-4a78-bd17-<br>46d19968eb7f%22%2C%22status%22%3A%22cancelled%22%2C%22<br>purchase_reference%22%3A%22Id+%231%22%7D|URL-encoded JSON structure containing information about the pos_session.<p>For more details, see the [Callback message content](#callbackmessagecontent) chapter.</p>|
|hmac|c196e985640a6291723dc2717d264f82e70126c<br>34b107f3be5b22201cb147c98b9709f5184a7f2fe8268<br>4d6086eee07df8a46c28fc0edfdd14fd306579244664|<p>HMAC value. </p><p>For more details, see HMAC calculation logic described in the [Callback authenticity](#callbackauthenticityvalidation) chapter.</p>|
|timestamp|<p>1549411200</p><p></p>|Current Unix timestamp at issuing server. <br>See <a href="https://en.wikipedia.org/wiki/Unix_time" target="_blank">https://en.wikipedia.org/wiki/Unix_time</a> for more details.|

## Callback Request Example

<b>Request header</b>

```json
{"Content-Type":"application/x-www-form-urlencoded"}
```

<b>Request body</b>

```
message=%7B%22uuid%22%3A%223241a6d5-051b-415b-afc7-0a5aad115fcc%22%2C%22status%22%3A%22cancelled%22%2C%22
purchase_reference%22%3A%221234%22%7D&hmac=4c4686db2aac832dd2e001fdc02e2b4021dc5e49c064552215dab2ca9c564
9435562bc60e96b812ca8ea40223f500ced9c257541b43ab7fb482067c8bae7a963&timestamp=1553072069
```

<span id="callbackmessagecontent"></span>

## Callback Message Content

The message contains minimal information and is meant as a trigger to obtain more detailed information over Partner API. The standard and extended callback lists use the same message fields:

- `uuid` - POS session UUID.
- `status` - status of the callback event. Possible values are listed in the [Standard Callback List](#standardcallbacklist) and [Extended Callback List](#extendedcallbacklist) sections above.
- `purchase_reference` - merchant side reference, i.e. order ID. For more details, see the [Session initiation](/api/epos-flow/other/postpossessions) chapter.

<span id="callbackauthenticityvalidation"></span>

## Callback Authenticity Validation

We use message authenticity hash (HMAC) transported within the POST request form field `hmac`.
To validate the message authenticity you need to calculate the verifying HMAC based on data from the request and your secret `api_key`, and compare the calculated HMAC with the HMAC value passed in the request.

Verifying HMAC is calculated as SHA512 HMAC, over the `timestamp` and `message` from the request, concatenated with `.` delimiter.
Your shop API key is used as HMAC secret.

Pseudocode for example verifying HMAC calculation:

```
key = your_api_key;
req_timestamp = request[timestamp];
req_message = request[message];
req_data = req_timestamp+'.'+req_message;
v_hmac = hmac("sha512", key, req_data);
```
JavaScript example (Postman):

```javascript
key = your_api_key;
req_timestamp = decodeURIComponent(request[timestamp]);
req_message = request[message];
req_data = req_timestamp + '.' + req_message;
v_hmac = CryptoJS.HmacSHA512(req_data, key);
```

PHP example:

```php
$key = $settings->api_key;
$req_timestamp = $_POST['timestamp'];
$req_message = stripslashes($_POST['message']);
$v_hmac = hash_hmac('sha512', $req_timestamp . '.' . $req_message, $key);
```

<span id="apirequests"></span>

# API Requests

This section lists the API request required for the integration with the Inbank e-POS system. The following pages contain charts with demonstration of the request sequence. The enlisted API requests are used in the following way:

1. The shop retrieves a primary credit calculation using the [POST /calculations](/api/epos-flow/other/postcalculation) request. The response includes an approximate monthly payment based on the credit amount and period. The final conditions will be presented in e-POS after the customer submits an application. <br><br>

    <b>Please note:</b>
    Inbank payment methods should be available only for cart values that are within the price range agreed with Inbank. If you would like to receive the price range and other details of your Inbank product over API, please use the [GET /products](/api/additional-api-flow/additional-endpoints/getproducts) endpoint.
    <br>
2. The e-shop initiates a payment session using the [POST /pos-sessions](/api/epos-flow/other/postpossessions) endpoint. The request includes merchant domain name as one of the parameters. The `redirectUrl` from the response indicates the link to which the client is redirected to complete the financing process. <br><br>

3. The e-shop redirects the client to the e-POS environment. In e-POS customers are guided through a number of dialogs to complete the financing of the purchase. After the e-POS dialogs, customers are redirected back to the e-shop. The `returnUrl` is the one the e-shop included in the [POST /pos-sessions](/api/epos-flow/other/postpossessions) request.<br><br>

4. If the flow is configured to request merchant approval before contract activation, the e-shop waits for the callback indicating that the payment session received the status `granted`. At this point, the e-shop retrieves the identifier of the contract using the [GET /pos-sessions](/api/epos-flow/other/getpossession) request. After that, the merchant can either approve the credit contract, using [POST /:contractUuid/merchant-approval](/api/epos-flow/other/postmerchantapproval) request, or cancel it, using the [POST /:contractUuid/cancel](/api/epos-flow/other/cancelcontract). The following step is necessary only if the contract was approved.<br><br>

5. Once the e-shop receives the callback indicating that the payment session received the status completed, the e-shop needs to check the contract status. First, the e-shop retrieves the identifier of the contract using the [GET /pos-sessions](/api/epos-flow/other/getpossession) request. Retrieving the contract identifier again is not required if it was previously done to approve the contract. Then the e-shop checks the status of the credit contract using the [GET /contracts](/api/epos-flow/other/getcontract) request. If the contract received status activated, the financing of the purchase has been successful.

If you would like to make a partial return for a Hire Purchase or a Split into parts contract, please refer to the [Partial Returns Guide](/api/partial-return-flow).

For any questions regarding the integration process, contact Inbank at:

- <b>Estonia</b>: <a href="mailto:integration@inbank.ee">integration@inbank.ee</a>
- <b>Latvia</b>: <a href="mailto:integration@inbank.lv">integration@inbank.lv</a>
- <b>Poland</b>: <a href="mailto:integration@inbank.pl">integration@inbank.pl</a>
- <b>Czechia</b>: <a href="mailto:integration@inbank.cz">integration@inbank.cz</a>
- <b>Lithuania</b>: <a href="mailto:integration@inbank.lt">integration@inbank.lt</a>

## API Request Flow

The chart demonstrates the sequence in which the API requests should be applied to successfully initiate the payment session, redirect the customer to e-POS and later check the credit contract status to confirm that the financing has been successful.

<br>
<p align="center">
<img src="/static/redirect-payment/epos-api-request-flow-v3.svg" style="width: 700px;"/>
</p>
<br>

## API Request Flow with Merchant Approval

The chart below applies to cases when the flow requires merchant approval prior to contract activation. The chart demonstrates the sequence in which the API requests should be applied to successfully initiate the payment session, redirect the customer to e-POS and later check the credit contract status to confirm that the financing has been successful.

<br>
<p align="center">
<img src="/static/redirect-payment/epos-api-request-flow-approval-v3.svg" style="width: 700px;"/>
</p>
<br>

</p>
</p>



## Servers

Demo environment
```
https://demo-api.inbank.ee
```

Live environment
```
https://api.inbank.ee
```

## Security

### bearerAuth

Type: http
Scheme: bearer

## Download OpenAPI description

[Redirect Payment Guide](https://docs.inbank.eu/_bundle/api/epos-flow.yaml)

## Other

### Calculator

 - [POST /partner/v3/shops/{shopUuid}/calculations](https://docs.inbank.eu/api/epos-flow/other/postcalculation.md): POST /partner/v3/shops/:uuid/calculations

To get a credit calculation from Inbank, use the POST /shops/:uuid/calculations request.

Note that this request returns the preliminary non-personalized credit conditions. The final conditions will be presented after the customer submits a credit application and receives a positive decision.

### Session Initiation

 - [POST /partner/v3/shops/{shopUuid}/pos-sessions](https://docs.inbank.eu/api/epos-flow/other/postpossessions.md): POST /partner/v3/shops/:uuid/pos-sessions

To start a payment session in Inbank e-POS, use the POST /shops/:uuid/pos-sessions. The response includes the identifier of the payment session - posSessionUuid and the URL to which the customer is to be redirected - redirectUrl.

\* The customerData, customerContactData and merchant objects and parameters included in them are optional. A request that does not contain these objects will be processed correctly. However, if the body does contain these objects, Inbank will validate the parameters passed inside them. Therefore, if the request contains customerData, customerContactData, merchant objects, their parameters become required.

### Session Details

 - [GET /partner/v3/shops/{shopUuid}/pos-sessions/{posSessionUuid}](https://docs.inbank.eu/api/epos-flow/other/getpossession.md): GET /partner/v3/shops/:shopUuid/pos-sessions/:posSessionUuid

When a user is redirected back to e-shop, or when a callback notification is received, the e-shop should make a GET /shops/:shopUuid/pos-sessions/:posSessionUuid request to inspect session details.
The response contains the creditContractUuid value which is used in the  GET /contracts request to check the status of the contract. If the flow is configured to request merchant approval before credit contract activation, this value is also used in the POST /:contractUuid/merchant-approval or the POST /:contractUuid/cancel request, to either approve or cancel the credit contract.

It is important to inspect the value of the status. If the status is completed, then from the e-shop order perspective it has been paid, and the goods can be shipped.

### Contract Approval

 - [POST /partner/v3/shops/{shopUuid}/contracts/{contractUuid}/merchant-approval](https://docs.inbank.eu/api/epos-flow/other/postmerchantapproval.md): POST /partner/v3/shops/:shopUuid/contracts/:contractUuid/merchant-approval

If the flow is configured to request merchant approval, the e-shop will receive the callback informing that the payment session has received status granted. This means that the credit has been approved by Inbank.

To approve the contract, the e-shop first needs to perform the GET /pos-sessions request, which, among other parameters, returns the creditContractUuid. This identifier can then be used to approve the credit contract.

The request does not require any parameters to be passed in its body.

### Contract Cancellation

 - [POST /partner/v3/shops/{shopUuid}/contracts/{contractUuid}/cancel](https://docs.inbank.eu/api/epos-flow/other/cancelcontract.md): POST /partner/v3/shops/:shopUuid/contracts/:contractUuid/cancel

 If the flow is configured to request merchant approval, the e-shop will receive the callback informing that the payment session has received status granted. This means that the credit has been approved by Inbank.

 To cancel the contract, the e-shop first needs to perform the GET /pos-sessions request, which, among other parameters, returns the creditContractUuid. This identifier can then be used to cancel the credit contract.

 The request does not require any parameters to be passed in its body.

### Contract Details

 - [GET /partner/v3/shops/{shopUuid}/contracts/{contractUuid}](https://docs.inbank.eu/api/epos-flow/other/getcontract.md): GET /partner/v3/shops/:shopUuid/contracts/:contractUuid

Once the credit contract UUID has been retrieved via the GET /pos-sessions request, the e-shop can check the status of the credit contract using the GET /partner/v3/shops/:shopUuid/contracts/:contractUuid request. The response will include the status parameter. If the status is activated, the purchase has been successfully financed by Inbank and the purchase items can be forwarded to the customer.

