Перейти к содержанию

Получение карты по транзакции

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

Сценарий интеграции

  1. Проведите операцию с привязкой карты: передайте customer_key и bind_card: true, например в платеже по карте через H2H или платеже с предавторизацией.
  2. Сохраните transaction и customer_key этой операции.
  3. Сформируйте подпись из X-Api-Key, transaction, customer_key и secret_key.
  4. Отправьте запрос с тем же X-Api-Key, с которым создавалась операция.
  5. Сохраните token карты, чтобы использовать его для оплаты привязанной картой.

URL

GET https://api.pay.kvell.group/v1/customers/{customer_key}/orders/{transaction}
GET https://api.pay.stage.kvell.group/v1/customers/{customer_key}/orders/{transaction}

Запрос

Path-параметры

Параметр Тип Обязательно Описание
customer_key string Да Идентификатор покупателя в системе мерчанта.
transaction string Да Идентификатор операции в системе мерчанта.

Заголовки

Название Тип Обязательно Описание
X-Api-Key string Да Идентификатор магазина.
X-Signature string Да Подпись запроса.

Формирование подписи

Объедините X-Api-Key, transaction, customer_key и secret_key без разделителей, вычислите SHA-256 от полученной строки в кодировке UTF-8 и передайте хеш в нижнем регистре в заголовке X-Signature.

SHA256(X-Api-Key + transaction + customer_key + secret_key)

secret_key находится в настройках магазина.

Пример

curl --request GET \
  --url 'https://api.pay.stage.kvell.group/v1/customers/customer-42/orders/payment-20261002-0001' \
  --header 'X-Api-Key: <api-key>' \
  --header 'X-Signature: <signature>'

Ответ

Выберите HTTP-код, чтобы посмотреть пример, параметры ответа и рекомендуемые действия.

Пример ответа 200 (OK)
{
  "customer_id": 25,
  "token": "4VNSbS7nF410G8WLEhUUUnflH2UKvWlHxIzN3Jr9JJs",
  "pan_mask": "411111******1111",
  "holder": "IVAN IVANOV",
  "expire": "2034-12",
  "created_at": "2026-10-02T07:52:29.720321Z",
  "pan_hash_encrypted": "EPNS42BPO6yazHvd6BKd...ObPg6EKv7mYKUy7zc8s=",
  "bank_id": "100000000004",
  "bank_name": "Tinkoff Bank",
  "bank_url": "tinkoff.ru"
}

Параметры ответа

Параметр Тип Описание
customer_id integer Идентификатор покупателя в KVELL.
token string Токен привязанной карты. Используется для оплаты привязанной картой.
pan_mask string Маска номера карты.
holder string | null Имя держателя карты.
expire string | null Срок действия карты в формате YYYY-MM.
created_at string Дата и время привязки карты в формате ISO 8601.
pan_hash_encrypted string | null Хеш номера карты, зашифрованный публичным ключом магазина, в Base64. Расшифровка описана в разделе «Расшифровка хеша номера карты».
bank_id string | null Идентификатор банка-эмитента карты.
bank_name string | null Название банка-эмитента карты.
bank_url string | null Домен сайта банка-эмитента карты.

Что означает ответ

Операция найдена, и карта, которой она проведена, привязана к покупателю.

Поля bank_id, bank_name и bank_url определяются по BIN карты и возвращаются со значением null, если банк определить не удалось. Если при шифровании хеша номера карты произошла ошибка, pan_hash_encrypted возвращается со значением null, а остальные поля ответа заполняются.

Что делать дальше

  1. Сохраните token и используйте его для оплаты привязанной картой.
  2. Если нужен pan_hash_encrypted, расшифруйте его приватным ключом магазина.
Пример ответа 400 (Bad Request)
{
  "errors": [
    {
      "code": 20002,
      "message": "Неверная подпись"
    }
  ]
}

Параметры ответа

Параметр Тип Описание
errors array Список ошибок. Коды и рекомендации по обработке приведены в разделе «Ошибки HTTP-ответов».
errors[].code integer Код ошибки. В примере — 20002.
errors[].message string Описание причины отклонения запроса.
Пример ответа 403 (Forbidden)
{
  "errors": [
    {
      "code": 20037,
      "message": "Доступ запрещен"
    }
  ]
}

