Интеграция API

Наша система реализует двухэтапный (H2H) процесс, когда весь пользовательский интерфейс и логика отображения находятся на стороне мерчанта. Это обеспечивает максимальную гибкость в дизайне интерфейса и контроле за процессом оплаты.

Платежный флоу представлен на диаграмме ниже:

Платежный флоу

Шаг 1. Аутентификация и управление токенами

Прежде чем отправлять запросы к API, необходимо аутентифицироваться и получить JWT‑токен. Токен используется для идентификации вашего сервис‑аккаунта при каждом запросе.

  1. Получение access_token
  2. Обновление токена с помощью refresh_token

1. Пример получения access_token

Запрос:

curl -X POST https://api.payler.one/v2/auth/token \
     -H "Content-Type: application/json" \
     -d '{"account_id":"YOUR_ACCOUNT_ID","public_key":"BASE64_PUBLIC_KEY"}'

Что происходит:

  • API проверяет account_id и public_key.
  • Возвращает access_token, refresh_token и expires_in.

Описание полей:

  • account_id: uuid (required) — account_id из файла credentials.json
  • public_key: string (required) — public_key из файла credentials.json

Ответ:

  • Status 200:

    {   
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",   
    "refresh_token": "8xLOxBatCN8fDrMHtkX1uDgeHxWxhoJDl...",   
    "expires_in": 3600 
    }   
    

  • Status 400:

    {
    "error": "ERROR_INVALID_PUBLIC_KEY", 
    "message": "Public key is invalid", 
    "statusCode": 400 
    }
    

  • Status 404:

    {
    "error": "ERROR_INVALID_CREDENTIALS", 
    "message": "Credentials are invalid or account not found", 
    "statusCode": 404 
    }
    

2. Обновление токена с помощью refresh_token

Этот эндпоинт позволяет обновить access_token с использованием действующего refresh_token. Обновлённый токен необходимо использовать для последующих API-запросов, чтобы сохранить доступ. Убедитесь, что refresh_token всё ещё действителен и не истёк.

Запрос:

curl -X POST https://api.payler.one/v2/auth/token/refresh \
     -H "Authorization: Bearer <ACCESS_TOKEN>" \
     -H "Content-Type: application/json" \
     -d '{"refresh_token":"REFRESH_TOKEN"}'

Описание полей:

  • access_token: string (required) — Authorization: Bearer
  • refresh_token: string (required) — refresh_token для обновления access_token

Разбор ответа:

  • Status 200:

    {   
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",   
    "refresh_token": "8xLOxBatCN8fDrMHtkX1uDgeHxWxhoJDl...",   
    "expires_in": 3600 
    }   
    

  • Status 400:

    {
    "error": "ERROR_REFRESH_TOKEN_INVALID", 
    "message": "Refresh token is invalid. Use a valid refresh token.", 
    "statusCode": 400 
    }
    

  • Status 401:

    {
    "error": "ERROR_REFRESH_TOKEN_EXPIRED", 
    "message": "Refresh token has expired.", 
    "statusCode": 401 
    }
    

Шаг 2. Получение обменного курса для клиента

На этом шаге выполняется расчет курса обмена и определение конечной стоимости для клиента.

В качестве параметров запроса передается базовая валюта (валюта клиента) и валюта получателя. В некоторых случаях дополнительно необходимо передать тип платежного метода — подробнее в разделе «Платежные методы».

Запрос:

curl -X POST https://api.payler.one/v2/rate \
     -H "Authorization: Bearer <ACCESS_TOKEN>" \
     -H "Content-Type: application/json" \
     -d '{"currency_from":"RUB", "currency_to": "AZN", "amount": 1000.25}'

Описание полей:

  • currency_from: string (required) - ISO код валюты клиента или в какой валюте будет происходить расчет
  • currency_to: string (required) - ISO код валюты получателя платежа
  • amount: number, float (required) - исходная сумма для обмена в валюте currency_from
  • subtype: string (optional) - Метод исполнения выплатной транзакции

