Skip to content

Recurring Payment by a Card from Another Bank

The method charges the customer's card without their involvement when the card was set up for recurring payments with another acquirer.

Enabling the method

The method is available only to shops for which it is enabled in KVELL. Contact your manager to enable it.

Handling card data

The method accepts the full card number. The merchant must have a valid document confirming compliance with PCI DSS requirements. Do not log card.pan and store it only in secure storage.

Integration flow

  1. Obtain from the previous acquirer the identifier of the customer's initial payment in which the card was set up for recurring charges, and store it together with the card details.
  2. When a charge is due, build the signature and send the request with a new unique transaction, passing the acquirer's initial payment identifier in initial_network_transaction_id.
  3. Determine the result from the status field of the 200 response: completed — the charge succeeded, canceled — it was declined, and the reason is in error_code.
  4. If the status in the response is not final, request the transaction status by transaction until you receive a final one, or wait for the callback — it is sent when the status becomes final.

URL

POST https://api.pay.kvell.group/v1/orders/rebill-external-card
POST https://api.pay.stage.kvell.group/v1/orders/rebill-external-card

Request

Headers

Name Type Required Description
X-Api-Key string Yes Shop identifier.
X-Signature string Yes Request signature.

Building the signature

Concatenate the values without separators in the order shown, compute SHA-256 of the UTF-8 string and pass the resulting lowercase hex hash in the X-Signature header:

SHA256(X-Api-Key + transaction + amount + card.pan + card.expire + initial_network_transaction_id + secret_key)

secret_key is in the shop settings. Do not add spaces, line breaks or other separators between the values. The values must exactly match the data in the JSON being sent.

Request body

Parameter Type Required Description
transaction string Yes Unique transaction number on the merchant's side.
amount integer Yes Charge amount in kopecks, greater than zero.
description string Yes Payment description, up to 99 characters.
card object Yes Card details. The fields are described below.
initial_network_transaction_id string Yes Initial payment identifier from the previous acquirer.
fiscal_data object | null No Data for receipt fiscalization under 54-FZ.
extra_data object | null No Additional merchant parameters.

card object

Parameter Type Required Description
pan string Yes Card number: 12 to 19 digits, passes the Luhn check.
expire string Yes Card expiry date in YYYY-MM format, for example 2028-12.
holder string | null No Cardholder name as shown on the card.

Example

{
  "transaction": "rebill-20261031-0001",
  "amount": 15000,
  "description": "Payment under contract 42",
  "card": {
    "pan": "2201382000000021",
    "expire": "2028-12",
    "holder": "IVAN IVANOV"
  },
  "initial_network_transaction_id": "483012345678901",
  "extra_data": {
    "contract": "42"
  }
}
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": "Payment under contract 42",
    "card": {
      "pan": "2201382000000021",
      "expire": "2028-12",
      "holder": "IVAN IVANOV"
    },
    "initial_network_transaction_id": "483012345678901",
    "extra_data": {
      "contract": "42"
    }
  }'

Response

Select an HTTP code to see an example, the response parameters and the recommended actions.

If no HTTP response is received

Handle a timeout or connection drop the same way as a 5XX response: the result of the charge is unknown. First request the status for the original transaction and do not send a new charge until the result of the original one is determined.

Example 200 response (OK)
{
  "id": "b13e1610-f26a-4c49-84e8-0edf1650a026",
  "status": "completed",
  "transaction": "rebill-20261031-0001",
  "amount": 15000,
  "commission": 0,
  "inner_commission": 0,
  "description": "Payment under contract 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 code 200 means the request was accepted and processed. The charge result is determined by the status field, not by the HTTP code: a bank decline is also returned with code 200 and status canceled.

Response parameters

Parameter Type Description
id string Payment identifier in KVELL.
status string Payment status. The values are listed in Transaction statuses.
transaction string Transaction number from the request.
amount integer Amount in kopecks.
commission integer Commission in kopecks.
inner_commission integer Internal commission in kopecks.
description string | null Payment description from the request.
success_url string | null null for this method.
fail_url string | null null for this method.
redirect_url string | null null for this method.
extra_data object Additional parameters from the request.
fiscal_data object | null Fiscalization data from the request.
additional_data object | null Additional payment data.
error_code string | null Decline reason when the status is canceled. The values are listed in Transaction error codes.
error_message string | null Text description of the decline reason.
created_at string Payment creation date and time in ISO 8601 format.
refund_amount integer | null Refunded amount in kopecks.
reverse_amount integer | null Reversed amount in kopecks.
confirm_amount integer | null Confirmed amount in kopecks.
instrument string | null Payment instrument — card.
ecommerce_type string | null Operation type — payment.

What to do next

  1. On completed, mark the charge as successful.
  2. On canceled, check error_code. Send a repeat charge with a new transaction.
  3. On new or processing, request the transaction status by transaction until the status is final, or wait for the callback.
Example 400 response (Bad Request)
{
  "errors": [
    {
      "code": 20007,
      "message": "Транзакция совершалась прежде"
    }
  ]
}

Response parameters

Parameter Type Description
errors array List of errors. Codes and handling recommendations are given in HTTP response errors.
errors[].code integer Error code. In the example — 20007.
errors[].message string Reason the request was rejected.
Example 403 response (Forbidden)
{
  "errors": [
    {
      "code": 20037,
      "message": "Доступ запрещен"
    }
  ]
}

Response parameters

Parameter Type Description
errors array List of errors. Codes and handling recommendations are given in HTTP response errors.
errors[].code integer Error code.
errors[].message string Reason access was denied.
Example 404 response (Not Found)
{
  "errors": [
    {
      "code": 20006,
      "message": "Магазин не найден"
    }
  ]
}

Response parameters

Parameter Type Description
errors array List of errors. Codes and handling recommendations are given in HTTP response errors.
errors[].code integer Error code.
errors[].message string Reason the resource was not found.
Example 422 response (Unprocessable Entity)
{
  "errors": [
    {
      "code": 20098,
      "message": "initial_network_transaction_id: Field required"
    }
  ]
}

Response parameters

Parameter Type Description
errors array List of validation errors. Codes and handling recommendations are given in HTTP response errors.
errors[].code integer Validation error code.
errors[].message string Field name and validation error reason.
Example 5XX response (Internal Server Error)
{
  "errors": [
    {
      "code": 20000,
      "message": "Неизвестная ошибка"
    }
  ]
}

Response parameters

Parameter Type Description
errors array List of errors. Codes and handling recommendations are given in HTTP response errors.
errors[].code integer Error code. For an unknown error — 20000.
errors[].message string Description of the technical error.

5XX, timeout and connection drop

In all these cases the result of the request is undetermined: the charge may have gone through even if the client did not receive a response. Keep the operation in your system in the "processing" state until you get a confirmed result from KVELL.

Handling algorithm

  1. Do not create a new payment and do not change transaction.
  2. Request the transaction status for the original transaction.
  3. If status requests keep failing with a technical error, contact support and provide transaction.