Это почти полное руководство по реализации Apple Pay на веб-сайте. Я пишу это, чтобы собрать все, что я нашел, в одном месте, пока я занимался реализацией.
Эта статья может быть длинной 😬, потому что я стараюсь объяснить все максимально подробно.

Что нужно для начала работы:

  • Платная учетная запись разработчика Apple. Бесплатный аккаунт не работает
  • Вам потребуется iPhone с поддержкой Apple Pay (iPhone 6 и новее, iPad Air 2 и новее, iPad mini 3 и новее, модели iPad Pro и компьютеры Mac с Touch ID). Я пытался использовать симулятор для этого. Но это не сработало. Я объясню это ниже.
  • Хостинг с SSL ИЛИ платная учетная запись ngrok
  • Вам нужен Mac

Настройте учетную запись продавца в учетной записи разработчика Apple.

Настройка идентификатора продавца

Сначала войдите в учетную запись разработчика Apple и перейдите в «Идентификаторы» в разделе «Сертификаты, идентификаторы и профили».

  1. Затем нажмите на синий значок «+», чтобы зарегистрировать новый идентификатор, выберите «Идентификаторы продавца» и «Продолжить».
  2. На экране «Регистрация идентификатора продавца» введите описание для идентификации идентификатора и введите идентификатор в стиле обратного домена.
    Например: если ваш домен — example.com, введите «merchant.productname.example.com», затем продолжите и зарегистрируйте идентификатор продавца.
  3. Теперь на экране «Сертификаты, идентификаторы и профили» выберите «Идентификаторы продавца» в правом раскрывающемся списке. Затем вы можете увидеть созданный вами идентификатор продавца. Нажмите здесь.
  4. Теперь вам нужно создать «Сертификат удостоверения продавца Apple Pay». Нажмите «Создать сертификат» под этим.
  5. Чтобы создать файл CSR, выполните следующие действия:
     – В папке Приложения на Mac откройте Утилиты и запустите Связка ключей.
     – В раскрывающемся меню "Связка ключей" выберите Доступ к цепочке ключей > Помощник по сертификатам > Запрос сертификата в центре сертификации.
     – В окне "Информация о сертификате" введите следующее:< br /> * Адрес электронной почты
    * Общее имя для вашего ключа, например. APPLE_PAY_MERCHANT_DEV_KEY
    * Оставьте адрес электронной почты ЦС пустым
    * В группе Запрос выберите вариант Сохранено на диск.
    * НЕ выбирайте Позвольте мне указать информацию о паре ключей.
     — Нажмите Продолжить и сохраните файл в нужном месте.
  6. В разделе Загрузить файл CSR нажмите Выбрать файл и загрузите файл CSR, созданный на предыдущем шаге. Нажмите Продолжить.
  7. Загрузите созданный сертификат удостоверения продавца. Сертификат будет называться merchant_id.cer.

Настройка учетной записи песочницы

Создайте учетную запись тестировщика песочницы
См. здесь: https://developer.apple.com/apple-pay/sandbox-testing/

  1. Войдите в App Store Connect.
  2. На главной странице щелкните Пользователи и доступ.
  3. В разделе «Песочница» щелкните Тестеры.
  4. Нажмите «+», чтобы настроить свои учетные записи тестировщика.
  5. Заполните форму информации о тестировщике и нажмите Пригласить.
  6. Выйдите из своего Apple ID на всех тестовых устройствах и снова войдите в свою новую учетную запись тестировщика песочницы.

Добавить тестовые карточки в учетную запись тестовой среды

  1. Обязательно выйдите из iCloud и войдите на тестовое устройство с помощью учетной записи тестера в песочнице.
  2. Перейдите в Wallet и нажмите «Добавить кредитную или дебетовую карту».
  3. Используя свои тестовые учетные данные, выполните шаги по добавлению новой карты с помощью ручного ввода.

Проблемы, с которыми я столкнулся здесь:

