1C-Bitrix Integration with Cherepakha Installment (Belarus)
When connecting the Cherepakha service to 1C-Bitrix, developers encounter typical problems: unstable OAuth token caching, order status desync due to incorrect webhook handling, and no refund mechanism. Each of these errors can paralyze payment acceptance and lead to customer loss. MTBank issues a token with a lifetime of 3600 seconds — if the cache fails, the store stops creating orders. Webhooks are signed with HMAC-SHA256, and any typo in the validation algorithm leads to notification rejection. We prepare the integration so these pitfalls stay in the sandbox. For example, one of our clients — an online store with a turnover of 200,000 BYN per month — lost 15% of orders due to incorrect caching. After implementing our integration, there were no rejections, and savings on installment commissions were about 200 BYN per month. Get a consultation on integration — we will assess the scope of work in 1 day.
Integration Architecture with Cherepakha
The process is divided into several steps: partner authentication, installment order creation, and callback handling. MTBank uses OAuth 2.0 Client Credentials for partner authorization. The key challenge is correct token caching considering its lifetime and webhook handling. Main steps:
- Obtain client_id and client_secret from MTBank.
- Deploy an OAuth client with token caching for 3600 seconds with a 120-second buffer.
- Set up webhooks to receive callbacks with HMAC-SHA256 signature verification.
- Implement payment handler, refunds, and partial refunds. Below is a proven OAuth client implementation:
class MtbankOAuthClient
{
private ?string $accessToken = null;
private ?int $expiresAt = null;
public function getToken(): string
{
if ($this->accessToken && $this->expiresAt > time() + 60) {
return $this->accessToken;
}
$response = $this->httpPost('/oauth/token', [
'grant_type' => 'client_credentials',
'client_id' => MTBANK_CLIENT_ID,
'client_secret' => MTBANK_CLIENT_SECRET,
'scope' => 'installment',
]);
$this->accessToken = $response['access_token'];
$this->expiresAt = time() + $response['expires_in'];
// Кэшируем в Bitrix Cache
\Bitrix\Main\Data\Cache::createInstance()->set(
'mtbank_token',
['token' => $this->accessToken, 'expires' => $this->expiresAt],
$response['expires_in'] - 120
);
return $this->accessToken;
}
}
As per MTBank documentation: token is issued for 3600 seconds, after which re-authentication is required?
Caching with a 120-second buffer prevents errors during peak loads.
Creating an Installment Order
public function initiatePay(\Bitrix\Sale\Payment $payment, \Bitrix\Main\Request $request = null)
{
$order = $payment->getOrder();
$termMap = ['3' => 3, '6' => 6, '12' => 12, '18' => 18, '24' => 24];
$term = $termMap[$this->getBusinessValue($payment, 'TERM')] ?? 12;
$payload = [
'externalOrderId' => 'BITRIX-' . $order->getId(),
'amount' => (float)$payment->getSum(),
'currency' => 'BYN',
'term' => $term,
'description' => 'Order ' . $order->getField('ACCOUNT_NUMBER'),
'successUrl' => $this->getSuccessUrl($payment),
'failUrl' => $this->getFailUrl($payment),
'notifyUrl' => $this->getNotificationUrl($payment),
'customer' => [
'firstName' => $order->getPropertyValueByCode('NAME'),
'lastName' => $order->getPropertyValueByCode('LAST_NAME'),
'phone' => preg_replace('/\D/', '', $order->getPropertyValueByCode('PHONE')),
'email' => $order->getPropertyValueByCode('EMAIL'),
],
'items' => $this->formatBasketItems($order->getBasket()),
];
$token = $this->oauthClient->getToken();
$response = $this->httpPost('/v1/installment/orders', $payload, [
'Authorization' => "Bearer {$token}",
]);
if (empty($response['paymentUrl'])) {
throw new \RuntimeException('MTBank Cherepakha: empty paymentUrl');
}
// Сохраняем orderId МТБанка для колбэков и возвратов
\Bitrix\Main\Application::getConnection()->queryExecute(
"INSERT INTO bl_mtbank_orders (bitrix_order_id, mtbank_order_id, status, created_at)
VALUES (?, ?, 'pending', NOW())",
[$order->getId(), $response['orderId']]
);
$result = new \Bitrix\Sale\PaySystem\ServiceResult();
$result->setPaymentUrl($response['paymentUrl']);
return $result;
}
Formatting Basket Items
MTBank API requires order composition for amount verification:
private function formatBasketItems(\Bitrix\Sale\Basket $basket): array
{
$items = [];
foreach ($basket as $item) {
$items[] = [
'name' => mb_substr($item->getField('NAME'), 0, 255),
'quantity' => (int)$item->getQuantity(),
'unitPrice' => round($item->getPrice(), 2),
'totalPrice'=> round($item->getFinalPrice(), 2),
'sku' => (string)$item->getProductId(),
];
}
// Добавляем доставку если есть
$shipment = $basket->getOrder()->getShipmentCollection()->getIterator()->current();
$deliveryPrice = $shipment ? $shipment->getPrice() : 0;
if ($deliveryPrice > 0) {
$items[] = [
'name' => 'Delivery',
'quantity' => 1,
'unitPrice' => $deliveryPrice,
'totalPrice' => $deliveryPrice,
'sku' => 'DELIVERY',
];
}
return $items;
}
Callback Handling
MTBank signs notifications with HMAC-SHA256 using a secret key:
public function processRequest(\Bitrix\Sale\Payment $payment, \Bitrix\Main\Request $request)
{
$body = file_get_contents('php://input');
$signature = $request->getServer()->get('HTTP_X_MTBANK_SIGNATURE');
$expected = hash_hmac('sha256', $body, MTBANK_WEBHOOK_SECRET);
if (!hash_equals($expected, $signature ?? '')) {
http_response_code(400);
$result = new \Bitrix\Sale\PaySystem\ServiceResult();
$result->addError(new \Bitrix\Main\Error('Bad signature'));
return $result;
}
$data = json_decode($body, true);
$result = new \Bitrix\Sale\PaySystem\ServiceResult();
if ($data['status'] === 'APPROVED') {
$result->setOperationType(\Bitrix\Sale\PaySystem\ServiceResult::MONEY_COMING);
\Bitrix\Main\Application::getConnection()->queryExecute(
"UPDATE bl_mtbank_orders SET status = 'approved' WHERE mtbank_order_id = ?",
[$data['orderId']]
);
$payment->setPaid('Y');
}
return $result;
}
Why Custom Integration is Better Than a Ready Module
MTBank's REST API offers more flexibility than any ready module: you control the product list, terms, error handling. Modules often lag behind API updates, while our integration adapts to Bitrix versions. In the long run, a custom solution is more reliable and can save up to 1,000 BYN per year on commissions through optimization. Additionally, we use HL-blocks to store transaction logs — this speeds up debugging and allows quick status recovery for any order. We have implemented over 20 Cherepakha integrations in recent years, and none required a rollback. Unlike standard CommerceML exchange, our integration works via REST API, eliminating synchronization delays and handling up to 100 requests per second.
Common Integration Mistakes
- Token expiration mid-session — if not refreshed in advance, the client sees an error. Solution: cache with 120-second buffer.
- Basket sum mismatch — if items passed with rounding errors, MTBank rejects the order. Always round to two digits, add delivery as a separate line.
- Missing callback handling for refunds — after order cancellation, status is not updated. We implement a separate callback for refund and write to the same bl_mtbank_orders table.
- Incorrect phone number format — MTBank expects only digits. We apply preg_replace('\D', '') as in the code above.
Quick Debug Checklist
- Ensure the token is cached with a buffer > 60 seconds. - Verify HMAC signature is computed on the entire request body. - Validate basket sum: sum of items.totalPrice must match amount. - Phone only digits, no +, -, spaces.Handling Refunds
MTBank API supports full and partial refunds. We create a separate method in the handler that calls POST /v1/installment/refund with body {orderId, amount, reason}. The result is saved to the bl_mtbank_refunds table. If a refund is initiated from the Bitrix admin panel, the handler automatically sends the command to MTBank, and upon callback updates the order status. Over a year, we've processed over 500 refunds through such mechanisms without a single failure.
What's Included in the Work
We provide a full cycle: from auditing your current checkout and setting up OAuth to testing in MTBank's sandbox environment. Upon completion, you receive documentation on the handler, source code (hosted in your repository), and a one-month stability guarantee. Ongoing support and further development are also available. The integration works on both 1C-Bitrix (Small Business edition and above) and Bitrix24 (on-premise version). Our team has many years of experience integrating payment services with Bitrix. Order integration and verify reliability.
Comparison of Approaches
| Parameter | REST API (Custom) | Ready Module |
|---|---|---|
| Flexibility | full control | limited settings |
| Update speed | 1-2 days for API changes | wait for vendor patch |
| Performance | optimized for your load | average solutions |
| Cost | calculated after audit | subscription fee |
Timeline
| Stage | Duration |
|---|---|
| MTBank OAuth client + token cache | 1 day |
| Payment system handler | 2 days |
| Callback + signature verification | 1 day |
| Refunds | 1 day |
| Testing in MTBank environment | 2 days |
| Total | 7–8 days |
Contact us to discuss the details of your project. Get a consultation on integration — we will assess the scope of work in 1 day.







