Введение в Payment Request API для оплаты через Apple Pay

Введение в Payment Request API для оплаты через Apple Pay

От автора: рады сообщить, что Safari 11.1 на macOS и Safari на iOS 11.3 теперь поддерживают W3C Payment Request API для проведения транзакций Apple Pay в интернете. Впервые мы представили Apple Pay on the Web на macOS Sierra и iOS 10. Apple Pay сделал онлайн транзакции простыми в использовании, защищенными и конфиденциальными. Мы были рады увидеть, как массово ее стали применять продавцы в последующие годы.

Однако мы поняли, что продавцам необходимо иметь несколько способов оплаты, а это значит еще больше сложностей. Payment Request нацелен на снижение этой сложности, так как поддерживает способы оплаты в нескольких браузерах с помощью стандартного API. Сегодня я проведу вам пошаговый разбор того, как производится оплата через Apple Pay с помощью Payment Request. Если вы уже работали с Apple Pay JS, описанное ниже вам будет знакомо. Если нет – отличный шанс познакомиться!

Предварительные условия

Для дальнейшей работы вам необходимо зарегистрировать идентификатор продавца и настроить сервер на обработку транзакций Apple Pay. Подробное описание, как это сделать, можно найти в документации Apple Pay on the Web.

Отображение кнопок Apple Pay

Транзакции Apple Pay всегда начинает покупатель, поэтому вам нужно отобразить кнопку Apple Pay, по которой они смогут нажать или кликнуть. WebKit предоставляет встроенную поддержку рендера кнопок Apple Pay для единообразного визуального представления. Как отобразить стандартную кнопку Apple Pay:

<button style="-webkit-appearance: -apple-pay-button;"></button>

Существуют другие типы кнопок с разными стилями. Вот такие кнопки вы могли видеть, покупая что-то в Safari:

Исходя из Apple Pay on the Web Human Interface Guidelines, необходимо отображать кнопки Apple Pay всегда, когда пользователь использует поддерживаемое устройство. Для проверки, поддерживает ли устройство покупателя Apple Pay, вызовите ApplePaySession.canMakePayments():

if (window.ApplePaySession && ApplePaySession.canMakePayments())

После того, как покупатель нажмет или кликнет на кнопку Apple Pay необходимо предоставить расчетный лист Apple Pay. Если у клиента нет привязанной карты, можно принять в Apple Pay. Safari подскажет, что нужно сделать, прежде чем продолжить транзакцию. Это правила Apple Pay, поэтому для настройки необходимо использовать Apple Pay JS ApplePaySession API. Напоминание о транзакции можно выполнить с помощью стандартного Payment Request API.

Создание PaymentRequest

После клика или нажатия на кнопку Apple Pay вы инициируете транзакцию путем создания нового PaymentRequest:

var request = null;
if (window.PaymentRequest) request = new PaymentRequest(methods, details, options);
else // Consider using Apple Pay JS instead.

Конструктор PaymentRequest принимает 3 аргумента: поддерживаемые вами методы оплаты, детали для отображения покупателю (варианты доставки и общая сумма, например) и любые необходимые вам опции.

Способы оплаты

Способы оплаты представляют собой инструменты, с помощью которых можно принимать платежи покупателей через Payment Request. Вы указываете принимаемые способы оплаты в виде последовательности словарей PaymentMethodData, каждый из которых содержит идентификатор (supportedMethods) и связанные с ним данные.

Подключите Payment Request как способ оплаты, чтобы использовать Apple Pay с Payment Request. Идентификатор способа платежа на основе URL в Apple Pay — «https://apple.com/apple-pay». Связанные с ним data – словарь ApplePayRequest. Как выглядит словарь PaymentMethodData для Apple Pay:

const applePayMethod = { supportedMethods: "https://apple.com/apple-pay", data: { version: 3, merchantIdentifier: "merchant.com.example", merchantCapabilities: ["supports3DS", "supportsCredit", "supportsDebit"], supportedNetworks: ["amex", "discover", "masterCard", "visa"], countryCode: "US", },
}; 

Safari поддерживает только способ оплаты Apple Pay, но в других браузерах способов может быть больше. Если вы указываете в запросе несколько способов оплаты, браузер сам решает, какой представить покупателю на основе доступности устройства и настроек пользователя.

Детали платежа

Детали платежа представляет словарь PaymentDetailsInit. Он содержит общую сумму транзакции, отображаемые элементы, специальные модификаторы для способа оплаты (подробнее о модификаторах ниже). Как выглядят валидные детали платежа за предмет стоимостью $20 плюс налог и 2 варианта доставки:

const paymentDetails = { total: { label: "My Merchant", amount: { value: "27.50", currency: "USD" }, }, displayItems: [{ label: "Tax", amount: { value: "2.50", currency: "USD" }, }, { label: "Ground Shipping", amount: { value: "5.00", currency: "USD" }, }], shippingOptions: [{ id: "ground", label: "Ground Shipping", amount: { value: "5.00", currency: "USD" }, selected: true, }, { id: "express", label: "Express Shipping", amount: { value: "10.00", currency: "USD" }, }],
};