Я был в регионе, НЕ поддерживаемом Apple Pay, и я создал учетную запись песочницы и вошел в нее из Симулятора и моего iPad. Но не удалось добавить тестовые карты. Появлялось сообщение Не удалось настроить Apple Pay, произошла ошибка при настройке Apple Pay. Итак, что я сделал, я попросил одного из моих коллег в регионе, поддерживаемом Apple Pay, настроить учетную запись и добавить тестовые карты, войдя в свой iPhone, а затем я вошел в свой iPad, и он запросил CVV добавленных карт, и тогда я мог использовать мое устройство для тестирования Apple Pay 🥳.
После настройки учетной записи песочницы протестируйте его на этом демонстрационном сайте. Посетите этот сайт со своим тестовым устройством, и если он выдаст лист оплаты, все готово.
https://applepaydemo.apple.com

Подтвердите свой домен

Обратитесь к этому: https://developer.apple.com/documentation/applepaywebmerchantregistrationapi/preparing_merchant_domains_for_verification

Пожалуйста, убедитесь, что на сайте есть SSL. Apple Pay требуется для обслуживания веб-сайта в HTTPS.
Если вам нужно только для разработки, вы можете использовать для этого платную учетную запись ngrok. (Бесплатная учетная запись не работает, потому что у нее есть открывающаяся веб-страница, которая делает невозможной проверку домена Apple)

  1. Теперь снова вернитесь к «Сертификаты, идентификаторы и профили» в учетной записи Apple Developer и выберите «Идентификаторы продавца» в правом раскрывающемся списке, а затем нажмите на созданный идентификатор продавца.
  2. Внизу вы можете увидеть «Домены продавца», нажмите «Добавить домен».
  3. Введите адрес своего веб-сайта и нажмите «Сохранить».
  4. Затем он позволит вам загрузить файл и загрузить этот файл .txt, создать папку в корневом каталоге вашего хостинг-сервера как «.well-known» и загрузить туда этот файл.
    Теперь попробуйте этот URL в своем браузере, и он должен открыть текстовый файл.
    https://[DOMAIN_NAME]/.well-known/apple-developer-merchantid-domain-association
  5. Теперь на странице «Регистрация домена», где вы загрузили файл .txt, нажмите «Подтвердить». Затем он проверит файл, и вы увидите статус вашего домена «Проверено» зеленым цветом. 🥳

Внедрение Apple Pay на сайте

Теперь приступим к разработке 🎉

Сначала давайте посмотрим, как это работает, чтобы получить общее представление.

Реализация внешнего интерфейса — HTML, CSS, Javascript

Прежде чем продолжить, ознакомьтесь с рекомендациями Apple по человеческому интерфейсу в отношении Apple Pay,
https://developer.apple.com/design/human-interface-guidelines/technologies/apple-pay/introduction.

Примечание. Этот веб-сайт должен иметь протокол HTTPS и должен обслуживаться из проверенного домена.

  1. Показывать кнопку Apple Pay на своем веб-сайте HTML
    Я добавил «id» как «appleBtn» и установил язык
<!-- Apple Pay Button -->
<apple-pay-button id="appleBtn" buttonstyle="black" type="buy" locale="en-US"></apple-pay-button>

2. Затем в файле script.js мы сначала проверяем, поддерживается ли Apple Pay и может ли пользователь совершать платежи с помощью Apple Pay, и на основании этого показывать кнопку Apple Pay.
Очень важное примечание: пользователь требуется наличие платежного адреса в добавленных картах. В противном случае значение «canMakePayments» равно false.

if (window.ApplePaySession) {
    // Add your merchant identifier here
    var merchantIdentifier = 'merchant.xxxx.xxxxx.xxxx';

    var promise = ApplePaySession.canMakePaymentsWithActiveCard(merchantIdentifier);
    promise.then(function (canMakePayments) {
        if (canMakePayments) {
            // Show Apple Pay Button if eligible
            document.getElementById("appleBtn").style.display = "block";

            // Add Action to Apple Pay Button 
            document.getElementById("appleBtn").addEventListener('click', beginApplePay);
        }
    });
}
apple-pay-button {
  --apple-pay-button-width: 140px;
  --apple-pay-button-height: 30px;
  --apple-pay-button-border-radius: 5px;
  --apple-pay-button-padding: 5px 0px;
  display: none;
}

