Integrating 1C-Bitrix with Apple Pay

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1173
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    745
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    976

Integrating 1C-Bitrix with Apple Pay

Apple Pay on a website is not a standalone payment system — it is a method of confirming a card payment through an Apple device. Technically, this means the buyer does not enter a card number; instead, they authorize the payment via Face ID or Touch ID, and the tokenized card data is transmitted to your acquiring bank. A common misconception is that you need to "connect Apple Pay separately." This is not the case: Apple Pay works on top of an already connected acquiring service that supports this method (YooKassa, Tinkoff, Sber, Stripe, and others).

Prerequisites

For Apple Pay to work on a website, you need:

  1. An acquiring service with Apple Pay support — check your contract with the bank or payment aggregator
  2. HTTPS — mandatory; Apple Pay does not work over HTTP
  3. Domain verification — Apple requires placing a file at /.well-known/apple-developer-merchantid-domain-association
  4. Merchant ID — created in Apple Developer Console, linked to the domain and certificate

Domain Verification

# nginx: serving a file without an extension
location /.well-known/apple-developer-merchantid-domain-association {
    default_type text/plain;
    alias /var/www/myshop/.well-known/apple-developer-merchantid-domain-association;
}

The verification file is downloaded from Apple Developer Console. In most cases, the acquiring service (YooKassa, Tinkoff) handles verification through their own services — you simply need to specify the domain in the aggregator's merchant portal.

Apple Pay Button in 1C-Bitrix

Apple Pay is displayed only in Safari on Apple devices. For all other browsers, the standard payment form is shown. In the sale.order.checkout component template or on the payment page:

// Check support before displaying the button
if (window.ApplePaySession && ApplePaySession.canMakePayments()) {
    document.querySelector('.apple-pay-button').style.display = 'block';
}

function startApplePay(orderTotal, orderId) {
    const request = {
        countryCode: 'RU',
        currencyCode: 'RUB',
        supportedNetworks: ['visa', 'masterCard', 'mir'],
        merchantCapabilities: ['supports3DS'],
        total: { label: 'My Store', amount: String(orderTotal) },
    };

    const session = new ApplePaySession(6, request);

    // Merchant validation — request to Apple via your server
    session.onvalidatemerchant = async (event) => {
        const res = await fetch('/bitrix/tools/apple_pay_validate.php', {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify({ validationURL: event.validationURL }),
        });
        session.completeMerchantValidation(await res.json());
    };

    // Received payment token
    session.onpaymentauthorized = async (event) => {
        const res = await fetch('/bitrix/tools/apple_pay_charge.php', {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify({ token: event.payment.token, orderId }),
        });
        const data = await res.json();
        session.completePayment(
            data.success ? ApplePaySession.STATUS_SUCCESS : ApplePaySession.STATUS_FAILURE
        );
        if (data.success) window.location.href = data.redirect;
    };

    session.begin();
}

Server-Side Merchant Validation

// /bitrix/tools/apple_pay_validate.php
$body = json_decode(file_get_contents('php://input'), true);
$validationUrl = filter_var($body['validationURL'] ?? '', FILTER_VALIDATE_URL);

$ch = curl_init($validationUrl);
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => json_encode([
        'merchantIdentifier' => APPLE_MERCHANT_ID,
        'displayName'        => 'My Store',
        'initiative'         => 'web',
        'initiativeContext'  => $_SERVER['HTTP_HOST'],
    ]),
    CURLOPT_SSLCERT        => APPLE_CERT_PATH,       // .pem merchant certificate file
    CURLOPT_SSLKEY         => APPLE_CERT_KEY_PATH,   // private key
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
]);
$merchantSession = curl_exec($ch);
curl_close($ch);

header('Content-Type: application/json');
echo $merchantSession; // pass directly to session.completeMerchantValidation

Token Processing via Acquiring Service

Apple Pay transmits an encrypted PKPaymentToken. It must be passed to your acquiring service:

// Example for YooKassa: /bitrix/tools/apple_pay_charge.php
$input   = json_decode(file_get_contents('php://input'), true);
$token   = $input['token'];
$orderId = (int)$input['orderId'];

$payment = $yookassaClient->createPayment([
    'amount'              => ['value' => getOrderAmount($orderId), 'currency' => 'RUB'],
    'payment_method_data' => [
        'type'         => 'apple_pay',
        'payment_data' => base64_encode(json_encode($token['paymentData'])),
    ],
    'capture'     => true,
    'description' => 'Order #' . $orderId,
], uniqid('', true));

// Update status in 1C-Bitrix on success
if ($payment->getStatus() === 'succeeded') {
    $bitrixPayment->setPaid('Y');
    $bitrixPayment->save();
}

Timeline

Task Duration
Domain verification, Merchant ID 0.5 day
JS button + server-side merchant validation 1 day
Token integration with acquiring service and testing 1 day