Можно выбрать способ доставки по умолчанию. Для этого необходимо установить selected в true, как мы сделали для «Ground Shipping». Общая сумма платежа не должна быть отрицательной. Все общие суммы платежей в запросе должны использовать один валютный код ISO 4217 при использовании Apple Pay. Правильность платежных реквизитов зависит только от вас. Safari не проводит никаких валютных вычислений от вашего имени.

Что такое модификаторы?

В детали платежа можно подключить последовательность modifiers (необязательно). Модификаторы обновляют отображаемые в транзакции элементы и общую сумму при наступлении условий, указанных для выбранного способа оплаты. В Apple Pay с помощью модификаторов можно настраивать цену в зависимости от типа выбранной карты оплаты в списке Apple Pay. Например, следующий модификатор применяет скидку $1.00, если покупатель выбирает в Apple Pay дебетовую карту:

const debitModifier = { supportedMethods: "https://apple.com/apple-pay", data: { paymentMethodType: "debit" }, total: { label: "My Merchant", amount: { value: "26.50", currency: "USD" }, }, additionalDisplayItems: [{ label: "Debit Card Discount", amount: { value: "-1.00", currency: "USD" }, }],
};
<p>

Модификаторы предоставляют функциональность из события paymentmethodselected для Apple Pay JS. Подробности читайте в ApplePayModifier.

Опции оплаты

Опции оплаты представлены в словаре PaymentOptions. Запросить имя покупателя, email, телефон или тип доставки можно следующим образом:

const paymentOptions = { requestPayerName: true, requestPayerEmail: true, requestPayerPhone: true, requestShipping: true, shippingType: "shipping",
};

Если requestShipping установить в true, в списке отобразятся опции доставки, указанные в Payment Details. Вы получите запрошенную информацию, как только покупатель разрешит оплату.

Исключения

Safari может вызвать исключение при создании нового PaymentRequest. Исключения могут быть вызваны следующими причинами:

Frame не в безопасном контексте

Frame является общим subframe

Не определены способы оплаты

Неправильный идентификатор способа оплаты

Вызов JSON.stringify() на данных способа оплаты не удался

Указана неправильная денежная мумма (отрицательная общая сумма или несколько валют)

Метод canMakePayment()

После создания PaymentRequest его можно спросить, а сможет ли ваш клиент разрешить транзакцию, учитывая принимаемые вами способы оплаты. Для этого необходимо вызвать метод canMakePayment(), который возвращает promise (который резолвится в true или false). В Safari когда Apple Pay является одним из способов оплаты, canMakePayment() резолвится в true только в том случае, если у покупателя добавлена активная карта в Apple Pay. Это эквивалент работы ApplePaySession.canMakePaymentsWithActiveCard() в Apple Pay JS.

Как мы говорили в разделе «отображение кнопок Apple Pay», Apple Pay Human Interface Guidelines требует показывать кнопку Apple Pay, если покупатель использует поддерживаемые устройства, независимо от того, если ли у них активная добавленная карта или нет. Поэтому не нужно прятать кнопку Apple Pay, когда canMakePayment() резолвится в false. Всегда показывайте кнопку Apple Pay, если ApplePaySession.canMakePayments() возвращает true. Всегда предоставляйте список Apple Pay, когда покупатель кликает или нажимает на кнопку. Safari уведомит клиента, если у него не добавлена карта, прежде чем проводить транзакцию. Подробнее читайте в Human Interface Guidelines > Apple Pay on the Web.

Метод show()

После нажатия или клика на кнопку Apple Pay необходимо представить список Apple Pay. Для этого необходимо вызвать метод show(). Метод возвращает promise, который резолвится в PaymentResponse, как только покупатель разрешил оплату. Если покупатель отменил транзакцию, promis отклоняется с AbortError.

Можно вызвать show() с promise для PaymentDetailsUpdate (необязательно). Иногда вы можете находиться в процессе вычисления деталей оплаты, когда покупатель нажимает или кликает кнопку Apple Pay. В таком случае можно создать новый PaymentRequest с прейсхолдерами деталей, после чего вызвать show() с promise, чтобы позже подгрузить обновленные детали. После резолвинга promise Safari отобразит обновленные детали в списке Apple Pay.

Safari может отклонить promise, возвращенный show() с исключением. Исключения могут быть вызваны следующими причинами:

Show() не был вызван активацией пользователя (кликом или нажатием)

Запрос уже был прерван

Сессия Apple Pay уже активна

Неправильные данные платежа (например, не заполнены обязательные поля)

Метод abort()

Прервать транзакцию можно с помощью метода abort(). При этом Safari очищает список Apple Pay и отклоняет promise, возвращенный show() с AbortError. Если транзакция уже была отклонена, или show() еще не был вызван, вызов abort() выбросит InvalidStateError.