3. Определите действие кнопки.
 — Когда пользователь нажимает кнопку Apple Pay, session.begin() запускает платежный лист Apple Pay, и как только платежный лист отображается session.onvalidatemerchant вызывается функция.
 – Внутри объекта applePayValidateMerchantEvent есть свойство «validationURL», в котором указан URL-адрес, используемый для создания подтвержденного платежного сеанса.
- Мы должны передать этот «validationURL» нашему серверному API, чтобы запросить платежную сессию. Здесь я делаю запрос JQuery AJAX к серверному API с помощью validationURL. Затем наш серверный API запрашивает платежный сеанс у службы Apple Pay и возвращает данные платежного сеанса.
 – Затем мы передаем возвращенные данные сеанса платежа в функцию session.completeMerchantValidation.
 – Это активирует платежный лист Apple Payment, чтобы попросить пользователя авторизовать платеж с помощью Touch ID. или FaceID.
 – При успешной авторизации платежа вызывается обработчик session.onpaymentauthorized, и ему передается объект события, который содержит объект платежа, состоящий из данных токена платежа и данных платежа, которые включают идентификационные данные карты и может использоваться для зарядки пользователя.
- Нам нужно передать эти данные в серверную часть, а затем в платежную систему, и мы завершим или завершим платеж в соответствии с возвращенным статусом.
(Я напишу об этом взимании платы с пользователя с помощью платежной системы в отдельной статье. . )

function beginApplePay() {
    var request = {
        countryCode: 'US',
        currencyCode: 'USD',
        supportedNetworks: ['visa', 'masterCard', 'amex', 'discover'],
        merchantCapabilities: ['supports3DS'],
        total: { label: 'Your Store Details', amount: '15.44' },
    }
    
    // Build ApplePaySession(API_Version, Request Options );
    var session = new ApplePaySession(3, request);

    // Define On Payment Authorized Handler
    session.onpaymentauthorized = (event) => {
        const payment = event.payment;
        // You can see a sample `payment` object in an image below.
        // Use the token returned in `payment` object to create the charge on your payment gateway.
        // Pass these data to backend and it will return the payment status
        
        chargeCreationSucceeds = passPaymentData(payment); // Get payment status from backend

        if (chargeCreationSucceeds) {
            // Capture payment from Apple Pay
            session.completePayment(ApplePaySession.STATUS_SUCCESS);
        } else {
            // Release payment from Apple Pay
            session.completePayment(ApplePaySession.STATUS_FAILURE);
        }
    };

    // Define On Merchant Validation Handler
    session.onvalidatemerchant = function (applePayValidateMerchantEvent) {
        console.log(applePayValidateMerchantEvent.validationURL);

        // Validate the merchant
        validateMerchant(applePayValidateMerchantEvent.validationURL, session);
    };
    session.begin();
}

function validateMerchant(validationUrl, session) {
    $.ajax({
        type: 'POST',
        url: 'https://your-server-url.ngrok.com/validateSession',
        headers: {
            'Content-Type': 'application/json',
            'ngrok-skip-browser-warning': "1515515"
        },
        data: JSON.stringify({ "validationUrl": validationUrl }),
    }).done(function (data) {
        session.completeMerchantValidation(data);
    });
}

Реализация серверной части с помощью NodeJS

Чтобы настроить конечную точку на вашем сервере для создания платежного сеанса продавца, вам необходимо иметь два файла .pem. Здесь я больше всего застрял, и, наконец, это сработало благодаря ответу, который я нашел на форуме разработчиков Apple и в Stackoverflow.
Я очень благодарен ребятам, которые ответили на эти вопросы. ❤️
https://developer.apple.com/forums/thread/107148
https://stackoverflow.com/a/15144560
Больше нигде не нашел упоминая об этом.

Итак, вот как вы создаете эти 2 файла.
1. Сначала дважды щелкните файл «merchant_id.cer», и он будет импортирован в Keychain Access.
2. Затем необходимо экспортировать сертификат в формат .p12.

Невозможно экспортировать SSL-сертификат Apple в формате .p12

3. Затем сделайте это, перейдите в Связка ключей и найдите сертификат, а затем перейдите в Мои сертификаты и найдите имя сертификата. он появится в списке.
Странная ошибка Keychain Access, на которую указал этот парень. 😂
https://stackoverflow.com/a/65287040/5939682
Уважаемый Apple, исправьте эту ошибку. Как и Гейб, я потратил около 2 часов на поиски этого. 🙄
4. Затем выполните следующие 2 команды, чтобы сгенерировать файлы сертификата и ключа.

