1C-Bitrix Integration with Payme (Uzbekistan) – JSON-RPC Guide

Integration of 1C-Bitrix with Payme (Uzbekistan) We’ve repeatedly encountered situations where an online store on Bitrix loses 30–40% of orders simply because it doesn’t accept Payme — the leading payment tool in Uzbekistan with over 10 million active users. There’s no official module for Bitrix,

Our competencies:

Frequently Asked Questions

Integration of 1C-Bitrix with Payme (Uzbekistan)

We’ve repeatedly encountered situations where an online store on Bitrix loses 30–40% of orders simply because it doesn’t accept Payme — the leading payment tool in Uzbekistan with over 10 million active users. There’s no official module for Bitrix, so a custom JSON‑RPC handler is required. Without it, conversion in the region stays low and clients turn to competitors. We, a team with over 7 years of Bitrix development experience and more than 50 payment integrations, will break down how to build a proper integration with guaranteed idempotency and correct currency handling.

How Payme’s Subscribe API Works

Payme does not use redirects — instead, the Payme server calls your server over the JSON‑RPC protocol. The store implements six mandatory methods, each must respond within 1–2 seconds. Timing violations cause payments to hang.

Method Purpose
CheckPerformTransaction Verify order and amount (in tiyins)
CreateTransaction Start payment, create record
PerformTransaction Confirm debit
CancelTransaction Cancel (different scenarios)
CheckTransaction Return transaction state
GetStatement Statement for reconciliation

Your own JSON‑RPC endpoint (e.g., local/api/payme.php) processes all these methods, checks authorization via Basic Auth, and returns strictly defined structures.

Why Idempotency Matters and How to Achieve It

If Payme sends CreateTransaction twice, the same payment could be charged twice. We solve this with a dedicated table b_payme_transactions, where the primary key is payme_id. A duplicate request with the same payme_id returns the existing transaction instead of creating a new one. This prevents double debits and satisfies Payme API requirements (see JSON‑RPC documentation).

CREATE TABLE b_payme_transactions ( payme_id VARCHAR(64) PRIMARY KEY, order_id INT NOT NULL, amount BIGINT NOT NULL, state TINYINT DEFAULT 1, create_time BIGINT, perform_time BIGINT DEFAULT 0, cancel_time BIGINT DEFAULT 0, reason TINYINT DEFAULT NULL ); 

States: 1 — created, 2 — successfully performed, -1/-2 — cancelled at various stages.

Typical Errors and Solutions

Error Cause Solution
-31001 Amount mismatch Verify conversion to tiyins and rounding
-31050 Order not found Ensure order_id is passed correctly
-32504 Authorization error Check Basic Auth password
Timeout Slow server response Optimize SQL queries and caching

Server Implementation in Bitrix (Case Study)

The entry point is a separate PHP file, independent of the public part. It handles all six methods. Below is the key snippet for CheckPerformTransaction:

<?php define('NO_KEEP_STATISTIC', true); define('NOT_CHECK_PERMISSIONS', true); require_once $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php'; header('Content-Type: application/json'); // Basic Auth — password must match the key from Payme cabinet $auth = $_SERVER['HTTP_AUTHORIZATION'] ?? ''; preg_match('/Basic (.+)/', $auth, $m); [, $password] = explode(':', base64_decode($m[1] ?? ''), 2); if (!hash_equals(PAYME_CASHIER_KEY, $password)) { echo json_encode(['error' => ['code' => -32504, 'message' => 'Auth failed']]); exit; } $body = json_decode(file_get_contents('php://input'), true); $method = $body['method'] ?? ''; $params = $body['params'] ?? []; $id = $body['id'] ?? null; if ($method === 'CheckPerformTransaction') { $orderId = (int)($params['account']['order_id'] ?? 0); $amount = (int)($params['amount'] ?? 0); // in tiyins $order = Bitrix\Sale\Order::load($orderId); if (!$order) { echo json_encode(['error' => ['code' => -31050, 'message' => ['ru' => 'Order not found']], 'id' => $id]); exit; } // Compare amounts (store prices in UZS, multiplied by 100) $expected = (int)round($order->getPrice() * 100); if ($expected !== $amount) { echo json_encode(['error' => ['code' => -31001, 'message' => ['ru' => 'Amount mismatch']], 'id' => $id]); exit; } echo json_encode(['result' => ['allow' => true], 'id' => $id]); exit; } if ($method === 'PerformTransaction') { $paymeId = $params['id']; // Find payment by payme_id and confirm $payment = findPaymentByPaymeId($paymeId); if ($payment && !$payment->isPaid()) { $payment->setPaid('Y'); $payment->save(); } echo json_encode(['result' => [ 'transaction' => $paymeId, 'perform_time' => time() * 1000, 'state' => 2, ], 'id' => $id]); exit; } 

The remaining methods follow the same pattern. In CreateTransaction, it's important to return create_time and state = 1. In CancelTransaction, check whether Perform was already executed and return the correct state (-1 or -2).

Currency and Tiyin Conversion

Payme accepts only Uzbek soms, and amounts are transmitted in tiyins (1 UZS = 100 tiyins). If store prices are in a foreign currency (USD/EUR), we convert using the Central Bank of Uzbekistan rate, cached for 1 hour.

$amountTiyin = (int)round($orderPriceUsd * $uzsPerUsd * 100); 

An off-by-one error in rounding will cause rejection in CheckPerformTransaction — so precise matching is critical.

Testing

Test endpoint: https://checkout.test.paycom.uz/. Test keys are issued separately from production ones. Be sure to test CancelTransaction at different stages — behaviour changes. On average, debugging takes 1–2 days.

What the Integration Process Includes

  1. Design and analysis — clarify currency, settlement methods, refund logic.
  2. JSON‑RPC server development — implement all 6 methods with idempotency and logging.
  3. Integration with Bitrix Sale module — attach payments to orders, update statuses and payment flags.
  4. Currency conversion — if the store operates in USD/EUR, add a cached converter to UZS.
  5. Testing — manual and automated tests for every scenario (success, cancel, duplicate, error).
  6. Documentation and training — endpoint descriptions, request/response examples, instructions for managers.
  7. Post-launch support — 2 weeks of monitoring and fast fixes.

What’s Included in the Work

  • Implementation of the JSON-RPC server with all 6 methods and idempotency.
  • Integration with Bitrix Sale module: create payment system, bind to orders.
  • Currency conversion with caching of the Central Bank rate.
  • Testing in Payme test environment and on live data.
  • Documentation on endpoints and operation procedures.
  • Training for managers and administrators.
Additional OptionsWe also implement logging of all requests in a separate table for audit and monitoring.

Why It’s Worth It

Integrating Payme boosts conversion among Uzbek customers by 2–3 times. Compared to redirect gateways, direct JSON-RPC integration cuts payment processing time from 5–10 seconds down to 1–2 seconds. Our experience shows that a store recoups the integration cost within the first month of operating in the region; average savings on refunds amount to up to 5,000,000 UZS per month.

Order Payme integration for your 1C-Bitrix store — we guarantee compliance with Payme specification and launch within 1–2 weeks. Contact us to get a preliminary estimate within one business day.