Integrating BNPL Services: From Provider Selection to Go-Live in Under Two Weeks

Our company is engaged in the development, support and maintenance of sites of any complexity. From simple one-page sites to large-scale cluster systems built on micro services. Experience of developers is confirmed by certificates from vendors.

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Showing 1 of 1All 2062 services
Integrating BNPL Services: From Provider Selection to Go-Live in Under Two Weeks
Medium
from 1 day to 3 days
Frequently Asked Questions

Our competencies:

Development stages

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1358
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1251
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    956
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1188
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    929
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Website development for FIXPER company
    947

A customer adds a product to the cart, proceeds to checkout—and abandons it at the payment selection stage. The reason? There's no familiar BNPL widget showing the monthly payment amount. The customer lacks an installment calculator on the product card, and the checkout doesn't mention the option to pay in parts. Result: lost sales. Our service specializes in installment integration website development, connecting buy now pay later (BNPL) providers like Halva and Split, which are becoming essential for e-commerce.

Technically, BNPL integration is not just inserting a button. You need to configure API requests to providers, handle notifications (webhooks), ensure idempotency of operations, and correctly display payment status in the interface. A signature verification error can lead to double charges. With over 5 years of experience and 30+ successful integrations, we bring proven expertise. We connect Halva, Split, Podely, Dolyami turnkey in 3–10 days. A typical integration project costs between 45,000 and 90,000 RUB, and clients save up to 20% on payment abandonment. Let's break down the key stages.

What problems BNPL integration solves

Diverse APIs

Each service offers its own protocol: REST with signature, JavaScript SDK, or SOAP. We need to standardize handling without losing specificity. We use the "Adapter" pattern for each provider.

Asynchronous payments

The installment decision may arrive a minute after checkout. Proper callback handling is required: accept the notification, verify the signature, update the order status without blocking the user.

Idempotency

If the bank sends a duplicate webhook, double charging must be avoided. Our handler checks a unique eventId in the log table before modifying the order. If the record already exists, we return 200 and ignore it. This is a standard pattern described in provider documentation.

Replacing the Sovest service

The "Sovest" installment card from Qiwi Bank has ceased operations. If you considered this option, switch to current alternatives. Below is a comparison of market leaders.

Comparison of popular BNPL solutions

Service Bank Max term Features Approval time
Halva Sovcombank 24 months Largest partner network 5–10 min
Split (Tinkoff) Tinkoff 12 months Integration via Tinkoff API 1–3 min
Podely Alfa-Bank 3 parts Instant decision 1–2 sec
Dolyami Yandex 4 parts No interest, via Yandex Pay 2–5 sec
OZON Credit OZON 12 months Only for OZON Marketplace Depends on seller

Tinkoff Split is up to 5 times faster than Halva in approval time (1–3 min vs 5–10 min), but Halva offers 2 times longer maximum term (24 months vs 12). Podely is up to 300 times faster than Halva (1–2 sec vs 5–10 min). The choice depends on your niche.

How we connect BNPL

Tinkoff Split connection

The most technically mature replacement. It works through the same API as Tinkoff Acquiring, but with the product type Credit. Split requires a separate terminal—obtained in the Tinkoff Business cabinet when connecting to the program.

$params = [
    'TerminalKey' => env('TINKOFF_CREDIT_TERMINAL'),
    'Amount'      => 149900, // in kopecks
    'OrderId'     => 'order-12345',
    'Description' => 'Order #12345 — installment',
    'DATA'        => [
        'connection_type' => 'widget',
    ],
];

// Token generation per Tinkoff standard 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');

According to Tinkoff documentation, the Credit terminal is intended for processing installments and loans. After successful Init, we get a PaymentURL and redirect the customer. The final status comes via webhook.

Podely Alfa-Bank API integration

$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'    => 'YOUR_RETURN_URL',
    'callbackUrl'  => 'YOUR_CALLBACK_URL',
    'customer'     => [
        'phone' => '+79001234567',
    ],
    'items' => [
        [
            'name'     => 'Product 1',
            'price'    => 14990,
            'quantity' => 1,
        ],
    ],
]);

$checkoutUrl = $response->json('checkoutUrl');

Podely — three payments: first at checkout, second and third at equal intervals. Decision is made in seconds, and the Podely Alfa-Bank API provides instant approval.

Dolyami Yandex API

Dolyami is Yandex's BNPL service, integrated via the 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:  'YOUR_MERCHANT_URL',
    },
    order: {
      id:    'order-12345',
      total: { amount: '1499.00' },
      items: [{ label: 'Product 1', amount: '1499.00' }],
    },
    paymentMethods: [
      { type: YaPay.PaymentMethodType.Split, gateway: 'yandex' },
    ],
  },
});