openssl pkcs12 -in Certificates.p12 -out applepay.crt.pem -clcerts -nokeys
openssl pkcs12 -in Certificates.p12 -out applepay.key.pem -nocerts -nodes

5. Теперь вы можете запросить платежную сессию с помощью этих ключей.
Обратитесь к этому:
https://developer.apple.com/documentation/apple_pay_on_the_web/apple_pay_js_api/requesting_an_apple_pay_payment_session

Параметры запроса

merchantIdentifier -Ваш идентификатор продавца.

displayName -Строка из 64 или менее символов UTF-8, содержащая каноническое название вашего магазина, подходящее для отображения. Не локализуйте название. Используйте только символы из поддерживаемых наборов символов в шрифтах, перечисленных в таблице ниже.

initiative — Предопределенное значение, идентифицирующее приложение электронной коммерции, отправляющее запрос.

initiativeContext -Значение, которое вы предоставляете на основе инициативы.

Значения для initiative и initiativeContext зависят от типа приложения, которое вы создаете:

  • Для Apple Pay в Интернете используйте “web” для параметра initiative. Для параметра initiativeContext укажите свое полное доменное имя, связанное с вашим сертификатом удостоверения продавца Apple Pay.
  • Для Apple Messages for Business используйте “messaging” для параметра initiative. В качестве параметра initiativeContext укажите URL своего платежного шлюза. Дополнительную информацию см. в разделе Интерактивный тип.

На поддерживаемых моделях MacBook Pro на сенсорной панели отображается значение, которое вы указываете для параметра displayName.

const express = require('express');
const bodyParser = require('body-parser');
const https = require("https");
const cors = require('cors');
const fs = require('fs');
const path = require('path');
const axios = require('axios');
const port = process.env.PORT || 8080;

// Configure express to use body parser and cors, and add our API endpoints
const app = express();
app.use(cors({ origin: '*' }));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.post('/validateSession', async (req, res) => {
    const { appleUrl } = req.body;

    // use set the certificates for the POST request
    httpsAgent = new https.Agent({
        rejectUnauthorized: false,
        cert: fs.readFileSync(path.join(__dirname, './certs/applepay.crt.pem')),
        key: fs.readFileSync(path.join(__dirname, './certs/applepay.key.pem')),
    });

    response = await axios.post(
        appleUrl,
        {
            merchantIdentifier: 'merchant.xxxx.xxxxx.xxxx',
            displayName: "Your Business Name",
            initiative: "web",
            initiativeContext: "your-verified-domain.com"
        },
        {
            httpsAgent,
        }
    );
    res.send(response.data);
});

app.listen(port, () => {
    console.log('💪 Server running on ➡️ ', `http://localhost:${port}`);
});

Это проверяет продавца и запрашивает платежный сеанс и возвращает его на сторону клиента.

Часть, в которой вы взимаете плату с пользователя за платежный процессор, не включена в эту статью. Потому что для каждого платежного процессора правила разные.
Но я сделаю все возможное, чтобы написать еще одну статью об этой части.

Вот и все 🥳🎉
Теперь у вас должна быть возможность протестировать реализацию Apple Pay на вашем веб-сайте.
Если вы обнаружите какие-либо проблемы или вам нужно что-то добавить или изменить в статье, не стесняйтесь комментировать. и дайте мне знать.
Если вам нужна помощь, просто укажите в комментарии, и я помогу вам в этом.

Особая благодарность замечательным разработчикам, посвятившим свое драгоценное время поддержке сообщества разработчиков. ❤️✌🏻

Я должен упомянуть Jagdeep Singh, огромное спасибо вам за ваш git readme Apple Pay on Web. я даже скопировал некоторые части из своего ридми в эту статью, потому что они были просто идеальными 👌🏻.

И спасибо Ioan Ghisoi за его пост на Medium на тему Пример Apple Pay + Payments 2 🫡

И спасибо пользователям stackoverflow: Gabe, kmx, nickdnk 🫡
Пользователи форума Apple Developer: asumaran, alexmarion 🫡