Рекуррентный платёж по карте другого банка
Метод списывает средства с карты покупателя без его участия, если карта была привязана для рекуррентных платежей у другого эквайера.
Подключение метода
Метод доступен только для магазинов, которым он подключён в KVELL. Для подключения обратитесь к менеджеру.
Работа с карточными данными
Метод принимает полный номер карты. Мерчант должен иметь действующий документ, подтверждающий соответствие
требованиям PCI DSS. Не логируйте card.pan и храните его только в защищённом хранилище.
Сценарий интеграции
- Получите у предыдущего эквайера идентификатор первого платежа покупателя, при котором карта была привязана для рекуррентных списаний, и сохраните его вместе с реквизитами карты.
- При наступлении списания сформируйте подпись и отправьте запрос с новым уникальным
transaction, передав идентификатор первого платежа эквайера вinitial_network_transaction_id. - Определите результат по полю
statusответа200:completed— списание выполнено,canceled— отклонено, причина указана вerror_code. - Если статус в ответе не финальный, запрашивайте статус транзакции по
transaction, пока не получите финальный, или дождитесь колбэка — он отправляется при финальном статусе.
URL
Запрос
Заголовки
| Название | Тип | Обязательно | Описание |
|---|---|---|---|
X-Api-Key |
string | Да | Идентификатор магазина. |
X-Signature |
string | Да | Подпись запроса. |
Формирование подписи
Объедините значения без разделителей в указанном порядке, вычислите SHA-256 от строки в кодировке UTF-8 и передайте
полученный hex-хеш в нижнем регистре в заголовке X-Signature:
SHA256(X-Api-Key + transaction + amount + card.pan + card.expire + initial_network_transaction_id + secret_key)
secret_key находится в настройках магазина. Пробелы, переносы строк и другие разделители между значениями добавлять
нельзя. Значения должны в точности совпадать с данными в отправляемом JSON.
Тело запроса
| Параметр | Тип | Обязательно | Описание |
|---|---|---|---|
transaction |
string | Да | Уникальный номер транзакции на стороне мерчанта. |
amount |
integer | Да | Сумма списания в копейках, больше нуля. |
description |
string | Да | Описание платежа, не более 99 символов. |
card |
object | Да | Реквизиты карты. Описание полей приведено ниже. |
initial_network_transaction_id |
string | Да | Идентификатор первого платежа у предыдущего эквайера. |
fiscal_data |
object | null | Нет | Данные для фискализации чека по 54-ФЗ. |
extra_data |
object | null | Нет | Дополнительные параметры мерчанта. |
Объект card
| Параметр | Тип | Обязательно | Описание |
|---|---|---|---|
pan |
string | Да | Номер карты: от 12 до 19 цифр, проходит проверку по алгоритму Луна. |
expire |
string | Да | Срок действия карты в формате YYYY-MM, например 2028-12. |
holder |
string | null | Нет | Имя держателя карты, как указано на карте. |
Пример
curl --request POST \
--url 'https://api.pay.kvell.group/v1/orders/rebill-external-card' \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <api-key>' \
--header 'X-Signature: <signature>' \
--data '{
"transaction": "rebill-20261031-0001",
"amount": 15000,
"description": "Оплата по договору 42",
"card": {
"pan": "2201382000000021",
"expire": "2028-12",
"holder": "IVAN IVANOV"
},
"initial_network_transaction_id": "483012345678901",
"extra_data": {
"contract": "42"
}
}'
Ответ
Выберите HTTP-код, чтобы посмотреть пример, параметры ответа и рекомендуемые действия.
Если HTTP-ответ не получен
Таймаут и разрыв соединения обрабатывайте так же, как ответ 5XX: результат списания неизвестен. Сначала
запросите статус по исходному transaction и не отправляйте новое списание, пока результат исходного не установлен.
{
"id": "b13e1610-f26a-4c49-84e8-0edf1650a026",
"status": "completed",
"transaction": "rebill-20261031-0001",
"amount": 15000,
"commission": 0,
"inner_commission": 0,
"description": "Оплата по договору 42",
"success_url": null,
"fail_url": null,
"redirect_url": null,
"extra_data": {
"contract": "42"
},
"fiscal_data": null,
"additional_data": {},
"error_code": null,
"error_message": null,
"created_at": "2026-10-31T12:55:00.951753+00:00",
"refund_amount": 0,
"reverse_amount": 0,
"confirm_amount": 0,
"instrument": "card",
"ecommerce_type": "payment"
}
HTTP-код 200 означает, что запрос принят и обработан. Результат списания определяется полем status, а не
HTTP-кодом: отказ банка также возвращается с кодом 200 и статусом canceled.
Параметры ответа
| Параметр | Тип | Описание |
|---|---|---|
id |
string | Идентификатор платежа в KVELL. |
status |
string | Статус платежа. Значения приведены в разделе «Статусы транзакции». |
transaction |
string | Номер транзакции из запроса. |
amount |
integer | Сумма в копейках. |
commission |
integer | Комиссия в копейках. |
inner_commission |
integer | Внутренняя комиссия в копейках. |
description |
string | null | Описание платежа из запроса. |
success_url |
string | null | Для этого метода — null. |
fail_url |
string | null | Для этого метода — null. |
redirect_url |
string | null | Для этого метода — null. |
extra_data |
object | Дополнительные параметры из запроса. |
fiscal_data |
object | null | Данные фискализации из запроса. |
additional_data |
object | null | Дополнительные данные платежа. |
error_code |
string | null | Причина отклонения при статусе canceled. Значения приведены в разделе «Коды ошибок транзакции». |
error_message |
string | null | Текстовое описание причины отклонения. |
created_at |
string | Дата и время создания платежа в формате ISO 8601. |
refund_amount |
integer | null | Сумма возвратов в копейках. |
reverse_amount |
integer | null | Сумма отмен в копейках. |
confirm_amount |
integer | null | Сумма подтверждений в копейках. |
instrument |
string | null | Способ проведения операции — card. |
ecommerce_type |
string | null | Тип операции — payment. |
Что делать дальше
- При
completedотметьте списание как успешное. - При
canceledпроверьтеerror_code. Повторное списание отправляйте с новымtransaction. - При
newилиprocessingзапрашивайте статус транзакции поtransactionдо финального статуса или дождитесь колбэка.
{
"errors": [
{
"code": 20007,
"message": "Транзакция совершалась прежде"
}
]
}
Параметры ответа
| Параметр | Тип | Описание |
|---|---|---|
errors |
array | Список ошибок. Коды и рекомендации по обработке приведены в разделе «Ошибки HTTP-ответов». |
errors[].code |
integer | Код ошибки. В примере — 20007. |
errors[].message |
string | Описание причины отклонения запроса. |
Параметры ответа
| Параметр | Тип | Описание |
|---|---|---|
errors |
array | Список ошибок. Коды и рекомендации по обработке приведены в разделе «Ошибки HTTP-ответов». |
errors[].code |
integer | Код ошибки. |
errors[].message |
string | Описание причины запрета доступа. |
Параметры ответа
| Параметр | Тип | Описание |
|---|---|---|
errors |
array | Список ошибок. Коды и рекомендации по обработке приведены в разделе «Ошибки HTTP-ответов». |
errors[].code |
integer | Код ошибки. |
errors[].message |
string | Описание причины, по которой ресурс не найден. |
{
"errors": [
{
"code": 20098,
"message": "initial_network_transaction_id: Field required"
}
]
}
Параметры ответа
| Параметр | Тип | Описание |
|---|---|---|
errors |
array | Список ошибок валидации. Коды и рекомендации по обработке приведены в разделе «Ошибки HTTP-ответов». |
errors[].code |
integer | Код ошибки валидации. |
errors[].message |
string | Название поля и причина ошибки валидации. |
{
"errors": [
{
"code": 20000,
"message": "Неизвестная ошибка"
}
]
}
Параметры ответа
| Параметр | Тип | Описание |
|---|---|---|
errors |
array | Список ошибок. Коды и рекомендации по обработке приведены в разделе «Ошибки HTTP-ответов». |
errors[].code |
integer | Код ошибки. Для неизвестной ошибки — 20000. |
errors[].message |
string | Описание технической ошибки. |
5XX, таймаут и разрыв соединения
Во всех этих случаях результат запроса считается неопределённым: списание могло пройти, даже если клиент не получил ответ. Оставьте операцию в своей системе в состоянии «обрабатывается» до получения подтверждённого результата от KVELL.
Единый алгоритм обработки
- Не создавайте новый платёж и не меняйте
transaction. - Запросите статус транзакции по исходному
transaction. - Если запросы статуса продолжают завершаться технической ошибкой, обратитесь в поддержку и передайте
transaction.