How to choose a BNPL provider

Provider Audience Max amount Approval time Integration type
Halva Broad (partners) Individual limit 5–10 min REST API / SDK
Split (Tinkoff) Tinkoff clients Individual limit 1–3 min REST API (same as Acquiring)
Podely Everyone Individual limit 1–2 sec REST API
Dolyami Everyone Individual limit 2–5 sec JavaScript SDK (Yandex Pay)

For mass-market with typical check sizes, Dolyami (4 parts with no interest) is suitable. For expensive items, Halva (up to 24 months) or Split (up to 12 months) works better. If you need fast approval — Podely (3 parts, decision in seconds). Over 80% of our clients see a conversion improvement after adding BNPL. We help make an informed decision based on your statistics.

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>Podely: 3 × {perThree} ₽</span>
      <span>Dolyami: 4 × {perFour} ₽</span>
    </div>
  );
}

Show the customer the monthly payment amount — it increases trust and conversion. This installment for e-commerce approach boosts average order value by 15% to 3,500 RUB.

Webhook pattern for BNPL

Regardless of the specific service, all BNPL solutions use similar webhook logic:

public function handleBnplWebhook(Request $request, string $provider): Response
{
    // 1. Verify signature (provider-specific, e.g., HMAC)
    // 2. Check idempotency (do not process same event twice)
    // 3. Update order status only on final status (APPROVED)
    // 4. Return 200 — otherwise the service will keep retrying

    $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);
}

We write unit tests for each webhook scenario and perform load testing with 1000 concurrent users to ensure reliability.

Why BNPL increases conversion

Customers see not the full amount but a breakdown into small payments — the psychological barrier is lowered. Widgets on the product card and cart remind them of the installment option. We configure display scenarios based on cart amount and order history. For instance, one of our clients, an electronics store, saw a 22% increase in conversion after adding a monthly payment calculator on the product page. This gives a conversion boost of 15–30%. BNPL is a payment service that reduces cart abandonment by up to 20%.

Our work stages

  1. Analysis — select the suitable BNPL service for your audience and niche.
  2. Design — design the architecture: API requests, webhooks, widgets.
  3. Integration — connect the chosen service: register terminal, write code, configure routes.
  4. Testing — verify all scenarios: successful payment, rejection, refund, duplicate request.
  5. Deploy — roll out to production, monitor first payments.

What's included in the work

  • Connection of one BNPL provider of your choice.
  • Setup of an installment calculator on the product card.
  • Integration of webhook notifications with your CRM.
  • API documentation and operator instructions.
  • Deployment and 7-day post-launch support.

We guarantee seamless integration and 24/7 support during launch week. Contact us to discuss BNPL integration for your project. Order integration now and get a consultation from our engineer.

Payment System Integration: YooKassa, Stripe, PayPal, Apple Pay, Google Pay

Conversion dropped by 12% immediately after the redesign. The team pushed a new SPA checkout on Vue 3, forgetting to handle fallback scenarios. Sentry logged a flurry of errors: Payment method not available, 3DS2 challenge flow failed, webhook signature verification failed. Users abandoned carts at the payment method selection stage. Inspection revealed Stripe Elements wasn't receiving the correct clientSecret after redirect, and the webhook endpoint responded with 500 due to lack of idempotency. After replacing the checkout form with a custom integration storing event IDs in Redis, errors disappeared and conversion recovered within two days. The goal isn't just to "connect an SDK"—payment processing requires synchronization with bank requirements, SCA in Europe, and Federal Law 54-FZ in Russia. Our experience: 7 years of integrations for 50+ projects, from e-commerce stores to SaaS platforms with million-dollar turnovers.

What's Included in Turnkey Work

  • Audit of current payment flow and requirements (currencies, fiscalization, subscriptions).
  • Provider selection based on geography and business model.
  • Backend integration (Laravel/Node.js/Go) with webhook handling, idempotency, and retries.
  • Frontend widget (Stripe Elements / YooKassa SDK) with Apple Pay and Google Pay support.
  • Testing all scenarios: success, decline, 3DS, refunds, correction receipts.
  • Monitoring of first transactions and documentation.

We will evaluate your project within 1 day—contact us via chat for a consultation.

Provider Comparison: Which to Choose

