openapi: 3.1.0
info:
  title: imoje FRONT API
  version: 1.1.0

  description: |
    # Technical documentation for integration with the imoje payment gateway
    # Introduction

    Instructions for integration using the FRONT API with the imoje payment gateway. The assumption behind this integration is that queries are handled on the user's browser side. If you want to handle communication with imoje on the server side, please refer to our [RESTful API](https://bump.sh/pgw/doc/imoje-api-en/) integration.

    ## Data required for integration

    * `Merchant ID`
    * `Shop ID`
    * `Shop key` 
    * `Authorisation token`

    ## Where to find data for integration

    After logging into the [imoje administration panel](https://imoje.ing.pl), go to the `Shops` tab, select the appropriate shop and go to its `Details`. Then go to the `Data for integration` tab. Here you will find: `Merchant ID`, `Shop ID`, `Shop key` and `Authorisation token`. 

    > [Administration panel](https://sandbox.imoje.ing.pl) for the sandbox test environment

    ## Contact

    Email address: kontakt.tech@imoje.pl  
    Tel: +48 32 319 35 70 

  contact:
    name: Wsparcie techniczne
    email: kontakt.tech@imoje.pl

x-externalLinks:
  - label: imoje
    url: https://www.ing.pl/bramka-platnicza-imoje

servers:
  - url: https://paywall.imoje.pl
    description: Production environment

  - url: https://sandbox.paywall.imoje.pl
    description: Test environment

x-topics:
  - title: Creating a payment
    content: |
      To create a payment in imoje, send a POST or GET request to {[server](#doc-servers)}`/payment` with the following parameters.

      A signature is used to authorise the request, which must also be included in the request. You can find out how to calculate the signature [here](#topic-authorisation).

      ## Request parameters

      | Parameter           | Type         | Required parameter | Description    |
      |---------------------|--------------|--------------------|----------------|
      | `serviceId`         | string(36)   | `YES`              | Customer store ID as `UUID v4` |
      | `merchantId`        | string(20)   | `YES`              | Customer ID |
      | `amount`            | string       | `YES`              | Amount of transaction in pennies |
      | `currency`          | string(3)    | `YES`              | Currency `ISO 4217`|
      | `orderId`           | string(100)  | `YES`              | order ID, <br> **available characters:** A-Za-z0-9#_-./ space (0x20) and the UNICODE characters from the range 00C0 - 02C0 (e.g. Polish diacritic characters) |
      | `customerFirstName` | string(100)  | `YES`              | first name of the person placing the order, <br> **available characters:** A-Za-z0-9-,. space (0x20) and the UNICODE characters from the range 00C0 - 02C0 (e.g. Polish diacritic characters), 0400 - 04FF (Cyrillic script) |
      | `customerLastName`  | string(100)  | `YES`              | surname of the person placing the order, <br> **available characters:** A-Za-z0-9-,. space (0x20) and the UNICODE characters from the range 00C0 - 02C0 (e.g. Polish diacritic characters), 0400 - 04FF (Cyrillic script) |
      | `signature`         | string       | `YES`              | [Calculated signature](#topic-authorisation) |
      | `customerEmail`     | string(200)  | `NO`               | E-mail address in the format compliant with RFC 5322 and RFC 6531 |
      | `customerPhone`     | string(20)   | `NO`               | telephone number of the person placing the order, <br> **available characters:** -+0-9 and space. <br> The value of the parameter can be up to 20 characters |
      | `orderDescription`  | string(255)  | `NO`               | title of transaction, <br> **available characters:** A-Za-z0-9#&_-,.\/ space (0x20) and the UNICODE characters from the range 00C0 - 02C0 (e.g. Polish diacritic characters) |
      | `additionalDescription` | string | `NO` | Details of products or services ordered |
      | `urlSuccess`        | string(300)  | `NO`               | URL the user will be redirected to after a successfully completed transaction. <br> The address must comply with the `RFC 3986` standard and contain a host. <br> The domain name cannot be absolute (FQDN). |
      | `urlFailure`        | string(300)  | `NO`               | URL the user will be redirected to after an incorrectly completed transaction. <br> The address must comply with the `RFC 3986` standard and contain a host. <br> The domain name cannot be absolute (FQDN). |
      | `urlReturn`         | string(300)  | `NO`               | URL the user will be redirected to after the completion of transaction. <br> The address must comply with the `RFC 3986` standard and contain a host. <br> The domain name cannot be absolute (FQDN). |
      | `urlNotification`   | string(300)  | `NO`               | Dynamic notification address, possibility to set a specific address for a single transaction.  |
      | `visibleMethod`     | string       | `NO`               | payment methods to display at payment gateway. <br> **Available values**: <br> `card` <br> `wallet` <br> `pbl` <br> `blik` <br> `imoje_paylater` <br> `wt` <br> `lease`<br> If this field is not inserted or is empty, all payment methods enabled in the store will be displayed. <br> Every payment method must be separated by coma (e.g. *card,pbl*) |
      | `validTo`           | string       | `NO`               | Payment link expiration date as timestamp in seconds. <br> Failure to process the payment by that time will result in its cancellation. <br> If it is not transferred, the payment link is valid until the time set in the "Payment activity:" parameter on the imoje Administration Panel (store settings) or until the expiry of 15 months. <br> Passing the parameter `validTo` =` NULL` causes that the payment link will not expire without the settings in the parameter "Payment activity:" on the imoje Administration Panel (store settings). <br> **Minimum** validity time is **60 seconds.** |
      | `preselectMethodCode`| string(20)  | `NO`              | Payment channel set as default and automatically selected when the payment gateway is opened. <br> If this field is not present, the gateway opens without the selected payment channel selected. <br> The field cannot be defined and left without a value. |
      | `billing`           | string       | `NO`             | Billing details - see the table below |
      | `shipping`          | string       | `NO`             | Delivery data - see the table below |
      | `isKsef`            | string       | `NO`             | Generate KSeF payment identifier (IPKSeF). <br> **Available characters:** `1` - yes, `0` - no | 

      **Parameters for the `billing` array:** 

      | Parameter           | Type        | Required parameter | Description      |
      |---------------------|-------------|-------------------|-------------------|
      | `firstName`         | string(100) | `YES`             | First name of the customer, <br> **available characters:** A-Za-z0-9#&_-"',.\/ space (0x20) and the UNICODE characters from the range 00C0 - 02C0 (e.g. Polish diacritic characters), 0400 - 04FF (Cyrillic script) |
      | `lastName`          | string(100) | `YES`             | Last name of the customer, <br> **available characters:** A-Za-z0-9#&_-"',.\/ space (0x20) and the UNICODE characters from the range 00C0 - 02C0 (e.g. Polish diacritic characters), 0400 - 04FF (Cyrillic script) |
      | `company`           | string(200) | `NO`              | Company name, <br> **available characters:** A-Za-z0-9 and space (0x20)     |
      | `street`            | string(200) | `NO`              | Street, <br> **available characters:** A-Za-z0-9 and space (0x20)           |
      | `city`              | string(100) | `NO`              | City, <br> **available characters:** A-Za-z0-9 and space (0x20)             |
      | `region`            | string(100) | `NO`              | State, <br> **available characters:** A-Za-z0-9 and space (0x20)            |
      | `postalCode`        | string(30)  | `NO`              | Postal code      |
      | `countryCodeAlpha2` | string(20)  | `NO`              | `Alpha2` country code |
      | `taxId`             | string(12)  | `NO`              | Tax number |

      **Parameters for the `shipping` array:** 

      | Parameter           | Type        | Required parameter | Description      |
      |---------------------|-------------|-------------------|-------------------|
      | `firstName`         | string(100) | `YES`             | First name of the customer, <br> **available characters:** A-Za-z0-9#&_-"',.\/ space (0x20) and the UNICODE characters from the range 00C0 - 02C0 (e.g. Polish diacritic characters), 0400 - 04FF (Cyrillic script) |
      | `lastName`          | string(100) | `YES`             | Last name of the customer, <br> **available characters:** A-Za-z0-9#&_-"',.\/ space (0x20) and the UNICODE characters from the range 00C0 - 02C0 (e.g. Polish diacritic characters), 0400 - 04FF (Cyrillic script) |
      | `company`           | string(200) | `NO`              | Company name, <br> **available characters:** A-Za-z0-9 and space (0x20)     |
      | `street`            | string(200) | `NO`              | Street, <br> **available characters:** A-Za-z0-9 and space (0x20)           |
      | `city`              | string(100) | `NO`              | City, <br> **available characters:** A-Za-z0-9 and space (0x20)             |
      | `region`            | string(100) | `NO`              | State, <br> **available characters:** A-Za-z0-9 and space (0x20)           |
      | `postalCode`        | string(30)  | `NO`              | Postal code      |
      | `countryCodeAlpha2` | string(2)   | `NO`              | `Alpha2` country code |

      ## Example request as an HTML form

      ```html
      <input type="hidden" value="63f574ed-d90d-4abe-9cs1-39117584a7b7" name="serviceId">
      <input type="hidden" value="6yt3gjtm9p1odfgx8491" name="merchantId">
      <input type="hidden" value="100" name="amount">
      <input type="hidden" value="PLN" name="currency">
      <input type="hidden" value="yourOrderId" name="orderId">
      <input type="hidden" value="yourDescription" name="orderDescription">
      <input type="hidden" value="John" name="customerFirstName">
      <input type="hidden" value="Doe" name="customerLastName">
      <input type="hidden" value="johndoe@domain.com" name="customerEmail">
      <input type="hidden" value="https://your-shop.com/success" name="urlSuccess">
      <input type="hidden" value="https://your-shop.com/failure" name="urlFailure">
      <input type="hidden" value="https://your-shop.com/return" name="urlReturn">
      <input type="hidden" value="cd5024f5ce5e6ff47990fe60572758fbcbcd6e3c04895d6815932b2d14e04ffd;sha256" name="signature">
      ```
      > info
      >**Each unpaid link will automatically expire 15 months after its creation date. If you want it to expire sooner, use the `validTo` parameter.**

  - title: Authorisation
    content: |
      In order to authorise payments you need signature, which is calculated as follows:

      1. Sort alphabetically, in ascending order, by order parameters.
      2. Combine the parameters as follows: `parameter1=value1&parameter2=value2...parameterN=valueN`. Save the result to a variable (hereinafter referred to as `body`).
      3. Calculate the signature using the `sha224`, `sha256`, `sha384` or `sha512` hashing method, e.g. `sha256(body + serviceKey`. Save the hashing result to a variable (hereinafter referred to as `signature`).
      4. Add the hashing method used after a semicolon to the calculated signature: `signature + “;sha256”`.

      ## Example of signature calculation

      ```php
      /**
      * @param array  $orderData
      * @param string $serviceKey
      * @param string $hashMethod
      *
      * @return string
      */
      function createSignature($orderData, $serviceKey, $hashMethod)
      {
          $data = prepareData($orderData);

          return hash($hashMethod, $data . $serviceKey);
      }

      /**
      * @param array  $data
      * @param string $prefix
      *
      * @return string
      */
      function prepareData(
          $data,
          $prefix = ''
      ) {
          ksort($data);
          $hashData = [];
          foreach($data as $key => $value) {
            if($prefix) {
              $key = $prefix . '[' . $key . ']';
            }
            if(is_array($value)) {
              $hashData[] = prepareData($value, $key);
            } else {
              $hashData[] = $key . '=' . $value;
            }
          }

          return implode('&', $hashData);
      }

      $hashMethod = 'sha256';

      $serviceKey = 'eAyhFLuHgwl5hu-32GM8QVlCVMWRU0dGjH1c';

      $fields = [
      'merchantId' => '6yt3gjtm9p1odfgx8491',
        'serviceId' => '63f574ed-d90d-4abe-9cs1-39117584a7b',
        'amount' => '300',
        'currency' => 'PLN',
        'orderId' => '123',
        'orderDescription' => 'Example transaction',
        'customerFirstName' => 'John',
        'customerLastName' => 'Doe',
        'customerEmail' => 'johndoe@domain.com',
        'customerPhone' => '501501501',
        'urlSuccess' => 'https://your-shop.com/success',
        'urlFailure' => 'https://your-shop.com/failure',
        'urlReturn' => 'https://your-shop.com/return',
      ];
      $result = createSignature($fields, $serviceKey, $hashMethod) . ';' . $hashMethod;
      ```

  - title: Language on the payment gateway
    content: |
      By default, the imoje payment gateway detects the language based on your browser settings. This behaviour is only possible with the basic request address: 
      
      ```
      https://paywall.imoje.pl/payment
      ```

      To force the imoje payment gateway to be displayed in a specific language, modify the base address by adding a value corresponding to the language in question.: 

      ```
      https://paywall.imoje.pl/[lang]/payment
      ```
      where:

      | Parameter   | Type        | Description            |
      |-------------|-------------|------------------------|
      | `lang`    | string(2)   | Location of the payer, determines the communication language of the Payment Gateway to the Payer - Paywall, E-mails and Statuses. <br> **Available values**: `pl`, `en`, `cs`, `de`, `es`, `fr`, `it`, `lt`, `ru`, `sk`, `sl`, `uk`, `nl`, `hu`, `ro`  |

      # Example

      ```
      https://paywall.imoje.pl/en/payment
      ```
  
  - title: Displaying selected payment methods on the payment gateway
    content: |
      In imoje, it is possible to display only selected payment methods to the payer. To the standard request creating a transaction from the [Create payment](#topic-create-payment) point, add the `visibleMethod` parameter with at least one of the following values:

      | Name | Parameter value | Description |
      |----------|-------------|------------------------|
      | Payment cards | `card` | Card payment: `Visa`, `MasterCard`|
      | Electronic wallets | `wallet`     | Electronic wallet payment:  `Apple Pay`, `Google Pay`, `Visa Mobile`, `PayPal`|
      | Online transfer | `pbl` | Online transfer payment|
      | BLIK | `blik` | BLIK payment|
      | Deferred payments | `imoje_paylater` | imoje pay later payments: `Twisto`, `PayPo`, `PragmaGO`, `Blik pay later`|
      | Leasing online | `lease` | Payment ING Lease Now|
      | Traditional transfer | `wt` | Payment by traditional transfer|
      | imoje installments | `imoje_installments` | Payment in installments |

      > info
      > **Important!** For `PayPal` payments to function correctly, do not delete URLs in webhooks. If you change your integration keys in PayPal, you must also update them in the imoje administration panel.

  - title: Notifications
    content: |
      For the correct configuration of notification sending, enter the appropriate notification URL in the imoje administration panel. 

      To add an address, log in to the imoje panel, go to the `Shops` tab, select the shop where the integration is performed, and click on `Details`. Then go to the `Integration data` section and edit the `Notification address` field.

      > info
      > Notifications are sent from IP addresses in the following ranges:
      **5.196.116.32/28**,
      **51.195.95.0/28**,
      **54.37.185.64/28**,
      **54.37.185.80/28**,
      **147.135.151.16/28**

      > info
      > Notifications are sent to the default HTTP (80) and HTTPS (443) ports.

      When the transaction status changes, imoje servers send notifications to the URL specified in the administration panel.
      The merchant's server (e.g. shop) is required to respond with status `200 OK` with body `{'status':'ok'}`, which will indicate that the notification has been correctly received and processed by the merchant's server.
      Notifications are sent in the following cycle:

      * 3 times every 10 seconds, then
      * 5 times every 5 minutes, then
      * 5 times every 60 minutes, then
      * 5 times every 360 minutes, then
      * 5 times every 720 minutes.

      > info
      > If the merchant's server returns a 200 OK status, or the notification is not received by the end of the entire cycle, imoje servers will stop resending the notification.

      If **two identical notifications** are received from imoje servers, the first one should be handled in accordance with the section [notification signature verification method](#topic-notifications#topic-notification-signature-verification-method), while the second one (duplicate) should be **ignored**.

      The notification may consist of the following objects:

      - `transaction` - contains information about the transaction if it was created after the payer selected the payment method
      - `payment` - contains information about the payment link created
      - `action` - contains information about the data used to redirect to the external bank website
      - `paymentProfile` - contains information about the created Oneclick/Recurring card profile

      > info
      > The `payment` object will be the only object sent when the payment link expires or is manually cancelled.

      ## Notification parameters

      #### Parameters for the `transaction` object:

      | Parameter               | Type         | Description                                                 |
      |------------------------|-------------|-------------------------------------------------------|
      | `id`                   | string(36)  | Transaction identifier `UUID v4`                              |
      | `type`                 | string      | Type of transaction, **allowed values**: `sale`, `refund`                                        |
      | `status`               | string      | Transaction status, **allowed values**: `new`, `pending`, `settled`, `cancelled`, `rejected`                                     |
      | `source`               | string      | Transaction source, **allowed values**: `api`, `web`                                     |
      | `created`              | integer(10) | Transaction creation date                            |
      | `modified`             | integer(10) | Transaction modification date                           |
      | `notificationUrl`      | varchar(300)| Notification address                                     |
      | `serviceId`            | string(36)  | Service identifier `UUID v4`                                 |
      | `amount`               | integer(9)  | Transaction amount, **maximum value**: 999999999                                     |
      | `currency`             | string(3)   | Transaction currency in `ISO 4217`                                     |
      | `title`                | string(255) | Order title, **allowed characters**: A-Za-z0-9#&_-"',./ and space character(0x20) and characters in the UNICODE range 00C0 - 02C0 (including Polish diacritics)                                     |
      | `orderId`              | string(100) | Order number, **allowed characters**: A-Za-z0-9#_-./ and space character(0x20) and characters from the UNICODE range 00C0 - 02C0 (including Polish diacritics)                                      |
      | `paymentMethod`        | string      | Order fulfilment method                         |
      | `paymentMethodCode`    | string      | Indication of payment channel                        |
      | `statusCode`           | string(24)  | Card transaction status code             |
      | `statusCodeDescription`| string(113) | Card transaction status code description       |

      <br>
      #### Parameters for the `payment` object:

      | Parameter               | Type         | Description                                                  |
      |------------------------|-------------|-------------------------------------------------------|
      | `id`                   | string(36)  | Order identifier `UUID v4`                             |
      | `title`                | string(255) | Order title, **allowed characters**: A-Za-z0-9#&_-"',./ and space character(0x20) and characters in the UNICODE range 00C0 - 02C0 (including Polish diacritics)                                      |
      | `amount`               | integer(9)  | Order amount, **maximum value**: 999999999                                      |
      | `status`               | string      | Order status, **allowed values**: `new`, `pending`, `settled`, `cancelled`, `rejected`                                    |
      | `created`              | integer(10) | Order creation date                            |
      | `orderId`              | string(100) | Order number, **allowed characters**: A-Za-z0-9#_-./ and space character(0x20) and characters from the UNICODE range 00C0 - 02C0 (including Polish diacritics)                                      |
      | `currency`             | string(3)   | Order currency in `ISO 4217`                                    |
      | `modified`             | integer(10) | Order modification date                          |
      | `serviceId`            | string(36)  | Service identifier `UUID v4`                                 |
      | `notificationUrl`      | varchar(300)| Notification address                                     |
      | `ipksef`               | string      | KSeF payment identifier                               |

      <br>
      #### Parameters for the `action` object:

      | Parameter               | Type         | Description                                                  |
      |------------------------|-------------|-------------------------------------------------------|
      | `type`                 | string      | Redirection type, **allowed values**: `redirect`, `transfer`                                    |
      | `url`                  | string(2083)| Redirection address                                  |
      | `method`               | string      | Redirection method, **allowed values**: `POST`, `GET`                                 |
      | `contentType`          | varchar(100)| Data format type                                    |
      | `contentBodyRaw`       | text        | Redirection parameters                              |
      | `ban`                  | string(26)  | Bank account number, **returned for Wire Transfer payment method** |

      <br>
      #### Parameters for the `paymentProfile` object:

      | Parameter              | Type        | Description                                                 |
      |------------------------|-------------|-------------------------------------------------------|
      | `id`                   | string(36)  | Profile identifier as `UUID v4`                            |
      | `merchantMid`          | string(20)  | Merchant identifier                                |
      | `merchantCustomerId`   | string(36)  | Customer identifier, **allowed values**: A-Za-z0-9 and dash (0x2D)                                |
      | `firstName`            | string(100) | Customer first name, **allowed values**: A-Za-z0-9#&_-"',./ and space character(0x20) and characters in the UNICODE range 00C0 - 02C0 (including Polish diacritics)     |
      | `lastName`             | string(100) | Customer last name, **allowed values**: A-Za-z0-9#&_-"',./ and space character(0x20) and characters in the UNICODE range 00C0 - 02C0 (including Polish diacritics) |
      | `maskedNumber`         | string(16)  | Masked customer card number                      |
      | `month`                | string(2)   | Card validity - month                      |
      | `year`                 | string(4)   | Card validity - year                           |
      | `organization`         | varchar(30) | Customer card organization                            |
      | `isActive`             | integer(1)  | Oneclick/Recurring profile activity, **allowed values**: `1` (active), `0` (inactive)                  |
      | `profile`              | string      | Customer profile type, **allowed values**: `oneclick`, `recurring`                                  |
      | `statusCode`           | string(24)  | Oneclick/Recurring transaction status code           |
      | `statusCodeDescription`| string(113) | Oneclick/Recurring transaction status code description       |

      ## Example content of the notification BODY

      ```json
      {
          "transaction": {
              "id": "07938437-cae3-4d46-877d-e1b9d6e6c58f",
              "type": "sale",
              "status": "pending",
              "source": "api",
              "created": 1666339083,
              "modified": 1666339083,
              "notificationUrl": "https://yourshopdomain.com/notification",
              "serviceId": "a33f331b-23fc-42b0-9fd1-67f310028b46",
              "amount": 1000,
              "currency": "PLN",
              "title": "yourTitle",
              "orderId": "yourOrderId",
              "paymentMethod": "pbl",
              "paymentMethodCode": "ipko"
          },
          "payment": {
              "id": "07980a69-a884-46f7-ad16-216c88a13b98",
              "title": "yourTitle",
              "amount": 100,
              "status": "pending",
              "created": 1666339083,
              "orderId": "yourOrderId",
              "currency": "PLN",
              "modified": 1666339083,
              "serviceId": "a33f331b-23fc-42b0-9fd1-67f310028b46",
              "notificationUrl": "https://yourshopdomain.com/notification"
          },
          "action": {
              "type": "redirect",
              "url": "https://paywall.imoje.pl/07980a69-a884-46f7-ad16-216c88a13b98",
              "method": "GET",
              "contentType": "",
              "contentBodyRaw": ""
          }
      }
      ``` 

      ## Notification header content

      Additionally, the following parameters are included in HTTP headers:

      ```json
      Accept: "text/plain",
      User-Agent: "imoje",
      Content-Type: "application/json; charset=UTF-8",
      X-Imoje-Signature: "merchantid={merchantid};serviceid={serviceid};signature={signature};alg={alg}"
      ```

      where:
      * `merchantid` - customer ID
      * `serviceid` - shop ID
      * `signature` - notification signature
      * `alg` - hash function algorithm, **acceptable values**: `sha224`, `sha256`, `sha384`, `sha512`

      #### Example of an X-Imoje-Signature header

      ```json
      X-Imoje-Signature: "merchantid=6yt3gjtm9p7b8h9xsdqz;serviceid=63f574ed-d4ad-407e-9981-39ed7584a7b7;signature=20cdc8646eb268ea754842bdf0db1df21a2cf0b1c6e3e16e74ef7f7cca8f5450;alg=sha256"
      ```

      ## Notification signature verification method

      Verification of the notification signature is a critical element of authenticating the information sent in the notification package.

      The header containing the notification signature has the following form:

      ```
      X-Imoje-Signature: merchantid=[...];serviceid=[...];signature=[...];alg=[...]
      ```

      To authenticate the origin and verify the integrity of the notification message, perform the following steps:

      1. From the headers of the incoming package to the notification address, retrieve the content of `X-IMoje-Signature`.
      2. Then retrieve the values of the `signature` and `alg` parameters.
      3. Depending on the hash function algorithm specified in the `alg` parameter, calculate the appropriate hash function:

          ```
          string incoming_signature = x_imoje_signature[signature]
          string body = notification_body
          string own_signature = hash(body + service_key, alg)
          ``` 

      4. The calculated value of `own_signature` should be compared with the value of `incoming_signature`, which was retrieved from the header.
      5. If the values of `own_signature` and `incoming_signature` are identical, it means that the notification message is valid and comes from a trusted source.
    
      > info
      > Transaction statuses should only be changed once the signature has been successfully verified.

      ### Example of notification signature verification

      1. The header contains the imoje signature:

          ```
          X-Imoje-Signature: merchantid=mdy7zxvxudgarxbsou9n;serviceid=a33f331b-23fc-42b0-9fd1-67f310028b46;signature=b73321c9e8bcc414b8c08198db4084dafb1b4dc252f512ffe71b1fbce857fd23;alg=sha256
          ```

      2. In the notification package, you receive `JSON`:

      ```json
      {
          "transaction": {
              "id": "07938437-cae3-4d46-877d-e1b9d6e6c58f",
              "type": "sale",
              "status": "pending",
              "source": "api",
              "created": 1666339083,
              "modified": 1666339083,
              "notificationUrl": "https://yourshopdomain.com/notification",
              "serviceId": "a33f331b-23fc-42b0-9fd1-67f310028b46",
              "amount": 100,
              "currency": "PLN",
              "title": "yourTitle",
              "orderId": "yourOrderId",
              "paymentMethod": "pbl",
              "paymentMethodCode": "ipko"
          },
          "payment": {
              "id": "07980a69-a884-46f7-ad16-216c88a13b98",
              "title": "yourTitle",
              "amount": 100,
              "status": "pending",
              "created": 1666339083,
              "orderId": "yourOrderId",
              "currency": "PLN",
              "modified": 1666339083,
              "serviceId": "a33f331b-23fc-42b0-9fd1-67f310028b46",
              "notificationUrl": "https://yourshopdomain.com/notification"
          },
          "action": {
              "type": "redirect",
              "url": "https://paywall.imoje.pl/07980a69-a884-46f7-ad16-216c88a13b98",
              "method": "GET",
              "contentType": "",
              "contentBodyRaw": ""
          }
      }
      ```

      1. Calculate the signature:

          `service_key`:PIcMy86ssE5wuNHAuQn5zPKf6hCAwX3Oxvjw

          `own_signature = sha256(body + service_key)`

          `own_signature`:b73321c9e8bcc414b8c08198db4084dafb1b4dc252f512ffe71b1fbce857fd23

      2. Compare the calculated signature with the one received in the notification header:

      ```javascript
      const crypto = require('crypto')
      let body = "{...}";
      let headerSignature = "b73321c9e8bcc414b8c08198db4084dafb1b4dc252f512ffe71b1fbce857fd23";
      let serviceKey = "PIcMy86ssE5wuNHAuQn5zPKf6hCAwX3Oxvjw";
      let mySignature = crypto.createHash("sha256").update(body + serviceKey).digest("hex");
      if (mySignature === headerSignature) {
          // Notification verified correctly. Continue processing.
      } else {
          // Notification verified as negative. Ignore notification.
      }
      ```

      ## Notifications for reports

      For scheduled reports, it is possible to receive notifications about the availability of the finished report.

      To do this, after logging in to the [imoje administration panel](https://imoje.ing.pl), go to the `Reports` tab, and then in the `Scheduled reports` section, select the `Add report` option. In addition to filling in the desired parameters in the form, you must also enter the `Notification address`, which will receive notifications about the availability of the report.

      Notifications for reports are sent as a `JSON` object using the `POST` method and have the following form:

      ```
      {
          "id": "57526046-db6a-45f9-8288-284337129a8f",
          "status": "generated",
          "fileExt": "owi1",
          "created": 1540382655,
          "modified": 1705398343,
          "url": "https://imoje.ing.pl/351e2776166edaf0e867e3231e518111b17580baa650c90764e671de57465e08c90ef7751600ef7107cdf7628ffced66bd85360776bf0b713881cbc9b9230c83"
      }
      ```
      > info
      > IMPORTANT! Notifications for reports do not contain signatures.

      The notification may consist of the following parameters:

      | Parameter   | Type           | Description                                                             |
      |------------|--------------|------------------------------------------------------------------|
      | `id`       | string(36)   | Report identifier `UUIDv4`                                   |
      | `status`   | string       | Report status, **acceptable values**: `generated`           |
      | `fileExt`  | string(5)    | Report format, **acceptable values**: `csv`, `owi1`, `mt940`|
      | `created`  | integer(10)  | Date of report creation                                          |
      | `modified` | integer(10)  | Report modification date                                         |
      | `url`      | string(2083) | Redirect address                                             |

      ## Refund notifications

      By default, we do not send return notifications.

      However, if you would like to receive them, please contact us at kontakt.tech@imoje.pl. In your email, please include the ID of the shop for which you would like to enable return notifications.

  - title: Refunds
    content: |
      Refunds can only be made via HTTP requests within our RESTful API integration. A detailed description of how to make a refund can be found [here](https://bump.sh/pgw/doc/imoje-api-en/group/endpoint-refund).

      When performing multiple refund transactions simultaneously, please allow **at least a 5-second delay** between transactions.

      > For security reasons, refunds can be made:
      > - for BLIK, up to a maximum of 12 months
      > - for imoje pay later, up to a maximum of 12 months
      > - for payment cards, up to 3 years

  - title: imoje pay later
    content: |
      imoje pay later payments do not require separate integration.
      To start an imoje pay later payment, create a standard payment according to the section [Creating a payment](#topic-creating-a-payment).

      Using the additional parameter `visibleMethod` with the value `imoje_paylater` will display only imoje pay later on the gateway. This allows you to separate this method as a separate item on the summary.

  - title: Widget for card payments
    content: |
      The widget integration method allows you to integrate card payments from within your shop. In this case, no redirection to the payment gateway is required. 
      
      The widget supports eCom 3DSecure payments, OneClick payments, and recurring payments.
      
      To use this method, you need to embed the appropriate JavaScript script.

      Production environment:

      ```
      https://paywall.imoje.pl/js/widget.min.js
      ```

      Test environment: 
  
      ```
      https://sandbox.paywall.imoje.pl/js/widget.min.js
      ```

      ## Parameters

      | Parameter            | Required parameter | Description           |
      |---------------------|-------------------|----------------|
      | `data-merchant-id`  | `YES`             | Merchant ID |
      | `data-service-id`   | `YES`             | Shop ID |
      | `data-amount`       | `YES`             | transaction amount given in pence |
      | `data-currency`     | `YES`             | currency |
      | `data-order-id`     | `YES`             | Order ID, **acceptable characters**: A-Za-z0-9#_-./ and the space character (0x20) and characters from the UNICODE range 00C0 - 02C0 (including Polish diacritical marks) |
      | `data-customer-id`  | `YES`             | Payer ID, **acceptable characters**: A-Za-z0-9_- |
      | `data-customer-first-name` | `YES`             | name of the person placing the order, **acceptable characters**: A-Za-z0-9-,. and space character (0x20) and characters from the UNICODE range 00C0 - 02C0 (including Polish diacritical marks), 0400 - 04FF (Cyrillic) |
      | `data-customer-last-name`  | `YES`             | name of the person placing the order, **acceptable characters**: A-Za-z0-9-,. and space character (0x20) and characters from the UNICODE range 00C0 - 02C0 (including Polish diacritical marks), 0400 - 04FF (Cyrillic) |
      | `data-customer-email`      | `YES`             | e-mail address in a format compliant with RFC 5322 and RFC 6531 standards |
      | `data-signature`           | `YES`             | calculated signature |
      | `data-customer-phone`      | `NO`             | telephone number of the person placing the order, **acceptable characters**: -+0-9 and space. The parameter value may contain **up to 20 characters**. |
      | `data-order-description`   | `NO`             | transaction title, **permitted characters**: A-Za-z0-9#&_-,.\/ and space character (0x20) and characters from the UNICODE range 00C0 - 02C0 (including Polish diacritical marks) |
      | `data-url-success`         | `NO`             | The URL to which the user will be redirected after a successful transaction.<br> The address must comply with the `RFC 3986` standard and contain a host. <br> The domain name cannot be absolute (FQDN). |
      | `data-url-failure`         | `NO`             | URL address to which the user will be redirected after an incorrect transaction.<br> The address must comply with the `RFC 3986` standard and contain a host. <br> The domain name cannot be absolute (FQDN). |
      | `data-url-return`          | `NO`             | The general URL to which the user will be redirected after completing the transaction. <br> The address must comply with the `RFC 3986` standard and contain a host. <br> The domain name cannot be absolute (FQDN). |
      | `data-url-cancel`          | `NO`             | The URL to which the user will be redirected after pressing the `Cancel` button. <br> The address must comply with the `RFC 3986` standard and contain a host. <br> The domain name cannot be absolute (FQDN). |
      | `data-widget-type`         | `NO`             | payment type designation **Acceptable values**: `oneclick`, `recurring`, `ecom3ds` |
      | `data-valid-to`            | `NO`             | expiry date of the payment link as a timestamp in seconds; if not provided, the link is always valid |
      | `data-invoice`             | `NO`             | encoded invoice data, necessary when using the **ING Księgowość** service. The data should be encoded in accordance with the instructions described **[here](#ing-ksiegowosc#preparing-the-invoice-object)**.|
      | `data-multipayout`         | `NO`             | data specifying the payment recipient for **multipayout functions**, where: <br> * `ban` - bank account number <br> * `amount` - transaction amount specified in pence <br> * `label` - recipient name (max. 35 characters), **permitted characters**: A-Za-z0-9-,. and space character (0x20) and characters from the UNICODE range 00C0 - 02C0 (including Polish diacritical marks) <br> * `title` - transfer title (max 105 characters), **acceptable characters**: A-Za-z0-9#&_-,.\/ and space character (0x20) and characters from the UNICODE range 00C0 - 02C0 (including Polish diacritical marks), optional parameter. Its presence causes the transaction to be separated in the recipient's account. <br> Specifying a parameter for one element requires it to be provided for the others. |
         
      ### The example structure of the `data-multipayout` parameter should look as follows:

      ```javascript
      data-multipayout=[{"ban":"39109024028943913168514519","label":"Test1","amount":100},{"ban":"72105000028166973380325415","label":"Test2","amount":100}]
      ```

      ## Configuration parameters - **should not be included when calculating the signature**

      | Parameter            | Required parameter | Description   |
      |----------------------|-------------------|----------------|
      | `data-locale`        | `NO`             | Two-letter language code. <br> **Acceptable values**: `pl`, `en`, `cs`, `de`, `es`, `fr`, `it`, `lt`, `ru`, `sk`, `sl`, `uk`, `nl`, `hu`, `ro`, `bg`, `sv`. <br> Default is `pl`; if an unknown value is passed, `en` will be displayed. |
      | `data-inline`        | `NO`             | If set to `true`, it is possible for the iframe to be embedded in an element with the identifier `imoje-widget__wrapper` (an element with this identifier must exist). <br> If this parameter is not present or is set to `false`, the iframe will be displayed full screen. |
      | `data-element-id`    | `NO`             | indication of the identifier of the element that is to be interactive with the widget; the default value is `false` |
      | `data-element-event` | `NO`             | specifies which event should initiate interaction with the widget; the default is `click` |

      ## Example

      ```
      <script
          src="https://paywall.imoje.pl/js/widget.min.js"
          id="imoje-widget__script"

          data-merchant-id="6yt3gjtm9p1odfgx8491"
          data-service-id="63f574ed-d90d-4abe-9cs1-39117584a7b"
          data-amount="200"
          data-currency="PLN"
          data-order-id="123"
          data-customer-id="123"
          data-customer-first-name="John"
          data-customer-last-name="Doe"
          data-customer-email="johndoe@domain.com"
          data-signature="5d8b909fd777f1e2a4bbf9af8a9dca248c4fe9b14ae70610d051e29358cb62b1;sha256">
      </script>
      ```

      where:

      * `src` - URL address for the `widget.min.js` script
      * `id` - Script ID. Must always have the value `imoje-widget__script`.

      > info
      > The above parameters `src` and `id` should **not be taken into account** when calculating the signature.

      ## Calculating the signature

      The names of the parameters for calculating the signature should be replaced as shown in the example:

      * parameter `data-order-id` to `orderId`.

      The signature should be calculated in the same way as described in the section [Authorisation](#topic-authorisation).

  - title: OneClick and recurring card payments
    content: |
      The FRONT API integration only allows you to create a card profile using the [widget](#topic-widget-for-card-payments).

      To charge or deactivate a profile, you need to use the [RESTful API](https://bump.sh/pgw/doc/imoje-api-en) integration.

      A description of all profile actions can be found [here](https://bump.sh/pgw/doc/imoje-api-en/group/endpoint-profile).

  - title: imoje installments
    content: |
      With this payment method, the payer can spread the order amount over instalments. 

      > info
      > **IMPORTANT!** imoje instalments are only available to individual customers of your shop.

      There are two instalment options available:

      - up to 60 instalments, variable APR, depending on the number of instalments
      - up to 10 instalments, 0% APR

      The minimum amount required to use imoje instalments is **PLN 300**, and the maximum is **PLN 50,000**. 

      imoje instalments will be displayed by default along with other payment methods. If you use the `visibleMethod` table, you must add the value `imoje_installments`.

      ## Creating a payment with imoje instalments

      imoje instalments will be displayed by default along with other payment methods. If you are using the `visibleMethod` array, you must add the value `imoje_installments`.

      ## Example request:

      ```json
      <input type="hidden" value="63f574ed-d90d-4abe-9cs1-39117584a7b7" name="serviceId">
      <input type="hidden" value="6yt3gjtm9p1odfgx8491" name="merchantId">
      <input type="hidden" value="5000000" name="amount">
      <input type="hidden" value="PLN" name="currency">
      <input type="hidden" value="imoje raty" name="orderId">
      <input type="hidden" value="imoje raty" name="orderDescription">
      <input type="hidden" value="John" name="customerFirstName">
      <input type="hidden" value="Doe" name="customerLastName">
      <input type="hidden" value="johndoe@domain.com" name="customerEmail">
      <input type="hidden" value="501501501" name="customerPhone">
      <input type="hidden" value="https://your-shop.com/success" name="urlSuccess">
      <input type="hidden" value="https://your-shop.com/failure" name="urlFailure">
      <input type="hidden" value="https://your-shop.com/return" name="urlReturn">
      <input type="hidden" value="imoje_installments" name="visibleMethod">
      <input type="hidden" value="cd5024f5ce5e6ff47990fe60572758fbcbcd6e3c04895d6815932b2d14e04ffd;sha256" name="signature">
      ```

      ## imoje instalment calculator - widget

      The imoje instalment widget allows you to display an instalment calculator on the shop summary, which the payer can use to preliminarily determine the amount of instalments for a selected period. 
      The preliminary instalment amount can be downloaded from the calculator and then transferred in the [transaction creation query](https://bump.sh/pgw/doc/imoje-api-en/operation/operation-post-parameter-transaction). 

      To call the calculator, use the appropriate JavaScript script and call it in the object with the ID `imoje-installments__wrapper`.

      ### Widget URLs

      **PRODUKCJA:** `https://paywall.imoje.pl/js/installments.js`

      **SANDBOX:** `https://sandbox.paywall.imoje.pl/js/installments.js`

      ### Script ID

      `imoje-installments__script`

      #### Parameters

      | Parameter               | Description                                 |
      |------------------------|--------------------------------------|
      | `merchantId`           | Customer ID                 |
      | `serviceId`            | Customer store ID as `UUID v4`                |
      | `amount`               | Transaction amount in the smallest currency unit, e.g. pence. Minimum value: `30000` Maximum value: `5000000` |
      | `currency`             | Transaction currency in ISO 4217 standard, **acceptable value:** `PLN`                |
      | `signature`            | [Calculated signature](#topic-authorisation)                |

      ### Example of script invocation

      ```javascript
          (function () {
            const form = document.getElementById('form');

            function onSubmit(event) {
              event.preventDefault();

              let script = document.getElementById('imoje-installments__script');
              if (!script) {
                script = document.createElement('script');
                script.id = 'imoje-installments__script';
                script.src = 'https://paywall.imoje.pl/js/installments.js';
                script.onload = () => onSubmit(event);
                document.body.appendChild(script);
                return;
              }

              const options = { 
                merchantId: "Twój identyfikator Klienta", 
                serviceId: "Twój identyfikator sklepu", 
                amount: "Kwota zamówienia", 
                currency: "PLN", 
                signature: "Wyliczona sygnatura" 
              };

              document.getElementById('imoje-installments__wrapper').imojeInstallments(options);
            }

            form.addEventListener('submit', onSubmit);
          })();
      ```

      ### Downloading settings from the calculator

      Depending on the imoje instalment channel selected on the calculator and the number of instalments, the widget creates a new event each time, based on which you can download the values and pass them in the request creating the transaction.

      #### Example of data download 

      ```javascript
          window.addEventListener('message', function (data) {
              if (data.data.channel && data.data.period) {
                  var channel = data.data.channel;
                  var period = data.data.period;
              }
          }, false);
      ```

      ## Refunds to imoje instalments

      With this payment method, the supplier decides how much can be refunded for a given transaction.

      To obtain information about the maximum amount of full and partial refunds, please use [this request](https://bump.sh/pgw/doc/imoje-api-en/operation/operation-post-parameter-transaction-parameter-can-refund).

  - title: Split Payment
    content: |
      An `invoice` object must be attached to the basic request creating the transaction as described in the section [Creating a payment](#topic-creating-a-payment). This object consists of a `buyer` object and a `positions` array with the following parameters:

      `buyer` object:

      | Parameter | Type | Parameter required | Description |
      |-------------------|-----------------------------------------------|-|-|
      | `invoiceId`       | string      | `YES`             | Invoice number |
      | `type`    | string | `YES` | It takes the value `PERSON` *individual buyer or `COMPANY` *company* |
      | `email`   | string(200) | `YES` | E-mail address in the format compliant with RFC 5322 and RFC 6531 |
      | `fullName`| string(200) | `YES` | Buyer's name/company name, <br> **available characters:** A-Za-z0-9#&_-"',.\/ space (0x20) and the UNICODE characters from the range 00C0 - 02C0 (e.g. Polish diacritic characters), 0400 - 04FF (Cyrillic script) |
      | `street`  | string(200) | `YES` | Street |
      | `city`    | string(100) | `YES` | City
      | `postalCode` | string(30) | `YES` | Postal code |
      | `countryCodeAlpha2` | string(2) | `YES` | Country code `Alpha2` |
      | `idCountryCodeAlpha2` | string(2) | `NO` | `Alpha2` country code identifier. Required for the `VAT_ID` value of the `idType` parameter. |
      | `idType`  | string | `NO` | Identification number type. Required for the `COMPANY` value of the `type` parameter. Takes the value of `ID` *TIN* or `VAT_ID` *CRN* |
      | `idNumber`| string(30) | `NO` | CRN or TIN number. Required for the `COMPANY` value of the `type` parameter |

      `positions` array:

      | Parameter | Type | Parameter required | Description |
      |-------------------|-----------------------------------------------|-|-|
      | `name` | string | `YES` | Product name |
      | `code` | string | `YES` | Product code |
      | `quantity` | number | `YES` | Quantity. The **minimum value is 0** |
      | `unit` | string | `YES` | Unit |
      | `grossAmount` | integer | `YES` | Gross unit value |
      | `taxStake` | string | `YES` | Tax rate. Available values: `TAX_23`, `TAX_22`, `TAX_8`, `TAX_7`, `TAX_5`, `TAX_3`, `TAX_0`, `TAX_EXEMPT`, `TAX_NOT_LIABLE`, `TAX_REVERSE_CHARGE`, `TAX_EXCLUDING` |
      | `taxAmount`       | integer     | `YES`             | Value of tax in pennies |
      | `discountAmount` | integer | `NO` | Discount value |

      ### Example data structure

      ```php
      $invoiceData = [
          "invoiceId" => "04/12/23",
          "buyer"     => [
              "type"                => "COMPANY",
              "idType"              => "VAT_ID",
              "idNumber"            => "5354235387",
              "email"               => "nazwafirmy@example.com",
              "fullName"            => "Nazwa firmy",
              "street"              => "Ulica",
              "city"                => "Miasto",
              "postalCode"          => "12-345",
              "countryCodeAlpha2"   => "PL",
              "idCountryCodeAlpha2" => "PL"
          ],
          "positions" => [
              [
                  "name"        => "Produkt",
                  "code"        => "produkt-01",
                  "quantity"    => 1,
                  "unit"        => "Sztuki",
                  "taxStake"    => "TAX_23",
                  "grossAmount" => 12300,
                  "taxAmount" =>  2300
              ],
          ],
      ];
      ```

      The above parameters should be taken into account when calculating the signature in accordance with the section [Authorisation](#topic-authorisation)

      ### Preparing the invoice object

      ### Using the PHP function
      The data collected from the above parameters should be encoded using the function:
      `base64_encode(gzencode(json_encode($invoiceData), 5));` 

      where:

      `$invoiceData` - previously prepared parameters

      ```php
      $invoiceData = [
          "invoiceId" => "04/12/23",
          "buyer"     => [
              "type"                => "COMPANY",
              "idType"              => "VAT_ID",
              "idNumber"            => "5354235387",
              "email"               => "nazwafirmy@example.com",
              "fullName"            => "Nazwa firmy",
              "street"              => "Ulica",
              "city"                => "Miasto",
              "postalCode"          => "12-345",
              "countryCodeAlpha2"   => "PL",
              "idCountryCodeAlpha2" => "PL"
          ],
          "positions" => [
              [
                  "name"        => "Produkt",
                  "code"        => "produkt-01",
                  "quantity"    => 1,
                  "unit"        => "Sztuki",
                  "taxStake"    => "TAX_23",
                  "grossAmount" => 12300,
                  "taxAmount" =>  2300
              ],
          ],
      ];
      $invoice = base64_encode(gzencode(json_encode($invoiceData), 5));

      $fields = [
          'serviceId' => '63f574ed-d90d-4abe-9cs1-39117584a7b7',
          'merchantId' => '6yt3gjtm9p1odfgx8491',
          'amount' => '12300',
          'currency' => 'PLN',
          'orderId' => 'Split payment',
          'orderDescription' => 'Split payment',
          'customerFirstName' => 'Jan',
          'customerLastName' => 'Kowalski',
          'customerEmail' => 'jan.kowalski@example.com',
          'customerPhone' => '501501501',
          'visibleMethod' => 'wt',
          'urlSuccess' => 'https://domain.com/success',
          'urlFailure' => 'https://domain.com/failure',
          'urlReturn' => 'https://domain.com/return',
          'invoice' => $invoice,
      ];
      $serviceKey = 'eAyhFLuHgwl5hu-32GM8QVlCVMWRU0dGjH1c';
      $hashMethod = 'sha256';
      $signature= createSignature(
          $fields,
          $serviceKey,
          $hashMethod
      ) . ';' . $hashMethod;
      ```

      ### Example of an encoded invoice object

      ```php
      H4sIAAAAAAAACm2QXU+DMBSG/4rp9eaAQjRcSfBmiUOSodE4s3TQaUM/EE51jPDfPe3inZfneT/6phMR+tuImq8bkpIg3q3CaLeKKFmQgx15T9KJwNhxFPPHTZkVr6iIprqg56zar+89Kaw6ODtJaBJHNKG3N8i5YkIi1Oz8w46iV+MdPzHVSX5dG4WGo5WyYMqVFc5z5U0oDNBzDoifpKgZglrAiOdGsAEM3p0ZgMncNC4bRksaJ85lrIZ+dDiT3SeLUCwf/ML8f2n2VQKE0QNJ3ybc6ueUvWlsC77Tv9FdwDIIkX1ZpsEvChfEauGWbs9gW4EisNMWWOtCVfay97/50ZthyJTbgJmIBoH3/REH5vf5FyK2JcWPAQAA
      ```
      ### Example HTML form content

      ```html
      <input type="hidden" value="63f574ed-d90d-4abe-9cs1-39117584a7b7" name="serviceId">
      <input type="hidden" value="6yt3gjtm9p1odfgx8491" name="merchantId">
      <input type="hidden" value="12300" name="amount">
      <input type="hidden" value="PLN" name="currency">
      <input type="hidden" value="Split payment" name="orderId">
      <input type="hidden" value="Split payment" name="orderDescription">
      <input type="hidden" value="Jan" name="customerFirstName">
      <input type="hidden" value="Kowalski" name="customerLastName">
      <input type="hidden" value="jan.kowalski@example.com" name="customerEmail">
      <input type="hidden" value="501501501" name="customerPhone">
      <input type="hidden" value="wt" name="visibleMethod">
      <input type="hidden" value="https://domain.com/success" name="urlSuccess">
      <input type="hidden" value="https://domain.com/failure" name="urlFailure">
      <input type="hidden" value="https://domain.com/return" name="urlReturn">
      <input type="hidden" value="<?= $invoice ?>" name="invoice">
      ```

  - title: Multipayout
    content: |
      This option is available when the multi-payment function is enabled. An additional `multipayout` table with the following parameters should be attached to the basic request:

      | Parameter           | Type          | Required parameter | Description          |
      |---------------------|---------------|--------------------|----------------|
      | `ban`               | string        | `YES`              | Bank account number |
      | `amount`            | integer       | `YES`              | Amount of transaction in the smallest currency unit, e.g. **pennies** |
      | `label`             | string(70)    | `YES`              | Recipient's name, **allowed characters**: A-Za-z0-9-',. and space character(0x20) and characters from the UNICODE range 00C0 - 02C0 (including Polish diacritics) |
      | `title`             | string(105)   | `NO`               | Transfer title, **allowed characters**: A-Za-z0-9#&_-"',.and space character(0x20) and characters from the UNICODE 00C0 - 02C0 range (including Polish diacritics). <br> Its presence causes the given transaction to be extracted from the recipient's account. <br> Specifying the parameter for one element determines the necessity of providing it for the other elements. |

      Each payment included in the form below should contain consecutive indices **numbered from 0**.

      Example HTML form content:

      ```html
      <input type="hidden" value="63f574ed-d90d-4abe-9cs1-39117584a7b7" name="serviceId">
      <input type="hidden" value="6yt3gjtm9p1odfgx8491" name="merchantId">
      <input type="hidden" value="300" name="amount">
      <input type="hidden" value="PLN" name="currency">
      <input type="hidden" value="123" name="orderId">
      <input type="hidden" value="Example transaction" name="orderDescription">
      <input type="hidden" value="John" name="customerFirstName">
      <input type="hidden" value="Doe" name="customerLastName">
      <input type="hidden" value="johndoe@domain.com" name="customerEmail">
      <input type="hidden" value="501501501" name="customerPhone">
      <input type="hidden" value="https://your-shop.com/success" name="urlSuccess">
      <input type="hidden" value="https://your-shop.com/failure" name="urlFailure">
      <input type="hidden" value="https://your-shop.com/return" name="urlReturn">
      <input type="hidden" value="card,pbl" name="visibleMethod">
      <input type="hidden" value="72105000028166973380325415" name="multipayout[0][ban]">
      <input type="hidden" value="100" name="multipayout[0][amount]">
      <input type="hidden" value="Nazwa firmy 0" name="multipayout[0][label]">
      <input type="hidden" value="58105000025503268251444948" name="multipayout[1][ban]">
      <input type="hidden" value="200" name="multipayout[1][amount]">
      <input type="hidden" value="Nazwa firmy 1" name="multipayout[1][label]">
      <input type="hidden" value="1a466af99a18c4691576bbbf5b935e2ac082285ae28a88f8686ac3317836a6f5;sha256" name="signature">
      ```

      ## Example data structure

      ```php
      $fields = [
          'merchantId' => '6yt3gjtm9p1odfgx8491',
          'serviceId' => '63f574ed-d90d-4abe-9cs1-39117584a7b',
          'amount' => '300',
          'currency' => 'PLN',
          'orderId' => '123',
          'orderDescription' => 'Example transaction',
          'customerFirstName' => 'John',
          'customerLastName' => 'Doe',
          'customerEmail' => 'johndoe@domain.com',
          'customerPhone' => '501501501',
          'urlSuccess' => 'https://your-shop.com/success',
          'urlFailure' => 'https://your-shop.com/failure',
          'urlReturn' => 'https://your-shop.com/return',
          'multipayout' => [
              [
              'ban' => '72105000028166973380325415',
              'amount' => '100',
              'label' => 'Nazwa firmy 0',
              ],
              [
              'ban' => '58105000025503268251444948',
              'amount' => '200',
              'label' => 'Nazwa firmy 1',
              ],
          ],
      ];
      ```

      The above parameters should be taken into account when calculating the signature in accordance with the section [Authorisation](#topic-authorisation).

  - title: ING Księgowość
    content: |
      This option is available when the ING Księgowość service is **enabled**. An `invoice` object must be attached to the basic request creating the transaction as described in the section [Creating a payment](#topic-creating-a-payment). This object consists of a `buyer` object and a `positions` array with the following parameters:
      
      `buyer` object:

      | Parameter | Type | Parameter required | Description |
      |-------------------|-----------------------------------------------|-|-|
      | `type`    | string | `YES` | It takes the value `PERSON` *individual buyer* or `COMPANY` *company* |
      | `email`   | string(200) | `YES` | E-mail address in the format compliant with RFC 5322 and RFC 6531 |
      | `fullName`| string(200) | `YES` | Buyer's name/company name |
      | `street`  | string(200) | `YES` | Street |
      | `city`    | string(100) | `YES` | City
      | `postalCode` | string(30) | `YES` | Postal code |
      | `countryCodeAlpha2` | string(2) | `YES` | Country code `Alpha2` |
      | `idCountryCodeAlpha2` | string(2) | `NO` | `Alpha2` country code identifier. Required for the `VAT_ID` value of the `idType` parameter |
      | `idType`  | string | `NO` | Identification number type. Required for the `COMPANY` value of the `type` parameter. Takes the value of ID *TIN* or VAT_ID *CRN*. |
      | `idNumber`| string(30) | `NO` | CRN or TIN number. Required for the `COMPANY` value of the `type` parameter. |

      `positions` array:

      | Parameter | Type | Parameter required | Description |
      |-------------------|-----------------------------------------------|-|-|
      | `name` | string | `YES` | Product name |
      | `code` | string | `YES` | Product code |
      | `quantity` | number | `YES` | Quantity. **The minimum value is 0** |
      | `unit` | string | `YES` | Unit |
      | `grossAmount` | integer | `YES` | Gross unit value |
      | `taxStake` | string | `YES` | Tax rate. **Available values:** <br> `TAX_23` <br> `TAX_22` <br> `TAX_8` <br> `TAX_7` <br> `TAX_5` <br> `TAX_3` <br> `TAX_0` <br> `TAX_EXEMPT` <br> `TAX_NOT_LIABLE` <br> `TAX_REVERSE_CHARGE` <br> `TAX_EXCLUDING` |
      | `discountAmount` | integer | `NO` | Discount value |

      In the case of tax exemption, the relevant data should be provided in the request using the `basisForVatExemption` object with the following parameters:

      | Parameter | Type   | Parameter required | Description |
      |-----------|--------|--------------------|-------------|
      | `type`    | string | `NO`               | **Available values:** <br> `DENTAL_TECHNICAN_SERVICES`, <br> `DOCTOR_DENTIST_SERVICES`, <br> `PHYSIOTHERAPY_SERVICES`, <br> `NURSING_SERVICES`, <br> `PSYCHOLOGICAL_SERVICES`, <br> `MEDICAL_TRANSPORT_SERVICES`, <br> `CARE_SERVICES`, <br> `TUTORING`, <br> `TEACHING_FOREIGN_LANGUAGES`, <br> `ARTISTS`, <br> `RENTING_PROPERTY`, <br> `INSURANCE_SERVICES`, <br> `CREDITS_AND_LOANS_SERVICES`, <br> `GUARANTIEES`, <br> `SPECIAL_CONDITIONS_FOR_EXEMPTION`, <br> `UE_TRANSACTIONS`, <br> `SUBJECTIVE_EXEMPTIONS`, <br> `OTHER`, <br> `OTHER_OBJECTIVE_EXEMPTIONS` |
      | `text`    | string | `NO`               | Description. This parameter is required when the value `OTHER` is specified in the `type` parameter. |


      Additionally, it is possible to specify whether the invoice should be sent automatically using the parameter:

      | Parameter      | Type    | Parameter required | Description                  |
      |----------------|---------|--------------------|------------------------------|
      | `issueInvoice` | boolean | `NO`               | Automatic invoice sending |

      ## Example data structure

      ```php
      $invoiceData = [
          "buyer"     => [
              "type"              => "PERSON",
              "email"             => "jan.kowalski@example.com",
              "fullName"          => "Jan Kowalski",
              "street"            => "Street",
              "city"              => "City",
              "postalCode"        => "12-345",
              "countryCodeAlpha2" => "PL",
          ],
          "positions" => [
              [
                  "name"        => "Produkt",
                  "code"        => "produkt-01",
                  "quantity"    => 1,
                  "unit"        => "Sztuki",
                  "taxStake"    => "TAX_23",
                  "grossAmount" => 12300,
              ],
          ],
      ];
      ```

      The above parameters should be taken into account when calculating the signature in accordance with the section [Authorisation](#topic-authorisation).

      ## Preparing the invoice object

      ### Using PHP functions
      The data collected from the above parameters should be encoded using the following functions:

      ```
      base64_encode(gzencode(json_encode($invoiceData), 5));
      ```

      where:

      `$invoiceData` - previously prepared parameters

      ```php
      $invoiceData = [
          "buyer"     => [
              "type"              => "PERSON",
              "email"             => "jan.kowalski@example.com",
              "fullName"          => "Jan Kowalski",
              "street"            => "Street",
              "city"              => "City",
              "postalCode"        => "12-345",
              "countryCodeAlpha2" => "PL",
          ],
          "positions" => [
              [
                  "name"        => "Produkt",
                  "code"        => "produkt-01",
                  "quantity"    => 1,
                  "unit"        => "Sztuki",
                  "taxStake"    => "TAX_23",
                  "grossAmount" => 12300,
              ],
          ],
      ];
      $invoice = base64_encode(gzencode(json_encode($invoiceData), 5));

      $fields = [
          'serviceId' => '63f574ed-d90d-4abe-9cs1-39117584a7b7',
          'merchantId' => '6yt3gjtm9p1odfgx8491',
          'amount' => '12300',
          'currency' => 'PLN',
          'orderId' => '123',
          'orderDescription' => '#Example transaction',
          'customerFirstName' => 'Jan',
          'customerLastName' => 'Kowalski',
          'customerEmail' => 'jan.kowalski@example.com',
          'customerPhone' => '515515515',
          'urlSuccess' => 'https://your-shop.com/success',
          'urlFailure' => 'https://your-shop.com/failure',
          'urlReturn' => 'https://your-shop.com/return',
          'invoice' => $invoice,
      ];
      $serviceKey = 'eAyhFLuHgwl5hu-32GM8QVlCVMWRU0dGjH1c';
      $hashMethod = 'sha256';
      $signature= createSignature(
          $fields,
          $serviceKey,
          $hashMethod
      ) . ';' . $hashMethod;
      ```
      ## Example of an encoded invoice object

      ```php
      H4sIAAAAAAAAA0WOQQvCNAyF/4rkPGWbenAnh3gTFedBEJGqVcu6dq4pOMf+u8MYeAnJl/fy0sDF17KCpAGsSwkJbJe7bLOGAGQhlCaA0uGcy6jUhO9e67UoZL8zcCHssJISfzAiclVY9zNNpXUo9MLe2BjFw/KkyhrrDVY141SXTxHzAytoO71CZY2D5NiA+QfGna07M6P25YXBLikKwBvFL2Qf9LmiJYp3hiJn7T49nENCj8o6lxacS5ZpGLan9gsKdX5sBQEAAA==
      ```
      ## Example HTML form content

      ```html
      <input type="hidden" value="63f574ed-d90d-4abe-9cs1-39117584a7b7" name="serviceId">
      <input type="hidden" value="6yt3gjtm9p1odfgx8491" name="merchantId">
      <input type="hidden" value="300" name="amount">
      <input type="hidden" value="PLN" name="currency">
      <input type="hidden" value="123" name="orderId">
      <input type="hidden" value="Example transaction" name="orderDescription">
      <input type="hidden" value="John" name="customerFirstName">
      <input type="hidden" value="Doe" name="customerLastName">
      <input type="hidden" value="johndoe@domain.com" name="customerEmail">
      <input type="hidden" value="501501501" name="customerPhone">
      <input type="hidden" value="https://your-shop.com/success" name="urlSuccess">
      <input type="hidden" value="https://your-shop.com/failure" name="urlFailure">
      <input type="hidden" value="https://your-shop.com/return" name="urlReturn">
      <input type="hidden" value="<?= $invoice ?>" name="invoice">
      ```

  - title: ING Lease Now
    content: |
      This option is available when the ING Lease Now service is enabled. 
      The basic request creating the payment must be accompanied by a `cart` object with an `items` array containing the following parameters:

      | Parameter | Type | Required parameter | Description |
      |-------------------|-----------------------------------------------|-|-|
      | `id` | string | `YES` | Product identifier |
      | `name` | string | `YES` | Name of the product |
      | `amount` | integer | `YES` | Unit value of the net product in the smallest unit of currency - **pennies**. The value `0` is also allowed. |
      | `tax` | integer | `YES` | Tax unit value|
      | `taxStake` | string | `YES` | Tax rate. **Available values**: `23`, `22`, `8`, `7`, `5`, `3`, `0`, `TAX_EXEMPT`, `TAX_NOT_LIABLE`, `TAX_REVERSE_CHARGE`, `TAX_EXCLUDING` |
      | `quantity` | integer | `YES` | Quantity. **Minimum value is 0** |
      | `url` | string | `YES` | The url for the product in question |
      | `categoryId` | string | `YES` | Category identifier |
      | `unit` | string | `NO` | unit |
      | `state` | integer | `NO` | Product state. **available values**: `NEW`, `USED` |
      | `discount.amount` | integer | `NO` | Value of discount |
      | `discount.tax` | integer | `NO` | Discount tax value |

      The minimum value for a single product in Leasing is PLN 1,000, while the value of the entire basket must be at least PLN 5,000. The amounts given are **net** amounts.

      ## Example data structure

      ```php
      $cart = [
          'items' => [
              [
                  'id'         => 1,
                  'categoryId' => 'category123',
                  'name'       => 'Product name',
                  'amount'     => 1000,
                  'tax'        => 230,
                  'taxStake'   => 23,
                  'quantity'   => 1,
                  'unit'       => 'szt',
                  'url'        => 'https://product.url',
                  'state'      => 'NEW',
                  'discount'   => [
                      'amount' => 100,
                      'tax'    => 23,
                  ]
              ]
          ]
      ];
      ```

      The above parameters should be taken into account when calculating the signature in accordance with the section [Authorisation](#topic-authorisation).

      ## Preparing the cart object

      ### Using the PHP function
      The data collected from the above parameters should be encoded using the function:

      ```
      base64_encode(gzencode(json_encode($cart), 5));
      ``` 

      where:

      `$cart` - previously prepared parameters

      ```php
      $cart = [
          'items' => [
              [
                  'id'         => 1,
                  'categoryId' => 'category123',
                  'name'       => 'Product name',
                  'amount'     => 500000,
                  'tax'        => 115000,
                  'taxStake'   => 23,
                  'quantity'   => 1,
                  'unit'       => 'szt',
                  'url'        => 'https://product.url',
                  'state'      => 'NEW',
                  'discount'   => [
                      'amount' => 100,
                      'tax'    => 23,
                  ],
              ],
          ],
      ];
      $cart = base64_encode(gzencode(json_encode($cart), 5));

      $fields = [
          'serviceId' => '63f574ed-d90d-4abe-9cs1-39117584a7b7',
          'merchantId' => '6yt3gjtm9p1odfgx8491',
          'amount' => '615000',
          'currency' => 'PLN',
          'orderId' => '123',
          'orderDescription' => '#Example transaction',
          'customerFirstName' => 'Jan',
          'customerLastName' => 'Kowalski',
          'customerEmail' => 'jan.kowalski@example.com',
          'customerPhone' => '515515515',
          'urlSuccess' => 'https://your-shop.com/success',
          'urlFailure' => 'https://your-shop.com/failure',
          'urlReturn' => 'https://your-shop.com/return',
          'cart' => $cart,
      ];
      $serviceKey = 'eAyhFLuHgwl5hu-32GM8QVlCVMWRU0dGjH1c';
      $hashMethod = 'sha256';
      $signature = createSignature(
          $fields,
          $serviceKey,
          $hashMethod
      ) . ';' . $hashMethod;
      ```
      Using the additional parameter `visibleMethod` with the value `lease` will display only Leasing on the gateway. This allows you to extract a given method as a separate item in the summary.

      ## Example form content

      ```html
      <input type="hidden" value="63f574ed-d90d-4abe-9cs1-39117584a7b7" name="serviceId">
      <input type="hidden" value="6yt3gjtm9p1odfgx8491" name="merchantId">
      <input type="hidden" value="300" name="amount">
      <input type="hidden" value="PLN" name="currency">
      <input type="hidden" value="123" name="orderId">
      <input type="hidden" value="Example transaction" name="orderDescription">
      <input type="hidden" value="John" name="customerFirstName">
      <input type="hidden" value="Doe" name="customerLastName">
      <input type="hidden" value="johndoe@domain.com" name="customerEmail">
      <input type="hidden" value="501501501" name="customerPhone">
      <input type="hidden" value="https://your-shop.com/success" name="urlSuccess">
      <input type="hidden" value="https://your-shop.com/failure" name="urlFailure">
      <input type="hidden" value="https://your-shop.com/return" name="urlReturn">
      <input type="hidden" value="<?= $cart ?>" name="cart">
      ```
  
  - title: Sandbox
    content: |
      Imoje offers a sandbox test mode to verify the correctness of the integration.

      The sandbox test environment can be found [here](https://sandbox.imoje.ing.pl).
      <br><br>To create a new account, click `Create Merchant Account`, then enter your e-mail address, to which a link to activate your account will be sent.
      After activating your account, simply log in with the generated login and the previously assigned password.
      A test shop will be assigned to your account, which will have its own integration data.

      ## Cards in the sandbox environment
      To test card payments, use the following details:

      | Card issuer | Card number | Month | Year | CVV | 3-D Secure | Description |
      |-------------|------------------|-------|------|-----|-------------|----------------------------------------------------------------------------|
      | Visa | 4111111111111111 | 12 | 29 | 123 | no | **Positive authorization** - profile transaction completed |
      | Visa | 4485201817664006 | 12 | 29 | 123 | no | **Positive authorization** - profile transaction rejected, dcc rejected |
      | Visa | 4444333322221111 | 12 | 29 | 123 | no | **Negative authorisation** |
      | Visa | 4012001037141112 | 12 | 29 | 123 | yes | **Positive authorization** - profile transaction completed |
      | Visa | 4749601201390567 | 12 | 29 | 123 | yes | **Positive authorization** - profile transaction rejected |
      | Visa | 4934403892699132 | 12 | 29 | 123 | yes | **Negative authorisation** |
      | Visa | 4012001007002005 | 12 | 29 | 123 | no | **Provider error** |
      | Visa | 4282513338596268 | 12 | 29 | 123 | no | **Positive authorization** - profile provider transaction error |

      ## PBL and BLIK transactions in the sandbox environment.
      In order to test PBL or BLIK transactions, send the appropriate value of the `orderDescription` parameter in the basic request with the [Creating a payment](#topic-creating-a-payment) point.

      | orderDesription         | Description                                    |
      |---------------|-----------------------------------------------|
      | `TEST-100000` | Standard - Refund settled, default action |
      | `TEST-100010` | Provider error |