> ## Documentation Index
> Fetch the complete documentation index at: https://docs.m4psp.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Invoice refund status

> To get status and up-to-date information on refunds.

<div class="success">
<p>Fields involved in request signature generation:</p>

* `invoice_id`
* `now`
* `shop_id`
</div>



## OpenAPI

````yaml /openapi.yaml post /invoice/get-refunds
openapi: 3.0.2
info:
  version: 1.0.0
  title: M4 Payment Gateway API
  termsOfService: https://m4solutions.io/terms
  contact:
    url: https://api.m4psp.com/gateway/v1/
    name: M4 Support
  description: >-
    ![M4 Logo](/assets/m4/images/m4-logo.png)


    ## Description


    Using this API, you can interact with M4 payment platform: accept payments,
    make payments and perform other operations supported by the platform.


    API runs over HTTP(S) protocol and uses JSON format to exchange data.


    All API requests must use `UTF-8` encoding and specify the `Content-Type:
    application/json` header. Each request must be signed, the signature
    generation process is described below, in the **Request signature** section.


    We use the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) standard as
    the date and time formats, if the time zone is not specified, then
    [UTC+03:00](https://en.wikipedia.org/wiki/Time_zone) is assumed.



    ## API changes


    To ensure that our API improvements do not break your integration, please
    consider the following list of backward compatible changes that can occur
    without increasing your M4 API version number.


    <div class="success">

    <p>We consider the following changes to our services to be
    backward-compatible:</p>


    * Adding new optional request parameters to existing API methods

    * Adding new fields to existing API responses (disregarding nullability)

    * Changing the order of fields in existing API responses

    * Adding new error codes

    * Adding new optional HTTP request headers

    * Adding new HTTP response headers

    * Adding new types of callback notifications

    * Changing the order of fields in callback notifications

    * Adding new fields in callback notification (while complying with the
    request signing rules)

    </div>


    ## Request signature


    <SecurityDefinitions />
servers:
  - url: https://api.m4psp.com/gateway/v1/
    description: The production API server
  - url: https://api.test.cplus-int.tech/gateway/v1/
    description: The test API server
security: []
tags:
  - name: invoice-create
    x-displayName: Invoice issue (payment creation)
    description: >
      ### Invoicing procedure


      `Single-step payment` is a type of payment in which a single request
      [invoice/create](/api-reference/invoice-create/invoice-issue) is
      immediately blocking and withdrawing funds.


      `Two-step payment` is a type of payment when funds are withdrawn in two
      steps.

      *You can check which payment ways support two-stage payment with the
      manager.*

      The first request
      [invoice/hold](/api-reference/invoice-create/funds-hold-two-stage-payments)
      is used to hold (block) funds on the client's account.

      The second request
      [invoice/charge](/api-reference/invoice-create/confirmation-of-funds-withdrawal-charge)
      initiates the withdrawal.

      If you want to cancel a previously held payment, then cancel it using the
      [invoice/unhold](/api-reference/invoice-create/cancellation-of-funds-holding)
      method. The money will be returned to the payer.


      ### Single-step payment

      ![Invoice Flow Diagram](assets/common/images/en/invoice-flow.v1.png)


      1. User generates an order on the shop's website;


      2. Shop sends a request to pre-calculate the invoice and get additional
      parameters
      [invoice/try](/api-reference/invoice-create/invoice-preliminary-calculation);


      3. When receiving `result: true`, verify the availability of additional
      information in `add_ons_config`, if present, it is necessary to pass
      additional parameters in the invoice request. When you get `result:
      false`, you need to analyse the error code in the `error_code` field (see
      [description of error codes](/errors-list)). If the `error code` is not
      fatal, then you need to wait for the [server notification](/callbacks). If
      the `error code` is fatal, then communication with our API is over.


      4. After verifying
      [invoice/try](/api-reference/invoice-create/invoice-preliminary-calculation),
      the shop sends an invoice request
      [invoice/create](/api-reference/invoice-create/invoice-issue), specifying
      the required parameters and additional information from `add_ons_config`
      (if it is required for the specified payment direction);


      5. The response returns information with the invoice and data to be sent
      by the specified method to the specified URL for making or charging the
      payment. It is necessary to send the user to make a payment. In case
      `result: false`, you need to analyse the error code in the `error_code`
      field (see [description of error codes](/errors-list)). If the `error
      code` is not fatal, then you need to wait for the [server
      notification](/callbacks). If the `error code` is fatal, then
      communication with our API is over, it is necessary to inform the user
      that the payment was not created.


      6. After the payment is made or charged by the user, the M4 system [sends
      a notification](/callbacks) to the URL of interaction with the shop,
      containing payment information, for more information, see
      [here](/api-reference/invoice-create/invoice-issue);


      7. After receiving the charge, the payment is considered successfully
      completed.


      ### Two-step payment


      *Most often, a two-stage payment is used for payments by bank cards.*


      ![Invoice Two Stage Flow
      Diagram](assets/common/images/en/invoice-two-stage-flow.v1.png)


      1. User generates an order on the shop's website;


      2. Shop sends a request for a preliminary calculation of the issued
      invoice and receiving additional parameters
      [invoice/try](/api-reference/invoice-create/invoice-preliminary-calculation);


      3. When receiving `result: true`, the availability of additional
      information in `add_ons_config` is checked, if present, additional
      parameters should be passed in the invoice request. When you get `result:
      false`, you need to analyse the error code in the `error_code` field (see
      [description of error codes](/errors-list)). If the `error code` is not
      fatal, then you need to wait for the [server notification](/callbacks). If
      the `error code` is fatal, then communication with our API is over.


      4. After verification
      [invoice/try](/api-reference/invoice-create/invoice-preliminary-calculation)
      shop sends invoice request
      [invoice/hold](/api-reference/invoice-create/funds-hold-two-stage-payments),
      specifying the required parameters and additional information from
      `add_ons_config` (if it is required for the specified payment way);


      5. The response returns information with the invoice issued and data to be
      sent by the specified method to the specified URL for making or charging
      the payment. It is necessary to refer the user to make the payment. In
      case `result: false`, you need to analyse the error code in the
      `error_code` field (see [description of error codes](/errors-list)). If
      the `error code` is not fatal, then you need to wait for the [server
      notification](/callbacks). If the `error code` is fatal, then
      communication with our API is over, it is necessary to inform the user
      that the payment was not created.


      6. After payment is completed by the user, the M4 system [sends a
      notification](/callbacks) to the shop's interaction URL, with information
      about the blocking of funds;


      7. After the funds are blocked on the client's account, you can charge the
      payment
      [invoice/charge](/api-reference/invoice-create/confirmation-of-funds-withdrawal-charge)
      or cancel the holding
      [invoice/unhold](/api-reference/invoice-create/cancellation-of-funds-holding);


      8. The response returns information with the result of charge (sometimes
      the payment status may not be final, then you should wait for the
      notification);


      9. M4 system [will send a notification](/callbacks) to the URL of the
      interaction of the shop with the final status regarding the confirmation
      of funds withdrawal.


      ### Ensuring payments idempotency


      <div class="warning">

      The system has duplication protection for invoice creation,
      <code>shop_order_id</code> should be unique within a single shop.

      </div>
  - name: invoice-refund
    x-displayName: Refunds
    description: >
      The refund of the paid invoice can be full or partial.


      * In case of a full refund, you refund the successfully paid payment in
      full.

      * In case of a partial refund - a part of the payment amount, for example,
      if you want to refund a part of the purchase.


      After confirmation of the refund by the payment system, the M4 system
      [will send a notification](/callbacks) with details

      of refund to the URL transferred in the request when creating the refund.
      A detailed description of the notification format

      is described [here](/callbacks#refund-notification-example).


      Please note that if you receive `result: false` in response in case of a
      synchronous response to a request, this means that

      you need to analyse the error code in the `error_code` field (see
      [description of error codes](/errors-list)). If the `error code` is not
      fatal, then you need to wait for the [server notification](/callbacks). If
      the `error code` is fatal, then the refund transaction will not be created
      (it will either not be created at all if basic checks

      have not passed, or it will be created with the immediate status
      `FAILED`). In this case, communication with our API is over.


      If in case of a synchronous response to a request in the response you
      received `result: true`, this means that you need to check the status

      of the refund transaction in the response body:

      it can be final (`SUCCESS`, `FAILED`), and then communication with the API
      is over, or it can be `WAITING` — then

      you have to wait for some time for a [server notification](/callbacks)
      from us with the final status.


      <div class="success">

      Refunds are made in the currency of the paid invoice, under which the
      refund transaction is carried out.

      </div>


      <div class="warning">

      Check with the manager for available refund ways for specific payment
      methods.

      </div>
  - name: callbacks
    x-displayName: Interaction format
    description: >
      ### Issued invoice notice after payment or refund


      After changing the payment status or returning to one of the final ones,
      the M4 system sends a notification to the shop to the URL specified in the
      shop settings or in the request body (if specified in the description of
      the request parameters).


      <div class="warning">

      <p>To successfully receive server-side notifications, please make sure
      that your server receiving HTTP requests from us is configured according
      to the current security standards described on <a
      href="https://cheatsheetseries.owasp.org/cheatsheets/Transport_Layer_Protection_Cheat_Sheet.html">https://cheatsheetseries.owasp.org/cheatsheets/Transport_Layer_Protection_Cheat_Sheet.html</a></p>

      <p>Pay special attention to the TLS ciphers you support.</p>

      </div>


      Notifications for payments and refunds are delivered to one callback URL.
      You can distinguish notifications by the value of the GET parameter named
      `type` in the URL from which you received the notification.

      Possible values of `type`:

      * `invoice` - payment notification

      * `refund` - refund notification


      Server notifications are sent from the following IP addresses:


      |IP addresses|

      |-|

      |35.198.100.222|

      |35.198.175.25|


      HTTP protocol is used to send the notification:


      * Method: `POST`

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


      <div class="success">

      <p>If necessary, the support service can enable an alternative
      notification format: <code>Content-Type:
      application/x-www-form-urlencoded</code>, in this case, all the
      transmitted parameters will have a string representation.</p>

      </div>


      <div class="attention">

      <p>It is <strong>necessary</strong> to check the values from the
      notification with the values in the invoice, and <strong>to check</strong>
      signature in the notification.</p>

      <p>The signature is generated using the same algorithm as when issuing the
      invoice.</p>

      <p>All the not-null and non-empty parameters present in the notification
      are involved in the signature validation, including zero values. At the
      same time, <code>null</code> values and empty strings are not involved in
      signature validation and are excluded.</p>

      </div>


      <p>Consider building your system using forward compatibility strategy to
      be ready to handle new parameters in the server notifications without need
      to upgrade your own system.</p>


      ### Expected response


      If the notice is received and processed correctly, it is necessary to
      return the status `200` and the message body `OK` (`text/plain`) to the
      `HTTP` response. Otherwise, notices will be sent again, with an increasing
      interval, including only 25 attempts, the last one at the end of the day.


      ## Payment notification example


      <SchemaDefinition schemaRef="#/components/schemas/InvoiceCallBack" />


      ## Refund notification example


      <SchemaDefinition schemaRef="#/components/schemas/RefundCallBack" />


      ## Example of Python code to verify the signature of a request


      The algorithm implemented below on the example of a server payment
      notification is the same for a server refund notification.


      ```python

      # Resulting notification string (in format application/json)

      request_body_json = """
          {
            "shop_id": 1,
            "shop_order_id": "The store's order ID",
            "description": "Your payment description",
            "shop_amount": 100.0,
            "shop_refund": 19.0,
            "shop_currency": 840,
            "payment_id": 1234,
            "client_price": 100.0,
            "ps_currency": "840",
            "payway": "payway_example",
            "ps_data": "{\\"amount\\": \\"20.00\\", \\"bill_id\\": \\"i_100\\", \\"ccy\\": \\"USD\\", \\"command\\": \\"bill\\", \\"comment\\": \\"[i_100] Payment\\", \\"error\\": 0, \\"prv_name\\": \\"PaymentSystem\\", \\"ps_payer_account\\": \\"150010000097\\", \\"status\\": \\"paid\\", \\"user\\": \\"tel:+150010000097\\"}",
            "created": "2026-08-27T15:38:07",
            "updated": "2026-08-27T15:38:07",
            "status": "success",
            "addons": "{\\"callback_rejected_url\\": \\"https://some-shop.com/callback-rejected-url\\", \\"callback_url\\": \\"https://some-shop.com/callback-url\\", \\"description\\": \\"Some payment\\", \\"failed_url\\": \\"https://some-shop.com/fail\\", \\"phone\\": \\"150010000097\\", \\"success_url\\": \\"https://some-shop.com/success\\"}",
            "sign": "26bcafa4b08dcfa901e47caa977c75ed286bb4390fb8271eb96e2f46470ffbf7"
      }"""


      import json

      parsed_request = json.loads(request_body_json)


      # Resulting notification string (in format
      application/x-www-form-urlencoded)

      if content_type == 'application/x-www-form-urlencoded':
          request_body_form_urlencoded = (
              'shop_id=1&shop_order_id=The+store's+order+ID&description=Your+payment+description&s'
              'hop_amount=20.0&shop_refund=19.0&shop_currency=840&payment_id=100&'
              'client_price=20.0&ps_currency=840&payway=payway_example&ps_data='
              '%7B%22amount%22%3A+%2220.00%22%2C+%22bill_id%22%3A+%22i_100%22%2C+'
              '%22ccy%22%3A+%22USD%22%2C+%22command%22%3A+%22bill%22%2C+%22commen'
              't%22%3A+%22%5Bi_100%5D+Payment%22%2C+%22error%22%3A+0%2C+%22prv_na'
              'me%22%3A+%22PaymentSystem%22%2C+%22ps_payer_account%22%3A+%2297151'
              '0000000%22%2C+%22status%22%3A+%22paid%22%2C+%22user%22%3A+%22tel%3'
              'A%2B150010000097%22%7D&created=2026-08-27T15%3A38%3A07&updated=202'
              '0-08-21T15%3A38%3A07&status=success&addons=%7B%22callback_rejected'
              '_url%22%3A+%22https%3A%2F%2Fsome-shop.com%2Fcallback-rejected-url%'
              '22%2C+%22callback_url%22%3A+%22https%3A%2F%2Fsome-shop.com%2Fcallb'
              'ack-url%22%2C+%22description%22%3A+%22Some+payment%22%2C+%22failed'
              '_url%22%3A+%22https%3A%2F%2Fsome-shop.com%2Ffail%22%2C+%22phone%22'
              '%3A+%22150010000097%22%2C+%22success_url%22%3A+%22https%3A%2F%2Fso'
              'me-shop.com%2Fsuccess%22%7D&sign=26bcafa4b08dcfa901e47caa977c75ed2'
              '86bb4390fb8271eb96e2f46470ffbf7'
          )
          from urllib.parse import parse_qsl
          parsed_request = dict(parse_qsl(request_body_form_urlencoded))

      print(parsed_request)

      # {

      #     'shop_id': 100,

      #     'shop_order_id': 'The store's order ID',

      #     'description': 'Some payment',

      #     'shop_amount': 20.0,

      #     'shop_refund': 19.0,

      #     'shop_currency': 840,

      #     'payment_id': '100',

      #     'client_price': 20.0,

      #     'ps_currency': 840,

      #     'payway': 'payway_example',

      #     'ps_data': '{"amount": "20.00", "bill_id": "i_100", "ccy": "USD",
      "command": "bill", "comment": "[i_100] Payment", "error": 0, "prv_name":
      "PaymentSystem", "ps_payer_account": "150010000097", "status": "paid",
      "user": "tel:+150010000097"}',

      #     'created': '2026-08-27T15:38:07',

      #     'updated': '2026-08-27T15:38:07',

      #     'status': 'success',

      #     'addons': '{"callback_rejected_url":
      "https://example.com/callback-rejected-url", "callback_url":
      "https://example.com/callback-url", "description": "Your payment
      description", "failed_url": "https://example.com/fail", "phone":
      "150010000097", "success_url": "https://example.com/success"}',

      #     'sign':
      '5d3ea83ec487fb1a769942b348741eafa5b124073d9bca968977731b724ee397',

      # }


      # Let's get a list of sorted keys for signature generation

      keys = sorted(parsed_request)


      # Let's remove the signed key from them.

      keys.remove('sign')


      print(keys)

      # This is how the resulting list will look like

      #     ['addons',

      #      'client_price',

      #      'created',

      #      'description',

      #      'payment_id',

      #      'payway',

      #      'ps_currency',

      #      'ps_data',

      #      'shop_amount',

      #      'shop_currency',

      #      'shop_id',

      #      'shop_order_id',

      #      'shop_refund',

      #      'status',

      #      'updated']


      # Let's compose a line using the sorted key values obtained in the
      previous step

      values_to_sign = []

      for k in keys:
          if parsed_request[k] != '' and parsed_request[k] is not None:
              values_to_sign.append(str(parsed_request[k]))

      # Let's form the final signature and check its value with the value
      received in the response

      string_to_sign = ':'.join(values_to_sign) + '<secret_key_here>'

      import hashlib

      sign = hashlib.sha256(string_to_sign.encode()).hexdigest()

      assert sign == parsed_request['sign']

      ```
  - name: invoice-recurrent
    x-displayName: Recurrent invoice
    description: >
      <div class="attention">This feature is available only after approval by
      the manager.</div>


      You can withdraw funds regularly from the payment instrument of the buyer
      without repeated entry of details and without participation of the payer
      to initiate the next payment. With such way of funds withdrawal the user
      should only confirm the first payment or linking of the payment
      instrument, all subsequent payments will be made without his/her
      participation.


      To create the first payment in the chain and to generate the payment
      token, pass `issue_payment_token: true` in
      [invoice/create](/api-reference/invoice-create/invoice-issue) or
      [invoice/hold](/api-reference/invoice-create/funds-hold-two-stage-payments).


      You will then receive a [notification](/callbacks) with `payment_token`
      inside `ps_data`. Save that token for subsequent charges.


      <div class="warning">Parameter <strong>payment_token</strong> is sent only
      after a successful transaction.</div>


      For each following payment, submit `payment_token: "<payment token>"` in
      [invoice/create](/api-reference/invoice-create/invoice-issue). The
      response may return `method: null` and `url: null` when no redirect to the
      payment page is required; the final result arrives via
      [notification](/callbacks).
  - name: invoice-statuses
    x-displayName: Invoice statuses
    description: >
      List of possible statuses of the created invoice.


      | Numerical identifier |
      Description                                          | Final     |

      |:-----:|---------------------------------------------------------------------|:---------:|

      |  1    | Payment request has been
      created                                    | &minus;   |

      |  2    | Payment is awaiting user
      action                                     | &minus;   |

      |  3    | Payment system has failed to create the
      payment                     | &minus;   |

      |  4    | Payment has been
      successful                                         | &plus;    |

      |  5    | Payment system has failed to receive a payment
      notice               | &minus;   |

      |  6    | M4 payment system has rejected the operation               |
      &plus;    |

      |  8    | Funds for the invoice are withheld (held) by the payment
      system     | &minus;   |
  - name: withdraw-create
    x-displayName: Payout creation
    description: >
      ### Process of shop payouts generation is as follows:


      ![Withdraw Flow Diagram](assets/common/images/en/withdraw-flow.v1.png)


      1. Shop executes a request for a preliminary calculation and receiving
      additional parameters for further creation of the payout using the method
      [withdraw/try](/api-reference/withdraw-create/payout-preliminary-calculation);


      2. If `result: true`, the shop sends request for a preliminary check of
      the existence and possibility of adding funds to the account
      [check_account](/api-reference/withdraw-create/checking-the-account-for-the-possibility-of-replenishment),
      to the specified payment way (if necessary, specify additional parameters
      obtained from the previous request from the `account_info_config` field);


      3. If `result: true`, verify availability of additional information in the
      `account_info` field, if available, it is necessary to pass additional
      parameters in the payout creation request. When getting `result: false`,
      analyse the error code in the `error_code` field (see [description of
      error codes](/errors-list)). If the `error code` is not fatal, then you
      need to start requesting the status of the transaction after a certain
      time (for 2 hours at 30-second intervals). If the `error code` is fatal
      the communication with our API is over.


      4. Shop submits a request for payout creation
      [withdraw/create](/api-reference/withdraw-create/payout-creation),
      specifying the required parameters and additional information from
      `account_info` (if it is required for the specified payment way);


      5. The response returns information with the generated payout request and
      indicating the amounts and the payout ID. In this case, the part of the
      balance of the shop from which the payout is made is frozen until the
      final payout status.


      6. After payout creation, it is necessary to make a request to get the
      status of the created payout
      [withdraw/status](/api-reference/withdraw-create/payout-status-request-by-id-of-the-payout-created-in-m4-system)
      or
      [withdraw/shop_payment_status](/api-reference/withdraw-create/payout-status-request-by-the-shop-payout-number),
      before receiving the final status.


      <div class="attention">

      Status requests are recommended to be made at 30-second intervals.

      </div>


      7. After final status is received, the payout is considered completed, and
      the funds are debited from the shop's balance (or returned to the balance
      if the payout was not completed).


      ### Guidelines for creation and verification of payout requests


      If you received `result: true` after creating the payout, you should
      immediately check the `data.status` field, perhaps there will already be a
      final [status](/withdraw-statuses), for example `6 (Rejected)` and in this
      case, you do not need to make a request for the payout status.


      If you receive the `Read timeout` error at the payout creation request,
      then you need to make a status request by the shop's payout number
      [withdraw/shop_payment_status](/api-reference/withdraw-create/payout-status-request-by-the-shop-payout-number)
      and if the response returns an error stating the absence of such a payout,
      you can repeat the request to create a payout. If the payout status is
      returned in the response, then it means that it was created and you need
      to focus on this status.


      Reason for payout rejection ([getting status 6](/withdraw-statuses)) can
      be clarified through the support service <a
      href="mailto:support@m4psp.com">support@m4psp.com</a>.


      ### Securing payouts idempotency


      <div class="warning">

      System has duplication protection for payouts,
      <code>shop_payment_id</code> must be unique within a single shop.

      </div>
  - name: withdraw-statuses
    x-displayName: Payout statuses
    description: >
      If the payout has been successfully created, the response will contain a
      unique payment identifier and its status.


      The status can be final and non-final, for non-final status, you must make
      a status request before receiving the final status.


      | Numerical identifier | Description                        | Final   |

      |:-----:|---------------------------------------------------|:--------:|

      |  1    | Payout has been created, awaits processing        | &minus; |

      |  3    | Sent to the payment system                        | &minus; |

      |  4    | Payout error on the part of the payment system    | &minus; |

      |  5    | Successfully completed                            | &plus;  |

      |  6    | Rejected by the payment system                    | &plus;  |

      |  9    | Network error on the part of the payment system   | &minus; |
  - name: other-shop-methods
    x-displayName: Other shop methods
    description: |
      ### Other methods available for the shop
  - name: errors-list
    x-displayName: List of possible errors
    description: >
      ### List of possible M4 API errors


      You can use this data to control the logic of your application, analyze
      and solve problems, output messages

      to the user, and for any other purpose. For example, if you received
      `error_code: 11` in the response, then most likely you

      incorrectly specified the value of the `shop_id` parameter in the request
      body.


      If you receive `result: false` in the response, this means that an error
      occurred, and the transaction was either not created (

      for example, in case of request body validation error), or ended with an
      error (for example, the payment system returned an error when

      trying to perform a transaction). If the `error code` is not fatal, then
      you need to wait for the [server notification](/callbacks) (applies to
      [invoice](/invoice-create) or [refund](/invoice-refund) transactions) or
      after a certain time start requesting the status of the transaction
      (applies to [payout](/withdraw-create) transactions) (for 2 hours at
      30-second intervals). If the `error code` is fatal the communication with
      our API is over.


      If you receive `result: true` in response, it means that the transaction
      was created successfully. If the transaction status in the synchronous

      response is not final (or is absent for some types of transactions), then
      you need

      to wait for the [server notification](/callbacks) or after a certain time
      start requesting the status

      of the transaction (applies only to [payout](/withdraw-create)
      transactions). After receiving the final status of the transaction,

      the communication with our API is over.


      | Error code |
      Description                                                                                                                                                                        
      |  Fatal  |

      |------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------:|

      | 1          | Payway has not been
      found                                                                                                                                                          
      | &plus;  |

      | 2          | Payway is not
      active                                                                                                                                                               
      | &plus;  |

      | 3          | Payway is not
      available                                                                                                                                                            
      | &plus;  |

      | 4          | The specified amount is too small (payway
      restriction)                                                                                                                             
      | &plus;  |

      | 5          | The specified amount is too big (payway
      restriction)                                                                                                                               
      | &plus;  |

      | 6          | A non-unique operation identifier has been transferred on
      the part of the
      shop                                                                                                     
      | &plus;  |

      | 7          | Operation has not been
      found                                                                                                                                                       
      | &plus;  |

      | 8          | Operation is being
      processed                                                                                                                                                       
      | &plus;  |

      | 9          | Insufficient
      balance                                                                                                                                                               
      | &plus;  |

      | 10         | Invalid request
      parameters                                                                                                                                                         
      | &plus;  |

      | 11         | Shop has not been
      found                                                                                                                                                            
      | &plus;  |

      | 12         | Shop is not
      active                                                                                                                                                                 
      | &plus;  |

      | 13         | Account has not been found in M4
      system                                                                                                                                    
      | &plus;  |

      | 14         | Account status does not allow
      operations                                                                                                                                           
      | &plus;  |

      | 15         | Request from the current IP has been
      rejected                                                                                                                                      
      | &plus;  |

      | 16         | Currency exchange rate has not been
      found                                                                                                                                          
      | &plus;  |

      | 17         | Invalid contract type for the
      shop                                                                                                                                                 
      | &plus;  |

      | 18         | Invalid account
      type                                                                                                                                                               
      | &plus;  |

      | 19         | Unable to perform operation for shop with the status of an
      aggregator                                                                                                              
      | &plus;  |

      | 20         | Invalid project
      ID                                                                                                                                                                 
      | &plus;  |

      | 21         | Project is
      inactive                                                                                                                                                                
      | &plus;  |

      | 22         | Invalid shop
      currency                                                                                                                                                              
      | &plus;  |

      | 23         | Account deposit limit
      exceeds                                                                                                                                                      
      | &plus;  |

      | 24         | Invalid payee
      balance                                                                                                                                                              
      | &plus;  |

      | 25         | Zero amount is
      specified                                                                                                                                                           
      | &plus;  |

      | 26         | Amount is less than
      zero                                                                                                                                                           
      | &plus;  |

      | 27         | Daily limit has been
      exceeded                                                                                                                                                      
      | &plus;  |

      | 40         | Operation with specified BIN is
      restricted                                                                                                                                         
      | &plus;  |

      | 41         | Transaction to this payment instrument is
      forbidden                                                                                                                                
      | &plus;  |

      | 100        | Operation has an invalid
      status                                                                                                                                                    
      | &plus;  |

      | 101        | Unable to refund since the invoice has a status other than
      Success
      (4)                                                                                                             
      | &plus;  |

      | 102        | Refund amount exceeds the available refund
      amount                                                                                                                                  
      | &plus;  |

      | 103        | Transaction for this payment method is not
      supported                                                                                                                               
      | &plus;  |

      | 104        | Cannot execute a refund because an incomplete refund
      already exists. Wait for the current refund to complete before creating a
      new one.                                             | &plus;  |

      | 1001       | Payment system is unable to process the request now. Please
      try again
      later.                                                                                                       
      | &minus; |

      | 1002       | Payment system has returned the "Access error" status.
      Please contact the payment system for further
      information.                                                                  
      | &plus;  |

      | 1003       | Invalid request parameters. Please verify the accuracy of
      the payment details and retry the request
      later.                                                                         
      | &plus;  |

      | 1004       | The payment amount is less or greater than the allowed
      limit. Please ensure that the payment amount complies with the
      requirements of the payment system or bank.                   | &plus;  |

      | 1005       | The transaction limit has been exceeded. Please contact
      bank or the payment system to get information about the reasons for
      reaching the transaction limit.                         | &plus;  |

      | 1006       | The account was not found in the payment system. Please
      check the correctness of the entered data and retry the
      request.                                                            |
      &plus;  |

      | 1007       | An error occurred in the payment system. Request the status
      of the transaction or wait for a server
      notification.                                                                  
      | &minus; |

      | 1008       | Insufficient funds in the account to process the payment.
      Please ensure that there are sufficient funds in the account and retry the
      request.                                       | &plus;  |

      | 1009       | Insufficient identification status of the
      wallet                                                                                                                                   
      | &plus;  |

      | 1010       | The account is blocked. Request information about the
      reasons for the blockage and the actions required to unblock the account
      in the payment system or use an alternative account. | &plus;  |

      | 1011       | Operation is forbidden by a payment system. Please contact
      the payment system for further
      information.                                                                             
      | &plus;  |

      | 1012       | Operation is rejected by payment system. Please contact the
      payment system for further
      information.                                                                                
      | &plus;  |

      | 1013       | Account is locked in payment
      system                                                                                                                                                
      | &minus; |

      | 1014       | Incorrect data in request
      parameters                                                                                                                                               
      | &minus; |

      | 1015       | Transaction lifetime was
      expired                                                                                                                                                   
      | &plus;  |

      | 1016       | The operation has been declined by the payment system. The
      user has an unpaid transaction that needs to be either declined or
      completed.                                            | &plus;  |

      | 1017       | The specified currency for the operation is unavailable.
      Please contact the payment system for information on the available
      currencies.                                             | &plus;  |

      | 1018       | No suitable options were found for the transaction. Please
      try again
      later.                                                                                                        
      | &plus;  |

      | 1019       | The user did not confirm or cancel the operation. Please
      try again
      later.                                                                                                          
      | &plus;  |

      | 1020       | The transaction failed KYT
      verification.                                                                                                                                           
      | &plus;  |

      | 1100       | Invalid CVV/CVC code. Please verify the accuracy of the
      entered CVV/CVC code on the back of the credit
      card.                                                                       
      | &plus;  |

      | 1101       | Suspicion of fraudulent activity. Please contact the
      payment system or bank for further
      information.                                                                               
      | &plus;  |

      | 1102       | The operation has been rejected by the payment system.
      Please verify the accuracy of the payment details and retry the request
      later.                                               | &plus;  |

      | 1103       | The operation has been rejected by the bank. Please contact
      the bank to determine the reason for the
      rejection.                                                                    
      | &plus;  |

      | 1104       | The operation with this payment instrument is prohibited.
      Please contact bank or the payment system for information on the reasons
      for the prohibition.                             | &plus;  |

      | 1105       | The card has expired. Please check the expiration date of
      the card provided during the payment. If the card has indeed expired,
      please use a card with a valid expiration date.     | &plus;  |

      | 1106       | Invalid card number. Please check the correctness of the
      entered number and retry the
      request.                                                                                     
      | &plus;  |

      | 1107       | 3D-Secure authentication is required. Please contact the
      payment system or bank for additional
      information.                                                                        
      | &plus;  |

      | 1108       | The payment token has expired. Obtain a new token and retry
      the
      request.                                                                                                           
      | &plus;  |

      | 1109       | Transaction rejected by MPI. Please repeat the payment
      using another bank
      card.                                                                                                    
      | &plus;  |

      | 2000       | Another
      error                                                                                                                                                                      
      | &plus;  |
paths:
  /invoice/get-refunds:
    post:
      tags:
        - invoice-refund
      summary: Invoice refund status
      description: |-
        To get status and up-to-date information on refunds.

        <div class="success">
        <p>Fields involved in request signature generation:</p>

        * `invoice_id`
        * `now`
        * `shop_id`
        </div>
      operationId: post-invoice-get-status-refunds
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InvoiceRefundStatusPayload.v1'
      responses:
        '200':
          description: ''
          x-summary: OK
          content:
            application/json:
              schema:
                oneOf:
                  - title: Refund is successfully created
                    allOf:
                      - $ref: '#/components/schemas/ResponseOK.v1'
                      - properties:
                          data:
                            type: array
                            description: >-
                              Information about created refund operations for
                              the specified invoice
                            items:
                              allOf:
                                - $ref: >-
                                    #/components/schemas/InvoiceRefundStatusResponse.v1
                  - $ref: '#/components/schemas/ResponseFail.v1'
      security:
        - Request signature: []
components:
  schemas:
    InvoiceRefundStatusPayload.v1:
      title: Get refund status
      allOf:
        - $ref: '#/components/schemas/ShopID.v1'
        - $ref: '#/components/schemas/InvoiceID.v1'
        - $ref: '#/components/schemas/Now.v1'
      required:
        - shop_id
        - invoice_id
        - now
    ResponseOK.v1:
      title: Successful response
      type: object
      allOf:
        - $ref: '#/components/schemas/Response.v1'
        - properties:
            result:
              example: true
            message:
              example: Ok
            error_code:
              example: 0
    InvoiceRefundStatusResponse.v1:
      title: Information about the created refund transaction
      allOf:
        - $ref: '#/components/schemas/ShopRefundID.v1'
        - $ref: '#/components/schemas/RefundStatus.v1'
        - $ref: '#/components/schemas/InvoiceID.v1'
        - properties:
            amount:
              $ref: '#/components/schemas/RefundAmount.v1'
            currency:
              $ref: '#/components/schemas/RefundCurrency.v1'
            error_code:
              $ref: '#/components/schemas/ErrorCode.v1'
            created_at:
              type: string
              description: Date and time when the refund was created
              format: date-time
              example: '2026-05-24T16:35:42'
            processed_at:
              nullable: true
              type: string
              description: >-
                Date and time of actual processing of the refund in the payment
                system
              format: date-time
              example: '2026-04-21T20:08:02'
            settlement_amount:
              type: string
              minimum: 0
              description: >-
                Amount of write-off from the shop balance, in currency
                `settlement_currency`
              example: '95.50'
            settlement_currency:
              type: string
              description: >-
                Shop balance currency. Alphabetic currency identifier in
                accordance with [ISO 4217](https://wikipedia.org/wiki/ISO_4217).
              example: USD
            settlement_rate:
              type: string
              format: float
              nullable: true
              description: Exchange rate
              example: null
          required:
            - amount
            - currency
            - status
            - invoice_id
            - shop_refund_id
            - created_at
            - processed_at
            - error_code
            - settlement_amount
            - settlement_currency
            - settlement_rate
    ResponseFail.v1:
      title: Error response
      type: object
      description: |
        # Error response 😎
      allOf:
        - $ref: '#/components/schemas/Response.v1'
        - properties:
            data:
              type: object
              example: null
              nullable: true
            result:
              example: false
            message:
              example: Shop (id = 1520) is not found
            error_code:
              example: 12
    ShopID.v1:
      type: object
      title: Shop ID
      properties:
        shop_id:
          type: integer
          example: 1520
          description: Unique shop identifier in the M4 system.
      required:
        - shop_id
    InvoiceID.v1:
      title: Payment ID
      type: object
      properties:
        invoice_id:
          type: number
          description: Invoice ID in the M4 system.
          format: integer
          example: 108744
      required:
        - invoice_id
    Now.v1:
      title: Request date and time
      type: object
      properties:
        now:
          type: string
          format: date-time
          example: '2026-05-24T16:35:42'
          description: Request date and time.
      required:
        - now
    Response.v1:
      title: API response
      type: object
      properties:
        result:
          type: boolean
          description: >-
            Boolean value, in case of successful response it will be `true`, in
            case of error – `false`
        message:
          type: string
          description: A textual description of the error, in case of success - simply `Ok`
        error_code:
          type: number
          description: >-
            If this value is greater than `0`, then the request ended with an
            error. [Description of error codes](/errors-list)
      required:
        - data
        - error_code
        - message
        - result
      description: ''
    ShopRefundID.v1:
      type: object
      title: Identifier sent by the shop
      properties:
        shop_refund_id:
          type: string
          example: dc4ad503-d97a-4fec-adeb-ba51d43a7191
          description: The refund ID in your system. *Must be unique for each new refund.*
          maxLength: 255
      required:
        - shop_refund_id
    RefundStatus.v1:
      title: Refund status on receipt of callback
      type: object
      properties:
        status:
          type: string
          example: SUCCESS
          description: |-
            Refund status:
            * `WAITING` - return in process;
            * `SUCCESS` - return successfully processed;
            * `FAILED` - the return has not been processed.
          enum:
            - WAITING
            - SUCCESS
            - FAILED
    RefundAmount.v1:
      title: Refund amount
      type: string
      description: |
        Refund amount, calculated in `currency`.
      example: '95.50'
      exclusiveMinimum: true
      minimum: 0
    RefundCurrency.v1:
      type: string
      x-examples:
        Dollars: USD
        Euro: EUR
      description: >-
        Alphabetic currency identifier in accordance with [ISO
        4217](https://wikipedia.org/wiki/ISO_4217).
      enum:
        - USD
        - EUR
      title: Currency identifier
      example: USD
    ErrorCode.v1:
      title: M4 API error code
      type: number
      format: integer
      example: 0
      description: >-
        M4 API error code. `0` in cases there is no any error. Other codes can
        be found here: [Description of error codes](/errors-list)
      required:
        - error_code
  securitySchemes:
    Request signature:
      type: apiKey
      in: requestBody
      name: sign
      description: >+
        Every API request must be signed so that we can identify your account.


        The signature is transferred in the request body through the `sign`
        parameter, for example:


        ```json

        {
            "shop_id": 1520,
            "shop_order_id" : "5b0efa8a-153b-4421-abac-2aba4d772a86",
            "amout": "6320.91",
            "currency": 840,
            "payway": "card_invoice_usd",
            "description": "Payment for shop_id=1520",
            "sign": "77a6f7a30876d480d4e771d08cb83800dd5cb874664c77e515ffc052b20293c6"
        }

        ```

        <div class="warning">

        All further request examples do not include the <code>"sign"</code>
        parameter, nevertheless your real requests <strong>must</strong> include
        it in the request body where required.

        </div>


        Signature line is generated according to the following algorithm: all
        request parameters involved in signature generation are ordered in the
        alphabetical order of keys, the values are concatenated with a colon
        (":") and the account secret key is added at the end (without the:
        `sign`), a sha256 hash is generated from the resulting line and its hex
        representation is passed in the sign request parameter.


        ### Example of signature generation for a method
        [invoice/create](/api-reference/invoice-create/invoice-issue):


        1. Determining the list of parameters. It looks as follows for the
        method in consideration:


        <div class="success">

        <p>Fields involved in request signature generation:</p>


        * `shop_id`

        * `shop_order_id`

        * `amount`

        * `currency`

        * `payway`

        </div>


        2. Let's sort keys in alphabetical sequence:


        `"amount", "currency", "payway", "shop_id", "shop_order_id"`


        3. The line for generating the SHA256 hash will be as follows:


        `"6320.91:840:card_invoice_usd:1520:5b0efa8a-153b-4421-abac-2aba4d772a86account-secret-key"`


        Where `account-secret-key` is the secret identification key for your
        account. You can request a key from the support service.


        4. Let's get a hash expression of the generated line using Python code:


        ```python

        >>> string_to_sign =
        '6320.91:840:card_invoice_usd:1520:5b0efa8a-153b-4421-abac-2aba4d772a86account-secret-key'

        >>> import hashlib

        >>> sign = hashlib.sha256(string_to_sign.encode()).hexdigest()

        >>> print(sign)

        '77a6f7a30876d480d4e771d08cb83800dd5cb874664c77e515ffc052b20293c6'

        ```


        <div class="success">

        You can check whether you have generated the signature correctly using
        the service <a
        href="https://www.xorbin.com/tools/sha256-hash-calculator">https://www.xorbin.com/tools/sha256-hash-calculator</a>.

        </div>


````