Integrating Halva Installment Plan into Your Website
An e-commerce store owner loses customers at checkout — expensive items get abandoned due to lack of installment options. For example, an electronics store noticed that 40% of abandoned carts were for high-value items. After implementing the Halva widget, abandonment halved. Adding installment solves this: the buyer pays in parts, and the store receives the full amount immediately. We have integrated Halva for 15+ stores over several years, and conversion has increased by an average of 30%.
How the Halva Widget Works
Halva is a credit card from Sovcombank that offers interest-free installments. The cardholder pays without interest, while the store subsidizes the commission. For online stores, this is a tool to increase average order value: customers are more likely to buy expensive items when they see a breakdown like "4 monthly payments". The widget displays the monthly payment on the product card. It loads dynamically without slowing the page — encapsulated in an iframe, it does not affect LCP.
How It Works
Integration is done via the Halva API or partner widget. Basic flow:
- Buyer selects "Pay in installments with Halva"
- Store creates an order via API and receives a link
- Buyer authorizes in Halva system, confirms the installment
- Halva notifies the store of confirmation
- Store ships the goods
API Integration
You need a contract with Sovcombank. After that, you receive a partnerToken and environment settings. Note: the test endpoint differs from production — use environment variables.
class HalvaService
{
private string $baseUrl = 'https://halvacard.ru/order/';
private string $partnerToken;
public function __construct()
{
$this->partnerToken = env('HALVA_PARTNER_TOKEN');
}
public function createOrder(Order $order): string
{
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . $this->partnerToken,
'Content-Type' => 'application/json',
])->post($this->baseUrl . 'create', [
'amount' => $order->total, // in RUB
'orderId' => (string)$order->id,
'successUrl' => 'https://example.com/payment/success',
'failUrl' => 'https://example.com/payment/fail',
'notifyUrl' => 'https://example.com/webhook/halva',
'partInstalment'=> 3, // number of months
'contact' => [
'phone' => $order->customer_phone,
'email' => $order->customer_email,
],
'items' => $order->items->map(fn($item) => [
'name' => $item->product->name,
'price' => $item->price,
'quantity' => $item->quantity,
'sum' => $item->price * $item->quantity,
])->toArray(),
]);
if (!$response->ok()) {
throw new \RuntimeException('Halva API error: ' . $response->body());
}
return $response->json('url'); // link to Halva page
}
}
Widget for Displaying Installment on Product Card
Halva provides a JavaScript widget to show the monthly payment right on the product page:
<script src="https://halvacard.ru/widget/halva-widget.js"></script>
<div
class="halva-widget"
data-halva-price="14990"
data-halva-months="3"
></div>
The widget automatically calculates and displays a monthly payment next to the price. If multiple installment options are available, it shows the minimum payment. According to our statistics, the widget doubles conversion compared to plain text offers.
| Parameter | Widget | API |
|---|---|---|
| Ease of integration | Instant | Requires server setup |
| Term management | Category-limited | Flexible |
| Customization | Minimal | Full control |
How to Secure Webhook Against Forgery
The webhook notifies the store about order status changes — APPROVED, REJECTED, or CANCELLED. Without it, you won't know if payment went through. HMAC-SHA256 signature prevents forgery: verify it on your side. The signature is computed from the request body and a secret key. Compare with the X-Halva-Signature header. If it doesn't match, discard the request.
public function webhook(Request $request): Response
{
// Halva signs notifications with HMAC-SHA256
$signature = $request->header('X-Halva-Signature');
$expected = hash_hmac('sha256', $request->getContent(), env('HALVA_WEBHOOK_SECRET'));
if (!hash_equals($expected, $signature)) {
return response('Forbidden', 403);
}
$data = $request->json()->all();
$status = $data['status']; // APPROVED, REJECTED, CANCELLED
$orderId = $data['orderId'];
if ($status === 'APPROVED') {
Order::where('id', $orderId)->update([
'status' => 'paid',
'payment_type' => 'halva',
'halva_order' => $data['halvaOrderId'],
]);
// initiate shipping
}
return response('OK');
}
When to Configure Installment Terms?
Different product categories may have different maximum installment terms (from 2 to 24 months), determined by the contract with Sovcombank. Check the term via API:
$terms = Http::withToken(env('HALVA_PARTNER_TOKEN'))
->get('https://halvacard.ru/order/terms', [
'categoryId' => $product->halva_category_id,
])->json('months'); // array of available terms, e.g. [3, 6, 12]
Show only available terms to the buyer in a select.
| Category | Max term (months) |
|---|---|
| Electronics | 12 |
| Furniture | 24 |
| Clothing | 6 |
Commission and Subsidizing
The store pays a commission to Sovcombank for each installment — a percentage of the amount, depending on the term. Longer terms mean higher commission. This must be factored into the economics: either include it in the price or treat it as a marketing cost for higher conversion. Average commission is 5% for a 6-month term, but can vary from 3% to 8%.
Common Integration Mistakes
- Skipping HMAC signature verification on webhook — an attacker can forge notifications and mark orders as paid.
- Using a test token in production — all requests go to sandbox.
- Not handling CANCELLED status — orders remain stuck as "pending payment".
- Passing an incorrect amount to the widget (without discounts) — the buyer sees one payment but a different one at checkout.
What's Included in Our Work
- Preparation and submission of documents to Sovcombank
- Widget setup on product cards
- Implementation of API endpoints (order creation, status check)
- Webhook handling with signature verification
- Testing all scenarios (success, rejection, cancellation)
- Providing documentation for your developers
- Training staff to work with reports
- Support for 14 days after launch
The connection to the Halva program takes 5 to 10 business days. It requires passing verification with Sovcombank. Contact us — we'll help you get through this stage faster. Get a consultation for your project today. We guarantee correct integration and support at all stages. Our experience: over 5 years in the market and 30+ completed projects.