Параметры ответа

Параметр Тип Описание
errors array Список ошибок. Коды и рекомендации по обработке приведены в разделе «Ошибки HTTP-ответов».
errors[].code integer Код ошибки. В примере — 20037.
errors[].message string Описание причины запрета доступа.
Пример ответа 404 (Not Found)
{
  "errors": [
    {
      "code": 20009,
      "message": "Заказ не найден"
    }
  ]
}

Параметры ответа

Параметр Тип Описание
errors array Список ошибок. Коды и рекомендации по обработке приведены в разделе «Ошибки HTTP-ответов».
errors[].code integer Код ошибки. В примере — 20009.
errors[].message string Описание ресурса, который не найден.
Пример ответа 422 (Unprocessable Entity)
{
  "errors": [
    {
      "code": 20017,
      "message": "customer_key не задан"
    }
  ]
}

Параметры ответа

Параметр Тип Описание
errors array Список ошибок. Коды и рекомендации по обработке приведены в разделе «Ошибки HTTP-ответов».
errors[].code integer Код ошибки. В примере — 20017.
errors[].message string Причина ошибки.
Пример ответа 5XX (Internal Server Error)
{
  "errors": [
    {
      "code": 20000,
      "message": "Неизвестная ошибка"
    }
  ]
}

Параметры ответа

Параметр Тип Описание
errors array Список ошибок. Коды и рекомендации по обработке приведены в разделе «Ошибки HTTP-ответов».
errors[].code integer Код ошибки. Для неизвестной ошибки — 20000.
errors[].message string Описание технической ошибки.

Что делать дальше

  1. Безопасно повторите тот же GET-запрос с исходными customer_key и transaction.
  2. При повторяющейся ошибке обратитесь в поддержку KVELL и передайте URL, время запроса, HTTP-код, code и message.

Расшифровка хеша номера карты

Поле pan_hash_encrypted позволяет сопоставить карту с картами в вашей системе, не получая номер карты. KVELL вычисляет SHA-256 от номера карты, записывает результат строкой в шестнадцатеричном формате в нижнем регистре и шифрует её публичным ключом магазина.

Параметр Значение
Алгоритм RSA-OAEP
Хеш-функция SHA-256
Функция формирования маски MGF1 с SHA-256
Метка (label) Не используется
Кодирование результата Base64

Расшифруйте значение приватным ключом магазина. Результат — строка из 64 шестнадцатеричных символов, которую можно сравнить с sha256(pan), вычисленным на вашей стороне.

Работа с приватным ключом

Храните приватный ключ только на своём сервере. Не передавайте его в KVELL и не используйте в клиентском коде.

Требуется пакет: pip install cryptography.

import base64

from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding

with open('private_key.pem', 'rb') as key_file:
    private_key = serialization.load_pem_private_key(key_file.read(), password=None)

# значение поля pan_hash_encrypted из ответа метода
encrypted_base64 = 'EPNS42BPO6yazHvd6BKd...ObPg6EKv7mYKUy7zc8s='

pan_hash = private_key.decrypt(
    base64.b64decode(encrypted_base64),
    padding.OAEP(
        mgf=padding.MGF1(algorithm=hashes.SHA256()),
        algorithm=hashes.SHA256(),
        label=None,
    ),
).decode('ascii')

print(pan_hash)

Используется встроенный модуль node:crypto.

const crypto = require('node:crypto');
const fs = require('node:fs');

const privateKeyPem = fs.readFileSync('private_key.pem', 'utf8');

// значение поля pan_hash_encrypted из ответа метода
const encryptedBase64 = 'EPNS42BPO6yazHvd6BKd...ObPg6EKv7mYKUy7zc8s=';

const panHash = crypto.privateDecrypt(
  {
    key: privateKeyPem,
    padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
    oaepHash: 'sha256',
  },
  Buffer.from(encryptedBase64, 'base64'),
).toString('ascii');

console.log(panHash);