Валидация продавца

Чтобы Safari могу представить список Apple Pay, необходимо получить сессию платежа от Apple. Этот процесс называют валидацией продавца.

После вызова show() Safari отправляет событие merchantvalidation в ваш объект PaymentRequest. Событие определяет атрибут validationURL, представляющий Apple URL, с которым связывается ваш сервер для получения сессии платежа. Необходимо вызвать метод события complete() с promise, который вы будете резолвить этой сессией оплаты, как только получите ее.

Как выглядит обработчик события merchantvalidation:

request.onmerchantvalidation = function (event) { const sessionPromise = fetchPaymentSession(event.validationURL); event.complete(sessionPromise);
};

События доставки

После получения сессии продавца Safari отобразит список Apple Pay для покупателя. Если вы запрашивали доставку, покупатель сможет выбрать представленные способы доставки и адрес. После того, как пользователь заполнит эти поля, Safari отправляет событие shippingoptionchange или shippingaddresschange в ваш объект PaymentRequest.

Shippingoptionchange

Как только пользователь выбирает опцию доставки, Safari отправляет событие shippingoptionchange. В обработчике события можно определить выбранный способ доставки через атрибут shippingOption в PaymentRequest. Чтобы обновить детали платежа выбранным способом доставки, вызовите updateWith() на объекте события с promise, который резолвится в PaymentDetailsUpdate.

При запросе доставки в Apple Pay всегда необходимо следить за shippingoptionchange и вызывать updateWith() с promise, который резолвится в течение 30 секунд. В противном случае время транзакции истекает.

Shippingaddresschange

Как только пользователь заполняет адрес доставки, Safari отправляет событие shippingaddresschange. В обработчике события можно определить выбранный адрес доставки через атрибут shippingAddress в PaymentRequest. Чтобы обновить детали платежа выбранным адресом доставки, вызовите updateWith() на объекте события с promise, который резолвится в PaymentDetailsUpdate. Если вы не доставляете по выбранному адресу, можно написать сообщение об ошибке в PaymentDetailsUpdate, которое Safari покажет покупателю.

При использовании Apple Pay Safari может редактировать некоторые детали адреса доставки. Например, в США предоставляются только город, штат, ZIP-код из 5 цифр и округ. Safari предоставляет полный, неотредактированный адрес доставки, как только покупатель разрешает платеж.

При запросе доставки в Apple Pay всегда необходимо следить за shippingaddresschange и вызывать updateWith() с promise, который резолвится в течение 30 секунд. В противном случае время транзакции истекает.

Обработка разрешения платежа

Когда покупатель разрешает платеж, Safari резолвит promise , полученный вами от вызова show() с PaymentResponse. В зависимости от того, что запрошено в вашем PaymentOptions ответ может содержать выбранный вариант доставки, адрес доставки, имя, email и телефон покупателя.

Ответ также хранит в себе идентификатор способа оплаты, используемый для проведения транзакции (methodName) и связанные с ним details. Если в качестве способа оплаты выбран Apple Pay, связанные details – это словарь ApplePayPayment. ApplePayPayment содержит токен Apple Pay, с помощью которого вы обрабатываете разрешение платежа. Он также содержит счет и контактную информацию для доставки в виде ApplePayPaymentContacts, если вы запрашивали их в ApplePayRequest.

Когда вы закончили обработку разрешения платежа, необходимо вызвать ApplePayRequest метод complete() на PaymentResponse, чтобы показать результат обработки. Метод complete() можно вызвать со статусом «success» или «failure». На этом этапе список Apple Pay скрывается.

У вас есть все кусочки для выполнения транзакции Apple Pay через Payment Request. Как выглядит сессия Apple Pay через Payment Request:

async function applePayButtonClicked()
{ // Consider falling back to Apple Pay JS if Payment Request is not available. if (!window.PaymentRequest) return; try { const request = new PaymentRequest([applePayMethod], paymentDetails, paymentOptions); request.onmerchantvalidation = function (event) { // Have your server fetch a payment session from event.validationURL. const sessionPromise = fetchPaymentSession(event.validationURL); event.complete(sessionPromise); }; request.onshippingoptionchange = function (event) { // Compute new payment details based on the selected shipping option. const detailsUpdatePromise = computeDetails(); event.updateWith(detailsUpdatePromise); }; request.onshippingaddresschange = function (event) { // Compute new payment details based on the selected shipping address. const detailsUpdatePromise = computeDetails(); event.updateWith(detailsUpdatePromise); }; const response = await request.show(); const status = processResponse(response); response.complete(status); } catch (e) { // Handle errors }
}

Доступность

Payment Request API доступен в Safari 11.1 на macOS Sierra и macOS High Sierra, Safari на iOS 11.3 и Safari Technology Preview.

Автор: Andy Estes

Источник: https://webkit.org/

Редакция: Команда webformyself.