Разбор ответа:

  • Status 200:

    {
        "id": "be9675e3-bd27-4d8b-a10f-4b357803f4c8",
        "finalAmount": 3404.23,
        "direction": 'FIAT_OUT',
        "fullRate": 443.2214,
        "fullRateReverse": 0.01241,
        "fees": 0,
        "fees_percent": 0,
        "expiredAt": "2025-05-13T18:57:27.489Z"
    }
    

    • id: (uuid) - Уникальный ID запроса, используется для следующего шага оплаты;
    • finalAmount: (number, float) - Сумма к получению в локальной валюте (currencyFrom);
    • direction: (string) - Направление обмена, служебное поле, принимает одно из значений: C2F, FIAT_OUT;
    • fullRate: (number, float) - Полный курс обмена для конечного клиента, 4 десятичных знака;
    • fullRateReverse: (number, float) - Обратный курс обмена;
    • fees: (number, float) - Сумма комиссий за обмен в валюте currencyFrom;
    • fees_percent: (number, float) - Процентная ставка комиссии за обмен;
    • expiredAt: (date-time) - Дата и время, до которого можно создать платеж по текущей сессии;
  • Status 400: Authentication failed. Access token is invalid.

    {
    "error": "ERROR_ACCESS_TOKEN_INVALID", 
    "message": "Access token is invalid.", 
    "statusCode": 400 
    }
    

    • error: string (required)
    • message: string (required)
    • statusCode: number
  • Status 401: Authentication failed. Access token has expired.

    {
    "error": "ERROR_TOKEN_EXPIRED", 
    "message": "Access token has expired.", 
    "statusCode": 401 
    }
    

  • Status 400: Currency not supported

    {
    "error": "ERROR_CURRENCY_FROM_INVALID", 
    "message": "Use only valid currency (id or symbol)", 
    "statusCode": 400 
    }
    

    • error: string (required)
    • message: string (required)
    • statusCode: number
  • Status 400: Direction not supported

    {
    "error": "ERROR_EXCHANGE_DIRECTION_STOPPED", 
    "message": "Exchange direction isn`t available right now", 
    "statusCode": 400 
    }
    

    • error: string (required)
    • message: string (required)
    • statusCode: number
  • Status 500: Project tariff not configured, pls contact with our support.

    {
      "error": "TARIFF_NO_FOUND",
      "message": "Project tariff not configured, pls contact with our support.",
      "statusCode": 500
    }
    

    • error: string (required)
    • message: string (required)
    • statusCode: number

Шаг 3. Получение списка банков для клиента

На этом шаге выполняется получение списка доступных банков по указанной валюте для выбора клиентом банка получателя.

В качестве параметра запроса передается валюта (ID или символ валюты), для которой нужно получить банки.

Запрос:

curl -X GET 'https://api.payler.one/v2/banks?currency=KZT' \
     -H "Authorization: Bearer <ACCESS_TOKEN>" \
     -H "Content-Type: application/json" \
     -d '{"currency":"KZT"}'

Описание полей:

  • currency: string (required) - ID или символ валюты (ISO код), пример: KZT

Разбор ответа:

  • Status 200:

    {
      "banks": [
        {
          "id": "e7de10cf-c773-4007-b288-842db239a26b",
          "name": "Kaspi",
          "country_code": "KZ"
        }
      ]
    }
    

    • banks (array): Список доступных банков
      • id (string, uuid): Уникальный ID банка, используется для дальнейших операций;
      • name (string): Название банка;
      • country_code (string, optional): Код страны банка (ISO 3166-1 alpha-2);
  • Status 400: Authentication failed. Access token is invalid.

    {
      "error": "ERROR_ACCESS_TOKEN_INVALID", 
      "message": "Access token is invalid.", 
      "statusCode": 400 
    }
    

    • error: string (required)
    • message: string (required)
    • statusCode: number
  • Status 401: Authentication required

    {
      "error": "ERROR_AUTHENTICATION_REQUIRED", 
      "message": "This method can only be accessed with authentication", 
      "statusCode": 401 
    }
    

    • error: string (required)
    • message: string (required)
    • statusCode: number
  • Status 401: Authentication failed. Access token has expired.

    {
      "error": "ERROR_TOKEN_EXPIRED", 
      "message": "Access token has expired", 
      "statusCode": 401 
    }
    

    • error: string (required)
    • message: string (required)
    • statusCode: number

Шаг 4. Финализация платежа

В двухэтапной парадигме ожидается, что на первом шаге клиент видит финальную ставку для себя и принимает решение о необходимости перевода, если он соглашается с условиями, мерчант присылает запрос на финализацию платежа c деталями о получателе и отправителя.

Запрос:

