О насБлогКонтакты
Бизнес и продукт5 декабря 2016 г. 4 мин 160Обновлено: 18 мая 2026 г.

Apple Pay и Google Pay в веб-приложении: что было реально в 2016 году (Россия)

AunimedaAunimeda
📋 Содержание

Apple Pay и Google Pay в веб-приложении: что было реально в 2016 году (Россия)

Коротко: Payment Request API (W3C, 2016) - единый интерфейс для Apple Pay, Android Pay и сохранённых карт. Chrome 53+ на Android поддерживал его. Safari на iOS 10+ поддерживал Apple Pay. В России в 2016 году поддержку имели Яндекс.Касса, Сбербанк Онлайн и несколько банков. Для реального использования - нужен банк-эквайер с поддержкой.


Что такое Payment Request API

// W3C Payment Request API - стандартизованный интерфейс оплаты в браузере
// Браузер показывает нативный диалог оплаты
// Пользователь не вводит данные карты - использует сохранённые в устройстве

// Поддержка в 2016:
// Chrome 53+ on Android - Google Pay / сохранённые карты
// Safari 10+ on iOS/macOS - Apple Pay (только Apple устройства)
// Edge - Microsoft Pay (позже)
// Firefox - не поддерживал

if (!window.PaymentRequest) {
    // Браузер не поддерживает Payment Request API
    // Показать обычную форму карты
    showTraditionalCheckout();
    return;
}

Интеграция Payment Request API

// checkout.js - Payment Request API для веб-магазина

async function startPayment(cart) {
    // Методы оплаты
    const paymentMethods = [
        {
            supportedMethods: 'basic-card',  // Стандартные банковские карты
            data: {
                supportedNetworks: ['visa', 'mastercard', 'mir'],
                supportedTypes: ['debit', 'credit']
            }
        },
        // Android Pay (2016 name, later renamed Google Pay)
        {
            supportedMethods: 'https://android.com/pay',
            data: {
                merchantName:  'Мой Магазин',
                merchantId:    'your-merchant-id',
                environment:   'PRODUCTION',  // или 'TEST'
                allowedCardNetworks:    ['VISA', 'MASTERCARD'],
                paymentMethodTokenizationParameters: {
                    tokenizationType: 'PAYMENT_GATEWAY',
                    parameters: {
                        gateway:          'yandexkassa',  // Ваш эквайер
                        gatewayMerchantId: 'your-ykassa-id'
                    }
                }
            }
        },
        // Apple Pay
        {
            supportedMethods: 'https://apple.com/apple-pay',
            data: {
                version:          3,
                merchantIdentifier: 'merchant.ru.myshop',
                merchantCapabilities: ['supports3DS'],
                supportedNetworks: ['visa', 'masterCard'],
                countryCode:       'RU'
            }
        }
    ];

    // Что показывать в диалоге оплаты
    const paymentDetails = {
        id:          'order-' + cart.orderId,
        displayItems: cart.items.map(item => ({
            label:  item.name,
            amount: { currency: 'RUB', value: String(item.price) }
        })),
        shippingOptions: [
            {
                id:       'courier',
                label:    'Курьер (1 день)',
                amount:   { currency: 'RUB', value: '300' },
                selected: true,
            },
            {
                id:       'pickup',
                label:    'Самовывоз',
                amount:   { currency: 'RUB', value: '0' },
            }
        ],
        total: {
            label:  'Итого',
            amount: { currency: 'RUB', value: String(cart.total + 300) }
        }
    };

    const options = {
        requestShipping:     true,
        requestPayerName:    true,
        requestPayerEmail:   true,
        requestPayerPhone:   true,
        shippingType:        'delivery',
    };

    try {
        const request = new PaymentRequest(paymentMethods, paymentDetails, options);

        // Обновить итог при смене способа доставки
        request.addEventListener('shippingoptionchange', event => {
            const selectedOption = request.shippingOption;
            const shippingCost  = selectedOption === 'pickup' ? 0 : 300;

            event.updateWith({
                ...paymentDetails,
                total: {
                    label:  'Итого',
                    amount: { currency: 'RUB', value: String(cart.total + shippingCost) }
                }
            });
        });

        // Проверить что хотя бы один метод поддерживается
        const canMakePayment = await request.canMakePayment();
        if (!canMakePayment) {
            showTraditionalCheckout();
            return;
        }

        // Показать диалог
        const paymentResponse = await request.show();

        // Отправить платёжные данные на сервер
        const serverResponse = await processPaymentOnServer(paymentResponse);

        if (serverResponse.success) {
            paymentResponse.complete('success');
            redirectToOrderSuccess(serverResponse.orderId);
        } else {
            paymentResponse.complete('fail');
            showError('Ошибка оплаты: ' + serverResponse.error);
        }

    } catch (error) {
        if (error.name === 'AbortError') {
            console.log('Пользователь отменил оплату');
        } else {
            console.error('Payment Request error:', error);
            showTraditionalCheckout();
        }
    }
}

