Integration of Sovest Installment on Website
Sovest is an installment card from Kiwi Bank (project closed in 2023). If you see this document and are considering Sovest integration — refer to current alternatives: Halva (Sovkombank), Split (Tinkoff), Podeli (Alfa-Bank), or SberPay Installments.
Current BNPL Alternatives in Russia
The buy now pay later (BNPL) market in 2024–2025 is dominated by:
| Service | Bank | Max Term | Features |
|---|---|---|---|
| Halva | Sovkombank | 24 months | Largest partner network |
| Split | Tinkoff | 12 months | Integration via Tinkoff API |
| Podeli | Alfa-Bank | 3 payments | Instant decision |
| Dolami | Yandex | 4 payments | Interest-free |
| OZON Credit | OZON | 12 months | OZON Marketplace only |
Tinkoff Split Integration
Most technically mature replacement. Works via the same API as Tinkoff Kassa, but with product type Credit:
$params = [
'TerminalKey' => env('TINKOFF_CREDIT_TERMINAL'),
'Amount' => 149900, // in kopeks
'OrderId' => 'order-12345',
'Description' => 'Order #12345 — installment',
'DATA' => [
'connection_type' => 'widget',
],
];
// Token generation via standard Tinkoff scheme
ksort($params);
$params['Token'] = hash('sha256', implode('', array_values($params)) . env('TINKOFF_CREDIT_PASSWORD'));
$response = Http::post('https://securepay.tinkoff.ru/v2/Init', $params);
$paymentUrl = $response->json('PaymentURL');
Split uses a separate terminal with product type Credit — obtained in Tinkoff Business cabinet when joining the program.
Podeli Integration (Alfa-Bank)
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . env('PODELI_TOKEN'),
'Content-Type' => 'application/json',
])->post('https://api.podeli.ru/v1/orders', [
'amount' => 14990,
'currency' => 'RUB',
'orderId' => 'order-12345',
'description' => 'Order #12345',
'returnUrl' => 'https://example.com/payment/return',
'callbackUrl' => 'https://example.com/webhook/podeli',
'customer' => [
'phone' => '+79001234567',
],
'items' => [
[
'name' => 'Product 1',
'price' => 14990,
'quantity' => 1,
],
],
]);
$checkoutUrl = $response->json('checkoutUrl');
Podeli — three payments: first at checkout, second and third at equal intervals. Decision made in seconds.
Dolami (Yandex)
Dolami — Yandex BNPL service, integrated via Yandex Pay API:
// Yandex Pay widget
YaPay.createPayment({
env: YaPay.PaymentEnv.Prod,
version: 4,
paymentSheet: {
version: 4,
countryCode: YaPay.CountryCode.Ru,
currencyCode: YaPay.CurrencyCode.Rub,
merchant: {
id: MERCHANT_ID,
name: 'My Store',
url: 'https://example.com',
},
order: {
id: 'order-12345',
total: { amount: '1499.00' },
items: [{ label: 'Product 1', amount: '1499.00' }],
},
paymentMethods: [
{ type: YaPay.PaymentMethodType.Split, gateway: 'yandex' },
],
},
});
BNPL Calculator on Product Card
function BnplBadges({ price }: { price: number }) {
const perThree = (price / 3).toFixed(2);
const perFour = (price / 4).toFixed(2);
return (
<div className="flex gap-2 text-sm text-muted-foreground">
<span>Podeli: 3 × {perThree} ₽</span>
<span>Dolami: 4 × {perFour} ₽</span>
</div>
);
}
Webhook Pattern for BNPL
Regardless of specific service, all BNPL solutions use similar webhook logic:
public function handleBnplWebhook(Request $request, string $provider): Response
{
// 1. Verify signature (specific to each provider)
// 2. Check idempotency (don't process same event twice)
// 3. Update order status only on final status (APPROVED)
// 4. Return 200 — otherwise service will retry
$payload = $this->verifyAndParse($request, $provider);
if (BnplWebhookLog::where('event_id', $payload['eventId'])->exists()) {
return response('Already processed', 200);
}
BnplWebhookLog::create(['event_id' => $payload['eventId'], 'provider' => $provider]);
if ($payload['status'] === 'APPROVED') {
Order::where('id', $payload['orderId'])->update(['status' => 'paid']);
}
return response('OK', 200);
}
Time to connect to any BNPL service is 3 to 10 business days depending on provider.