curl -X POST https://api.payler.one/v2/payout \
     -H "Authorization: Bearer <ACCESS_TOKEN>" \
     -H "Content-Type: application/json" \
     -d '{"quoteId":"<QUOTE_ID>","invoiceId":"<INVOICE_ID>", "clientId": "<CLIENT_ID>", "recipient": {"account_number": "4210090401235566","account_owner": "Card Holder", "type": "card"}}'
  • quoteId: string (required) — Идентификатор, полученный на этапе /v2/rate
  • invoiceId: string (required) — Внутренний номер инвойса мерчанта
  • clientId: string (optional) — Идентификатор клиента в системе мерчанта
  • type: string (optional) — Способ исполнения выплаты (платежный метод), по умолчанию p2p, применяется только в случае, если выплата идет на кошелек.
  • recipient: Object (required) — Данные получателя платежа
    • account_number: string (required) — Номер счета получателя (в этом поле передается основной реквизит получателя, например если перевод будет по номеру карты, то тут передается именно ее номер. Тип реквизита определяется в поле ниже)
    • account_owner: string (required) — Имя владельца номера счета (имя получателя)
    • account_iban: string (optional) — IBAN получателя, в случае если это НЕ основной реквизит а дополнительный
    • account_phone: string (optional) — Телефон получателя, в случае если это дополнительный реквизит, а не основной
    • account_email: string (optional) — Email получателя
    • account_ewallet_name: string (optional) — Название кошелька получателя
    • account_bank_id: string (optional) — ID банка, полученный на этапе /banks
    • account_bic: string (optional) — BIC/SWIFT получателя
    • account_internal_client_number: string (optional) — Bank internal identifier used for method banktransferphp
    • type: string (required) — Тип реквизита, который используется в качестве основного счета получателя. Может принимать одно из следующих значений: iban, phone, card, account, custom
  • sender_personal: Object (optional) — Данные отправителя платежа для KYC
    • name: string (required) — Фамилия и имя отправителя
    • birthday: string (optional) — Дата рождения отправителя в любом формате
    • phone: string (optional) — Номер телефона отправителя в международном формате
    • address: string (optional) — Адрес отправителя
    • passport: string (optional) — Номер удостоверения личности отправителя

Info

Для большинства выплат (на карты, IBAN, номер банковского счета либо по номеру телефона) type не указывается. Для выплат на кошельки используется recipient.type = custom и передается type в соответствии с типом кошелька.

Info

Необходимость передачи персональных данных и их состав в поле sender_personal устанавливается в рамках договора с мерчантом. Все персональные данные сохраняются в системе оператора площадки в зашифрованном виде, не участвуют в автоматизированном обмене данными. Передача персональных данных возможна только банку получателя при соответствуещем запросе в рамках процедуры AML/KYC. В рамках договора с мерчантом можно выбрать геолокацию для хранилища персональных данных.

Warning

Если в ответ на создание транзакции пришел HTTP-статус, отличный от 2xx — это автоматически означает, что транзакция не была принята к исполнению. В целях контроля целостности и исключения сетевых ошибок допустимо дополнительно отправлять запрос на проверку статуса транзакции, чтобы убедиться, что транзакция не была принята. Кроме того, для защиты от двойных выплат используется идемпотентный ключ invoiceId.

Разбор ответа:

В ответе на запрос создание транзакции сервер возвращает только id транзакции и ее первичный статус.

  • Status 200:

    {
      "id": "00fd5cb1-a99b-49c0-813f-5b5df0c7e32b",
      "status": "queued"
    }
    

    • id: uuid (required) — invoice ID
    • status: string (required) — queuedcanceled, completed,paid,pending