async function processPaymentOnServer(paymentResponse) {
    const response = await fetch('/api/process-payment', {
        method:  'POST',
        headers: { 'Content-Type': 'application/json' },
        body:    JSON.stringify({
            methodName:      paymentResponse.methodName,
            details:         paymentResponse.details,  // Токен или данные карты
            payerName:       paymentResponse.payerName,
            payerEmail:      paymentResponse.payerEmail,
            payerPhone:      paymentResponse.payerPhone,
            shippingAddress: paymentResponse.shippingAddress,
            shippingOption:  paymentResponse.shippingOption,
        })
    });
    return response.json();
}

Apple Pay Domain Verification

# Для Apple Pay требуется верификация домена
# Создать файл в корне сайта:
mkdir -p .well-known
# Скачать файл с Apple Developer Portal
# Поместить в: .well-known/apple-developer-merchantid-domain-association

# nginx: раздавать файл без расширения
location = /.well-known/apple-developer-merchantid-domain-association {
    default_type text/plain;
    root /var/www/html;
}

Серверная обработка Apple Pay токена

<?php
// ProcessPaymentController.php

public function process(Request $request): JsonResponse {
    $methodName = $request->input('methodName');
    $details    = $request->input('details');

    switch ($methodName) {
        case 'https://apple.com/apple-pay':
            // Apple Pay: details содержит зашифрованный токен
            // Передаём в платёжный шлюз (Яндекс.Касса, Сбербанк)
            $result = $this->yandexKassa->chargeApplePay($details['token']);
            break;

        case 'https://android.com/pay':
            // Android Pay: details содержит tokenized payment data
            $result = $this->yandexKassa->chargeAndroidPay($details['paymentToken']);
            break;

        case 'basic-card':
            // Обычная карта
            $result = $this->yandexKassa->chargeCard([
                'cardNumber' => $details['cardNumber'],
                'cardExpiry' => $details['cardExpiryMonth'] . '/' . $details['cardExpiryYear'],
                'cardCVC'    => $details['cardSecurityCode'],
            ]);
            break;

        default:
            return response()->json(['success' => false, 'error' => 'Unknown payment method']);
    }

    return response()->json([
        'success' => $result['status'] === 'success',
        'orderId' => $result['orderId'] ?? null,
        'error'   => $result['error']   ?? null,
    ]);
}

Реальность 2016 года в России

Метод Браузерная поддержка Банков-эквайеров с поддержкой
Apple Pay Web Safari 10+ Яндекс.Касса, ВТБ, Сбербанк
Android Pay Chrome 53+ Android Яндекс.Касса
basic-card (Payment Request API) Chrome 53+, Edge Все через Яндекс.Кассу
Обычная форма Все Все

Мы внедрили Payment Request API в конце 2016 года. Конверсия на устройствах с поддержкой выросла на 18%: нативный диалог проще, чем 10-полевая форма карты.

Наибольший эффект - на мобильных устройствах. Набирать данные карты на телефоне сложно. Нажать кнопку Face ID/отпечаток - легко.

Читайте также

Как подключить ЮKassa (Яндекс.Касса) к PHP-сайту в 2015 годуaunimeda
Бизнес и продукт

Как подключить ЮKassa (Яндекс.Касса) к PHP-сайту в 2015 году

ЮKassa (тогда называлась Яндекс.Касса) в 2015 году была стандартом приёма онлайн-платежей в России для малого и среднего бизнеса. Вот точная интеграция: создание платёжной формы, обработка callback, проверка подписи, работа с webhooks. PHP без внешних библиотек.

Первый SaaS из Самары в 2013 году: от идеи до первого платящего клиента за 4 месяцаaunimeda
Бизнес и продукт

Первый SaaS из Самары в 2013 году: от идеи до первого платящего клиента за 4 месяца

2013 год. SaaS как бизнес-модель в России только начинал формироваться. Мы решили сделать сервис для управления клиентскими заявками для небольших сервисных компаний. Вот хронология: PHP 5.4, CodeIgniter, Bootstrap 2 и как мы нашли первого платящего клиента буквально на улице.

IT аутсорсинг в Кыргызстан для российских компаний: как это работает в 2026aunimeda
Веб-разработка

IT аутсорсинг в Кыргызстан для российских компаний: как это работает в 2026

Почему российские компании всё чаще заказывают разработку у кыргызских студий: ценовое преимущество, общий язык, часовой пояс. Как организовать работу с командой из Бишкека.

Нужна IT-разработка для вашего бизнеса?

Разрабатываем сайты, мобильные приложения и AI-решения для бизнеса в России. Бесплатная консультация.

Получить консультацию Все статьи