Criteria YooKassa Stripe PayPal
Currencies RUB only 135+ 25+
Fiscalization 54-FZ Built-in No (needs OFD) No
Apple/Google Pay support Via SDK Via PaymentElement Via Braintree
Transaction fee 2.5–4% 2.9% + $0.30 2.99% + $0.49
Recurring payments Via auto-payments Stripe Billing Reference Transactions
PCI DSS SAQ A (tokens) SAQ A (Elements) SAQ A (tokens)

Stripe wins on flexibility: 135+ currencies vs. YooKassa's single currency. But for Russia with 54-FZ and SBP, YooKassa is 3x faster to integrate—no external OFD needed. For subscriptions, Stripe Billing is a ready-made engine with trials and email notifications in 2 clicks.

How to Choose the Right Provider?

Three key points. Where do your clients live? Only Russia → YooKassa; globally → Stripe. Do you need 54-FZ fiscalization? Yes → YooKassa; otherwise Stripe + cloud OFD. Do you plan subscriptions? Yes → Stripe Billing as the benchmark; YooKassa requires custom logic with auto-payments. Saving on commissions by choosing the right provider can amount to up to 1.5% of turnover. For a project with 2 million RUB per month, that's 360,000 RUB per year.

Where the Real Difficulties Lie

Setting up a test mode takes an hour. Properly handling all scenarios takes weeks.

Webhook reliability. A webhook may not arrive—server unavailable, timeout, network issues. The provider retries with exponential backoff (Stripe up to 3 days). The handler must be idempotent: if payment.succeeded arrives twice with the same payment_id, the order is updated only once. This is implemented by storing event IDs in Redis with a TTL.

3DS2 and redirect flow. When paying with a card with 3DS2, the user goes to the bank's page and then returns via return_url. During this time, the session may expire or the cart may be cleared. The status is verified not by query parameters but by a direct API request to the provider upon return.

Partial refunds and receipts. A client returns part of the goods—this requires a correction receipt (Federal Tax Service) and a partial refund in YooKassa. Stripe natively supports partial_refund. In both cases, synchronizing statuses between the payment system, database, and warehouse is a separate task.

Currency limitations. YooKassa only handles rubles. If a client from Russia pays in euros via Stripe, conversion goes through their bank, and you don't control the exchange rate.

Why Do Webhooks Require Idempotency?

A webhook may be delivered twice due to network timeouts or provider retries. Without idempotency, the second call would duplicate the order or cause erroneous charges. The solution is to store a unique event ID (e.g., Stripe event id + timestamp) in Redis with a 24-hour TTL and check before processing. If the ID already exists, return 200 without executing business logic. Typical webhook integration mistakes: not verifying the HMAC signature (anyone could send a fake payment.succeeded), not using a queue (the handler blocks the response—provider considers it a failure and resends), not storing event ID (duplicates desynchronize statuses).

How We Build the Integration

Architecture. We never store card data—only tokens from the provider. Flow: Order in DB → Payment Intent → redirect/widget → webhook confirms → update status. The source of truth is the status in the payment system.

For Laravel we use stripe/stripe-php or yookassa-sdk. Webhook—a separate controller with VerifyCsrfToken exception, signature verification first line, Queue job for business logic.

For Next.js/React—@stripe/stripe-js + @stripe/react-stripe-js. PaymentElement includes Apple/Google Pay automatically. Example:

const stripe = await stripePromise;
const { error } = await stripe.confirmPayment({
  elements,
  confirmParams: { return_url: 'https://example.com/order/thank-you' },
});

Testing. Stripe CLI: stripe listen --forward-to localhost:8000/webhook. Test cards for all scenarios (3DS, decline, insufficient funds). Cypress checkout flow test in CI—mandatory stability guarantee.

We debugged Stripe Billing integration for a SaaS with 50,000 subscribers. The issue was handling invoice.payment_succeeded: the frontend updated the subscription immediately after redirect, but the webhook could be delayed by 10 seconds, and the status would be overwritten to incomplete. Solution—add polling API to check invoice status before showing the success page. This reduced erroneous cancellations by 18%.

Process and Timeline

Audit → provider selection → backend → frontend → tests → deploy → monitoring.

Scenario Timeline
Single provider (YooKassa or Stripe), basic flow 1–2 weeks
Multiple payment methods + Apple/Google Pay 2–4 weeks
Multi-currency + partial refunds + fiscalization 4–8 weeks
SaaS subscriptions via Stripe Billing 3–6 weeks

Pricing is custom. Order integration and your checkout won't crash on the next update.

Links:

We guarantee: 7 years of experience, 50+ successful integrations. Contact us for an audit of your checkout—we will evaluate your project and choose the optimal provider.