Обработка ошибок

  • Status 400: Invalid request, typically due to a missing or malformed parameter.

    {
    "error": "ERROR_ACCESS_TOKEN_INVALID", 
    "message": "Access token is invalid.", 
    "statusCode": 400 
    }
    

    • error: string (required)
    • message: string (required)
    • statusCode: number
  • Status 401: Authentication failed. This may happen due to the following reasons:

  • Authentication is required but not provided.
  • The access token has expired.
{
"error": "ERROR_TOKEN_EXPIRED", 
"message": "Access token has expired.", 
"statusCode": 401 
}
- `error`: string (required)
- `message`: string (required)
- `statusCode`: number
  • Status 400: QR code format not supported right now.
{ 
"error": "ERROR_CURRENCY_NOT_SUPPORTED", 
"message": "Currency not supported", 
"statusCode": 400 
}
- `error`: string (required)
- `message`: string (required)
- `statusCode`: number
  • Status 400: QR code expired.
{ 
"error": "ERROR_QUOTE_EXPIRED", 
"message": "Quote request expired", 
"statusCode": 400 
}
- `error`: string (required)
- `message`: string (required)
- `statusCode`: number
  • Status 409: Conflict occurred because a deal with the same invoice ID already exists.
{ 
"error": "TRANSACTION_ALREADY_EXISTS", 
"message": "Transaction with same invoiceId already exists.", 
"statusCode": 409 
}
- `error`: string (required)
- `message`: string (required)
- `statusCode`: number
  • Status 500: Project tariff not configured, please contact our support.
{
  "error": "TARIFF_NO_FOUND",
  "message": "Project tariff not configured, pls contact with our support.",
  "statusCode": 500
}
- `error`: string (required)
- `message`: string (required)
- `statusCode`: number
  • Status 501: Requested quote not found, please contact our support.
{
  "error": "QUOTE_NOT_FOUND",
  "message": "Requested quote not found, pls contact with our support.",
  "statusCode": 501
}
* `error`: string (required)
* `message`: string (required)
* `statusCode`: number

Шаг 5. Проверка статуса транзакции

Запрос:

curl -X GET https://api.payler.one/v2/{id} \
     -H "Authorization: Bearer <ACCESS_TOKEN>" \
     -H "Content-Type: application/json" \

id: uuid (required) — ID из ответа на запрос /fx/calculatenew; либо ID, переданный нам на этапе финализации платежа в параметре invoiceId; либо ID из ответа на на запрос /deals/payout

Разбор ответа:

  • Status 200:

    {
      "id": "2d4d3684-91bb-4395-8b76-f2f4b30dd0f",
      "invoiceId": "00000203023",
      "clientId": "1232023032-23023023",
      "amount": 120,
      "amountToPay": 3223.23,
      "currency": "TRY",
      "currencyToPay": "RUB",
      "fee": 0,
      "feePercent": 0,
      "fullRate": 323,
      "baseRate": 300,
      "status": "completed",
      "reason": "BAD_RECIPIENT_BANK_ID",
      "createdAt": "2025-05-13T18:57:27.489Z",
      "completedAt": "2025-05-13T19:08:27.000Z"
    }
    

    • id (string): Уникальный идентификатор запроса на оплату;
    • invoiceId (string): Внутренний уникальный номер инвойса мерчанта;
    • clientId (string): Идентификатор клиента в системе мерчанта, помогает связывать платёж с пользователем;
    • amount (required) (float): Сумма платежа в локальной валюте, которая прийдет получателю
    • currency (required) (string): ISO-код валюты получателя
    • currencyToPay (required) (string): ISO-код валюты отправителя
    • amountToPay (required)(float): Сумма к списанию в валюте отправителя;
    • fee (required) (float): Комиссия платёжного провайдера в валюте отправителя;
    • feePercent (required) (float): Процент комиссии по тарифу;
    • fullRate (required) (float): Обменный курс, рассчитанный как amount / amountToPay;
    • baseRate (required) (float): Базовый обменный курс для пары валют;
    • status (required) (string): Текущий статус платежа — может принимать значения paid, completed canceled, expired, new, queued
    • reason (optional)(string): причина отклонения транзакции
    • createdAt (date-time): Временная метка (ISO 8601) создания запроса на оплату;
    • completedAt (date-time): Временная метка (ISO 8601) завершения платежа (успешного или отмены);
  • Status 400: Invalid request, typically due to a missing or malformed parameter.

{
"error": "ERROR_ACCESS_TOKEN_INVALID", 
"message": "Access token is invalid.", 
"statusCode": 400 
}
- `error`: string (required)
- `message`: string (required)
- `statusCode`: number
  • Status 401: Authentication failed. This may happen due to the following reasons:

  • Authentication is required but not provided.

  • The access token has expired.
{
"error": "ERROR_TOKEN_EXPIRED", 
"message": "Access token has expired.", 
"statusCode": 401 
}
- `error`: string (required)
- `message`: string (required)
- `statusCode`: number
  • Status 500: Transaction with specified ID not found.
{
"error": "TRANSACTION_NOT_FOUND", 
"message": "Transaction with specified ID not found.", 
"statusCode": 500 
}
- `error`: string (required)
- `message`: string (required)
- `statusCode`: number