Виджет Apple Pay позволяет покупателям использовать Apple Wallet для оплаты в интернет-магазине без переадресации на внешние платежные страницы и без ввода данных банковской карты.
Apple Pay поддерживается на устройствах iOS и macOS.
Визуально виджет представлен в виде кнопки Apple Pay, нажатие на которую запускает процесс авторизации и оплаты заказа.
Для организации оплат с помощь виджета на странице интернет-магазина необходимо выполнить следующие подготовительные шаги:
Для размещения виджета на странице интернет-магазина следует выполнить следующие действия:
Виджет представляет собой HTML-код и JS-скрипт, которые необходимо разместить и настроить на странице оплаты интернет-магазина.
В том месте страницы интернет-магазина, на которой планируется разместить кнопку оплаты Apple Pay, необходимо добавить следующий код:
<button id="apple-pay-button"></button> |
Для кнопки можно задать цвет, тип и размеры. Примеры типов кнопок и их описание доступны на сайте https://developer.apple.com/design/human-interface-guidelines/apple-pay/overview/buttons-and-marks/.
Для настройки внешнего вида кнопки необходимо добавить описание стиля в теге <head></head>.
<style> #apple-pay-button { display: none; background-color: black; background-image: -webkit-named-image(apple-pay-logo-white); background-size: 100% 100%; background-origin: content-box; background-repeat: no-repeat; width: 100%; height: 44px; padding: 10px 0; border-radius: 10px; } </style> |
Подробнее о настройке внешнего вида кнопки см. https://developer.apple.com/documentation/apple_pay_on_the_web/displaying_apple_pay_buttons.
После нажатия на кнопку Apple Pay на странице интернет магазина создается сессия applePaySession, в которую нужно передать параметры заказа.
В качестве параметров заказа следует передать сумму и валюту заказа, а также поддерживаемые типы карт.
Const currency = $('#currency').val(); // валюта Const paymentRequest = { countryCode: region.toUpperCase(), currencyCode: currency.toUpperCase(), total: { label: 'Your label', // название платежа amount: $('#amount').val() //сумма заказа }, supportedNetworks:['masterCard', 'visa'], merchantCapabilities: [ 'supports3DS' ] //поддерживаемые карты }; Const applePaySession = new window.ApplePaySession(1, paymentRequest); |
Для обработки сессии используются два метода:
В методе onvalidatemerchant осуществляется проверка платежной сессии, метод выполняется при отображении всплывающего окна Apple Pay.
Метод onpaymentauthorizad выполняется при подтверждении операции оплаты. В метод передается платежный токен, полученный от Apple Pay, а также параметры заказа.
Список параметров заказа
Параметр | Описание |
merchant_id | Идентификатор интернет-магазина |
amount | Сумма заказа в единицах валюты |
currency | Валюта заказа |
ordernumber | Уникальный номер заказа на стороне интернет-магазина |
comment | Комментарий |
Email покупателя | |
firstname | Имя покупателя |
lastname | Фамилия покупателя |
middlename | Отчество покупателя |
В качестве значений могут быть указаны названия полей заполненной платежной формы, например:
var data = { token : event.payment.token, merchant_id : $('#merchant_id').val(), email : $('#email').val(), amount : $('#amount').val(), currency : $('#currency').val(), ordernumber : $('#ordernumber').val(), email : $('#email').val(), firstname : $('#firstname').val(), middlename : $('#middlename').val(), lastname : $('#lastname').val(), comment : $('#comment').val() }; |
После завершения оплаты сервер возвращает в ответ номер заказа и статус. Для обработки ответа необходимо добавить соответствующий код:
$.post("/pay/tokenpay_widget_ap.cfm", JSON.stringify(data)).then(function (result) { //пример обработки платежа: if (!result.hasOwnProperty('firstcode') && JSON.stringify(result.order.orderstate) == '"Approved"' && JSON.stringify(result.order.orderstate) == '"Delayed"') { applePaySession.completePayment(ApplePaySession.STATUS_SUCCESS); } else { applePaySession.completePayment(ApplePaySession.STATUS_FAILURE); } }); |
Если по каким-то причинам оплата заказа прошла неуспешно, то сервис вернет сообщения об ошибках (ненулевые значения параметров firstcode, secondcode).
Скрипт использует Apple Pay API, который поддерживается:
Ниже приведен пример скрипта виджета, который может быть размещен на платежной странице интернет-магазина.
<script type="text/javascript"> document.addEventListener('DOMContentLoaded', function(){ if (window.ApplePaySession) { //проверка возможности оплаты и отображение кнопки Apple Pay if (ApplePaySession.canMakePayments) { document.getElementById('apple-pay-button').style.display = 'block'; document.getElementById('apple-pay-button').addEventListener('click', applePayButtonClicked); } } else {console.log("ApplePaySession not available"); } }); function applePayButtonClicked() { const region = 'RU'; const currency = $('#currency').val();//валюта заказа const paymentRequest = { countryCode: region.toUpperCase(), currencyCode: currency.toUpperCase(), total: { label: 'Your label', //название платежа amount: $('#amount').val()//сумма заказа }, supportedNetworks:['masterCard', 'visa'], merchantCapabilities: [ 'supports3DS' ] }; const version = window.ApplePaySession.supportsVersion(3) ? 3 : window.ApplePaySession.supportsVersion(2) ? 2 : 1; const applePaySession = new window.ApplePaySession(version, paymentRequest); console.log("start session"); // обработчик события для создания merchant session. applePaySession.onvalidatemerchant = function (event) { console.log("onvalidatemerchant in"); var data = { validationUrl: event.validationURL }; console.log(JSON.stringify(data)); // отправка запроса на сервер предприятия, далее запрос API для запуска сессии $.post("/pay/apple_pay_comm.cfm", data).then(function (result) { applePaySession.completeMerchantValidation(result); }); } // обработчик события авторизации платежа applePaySession.onpaymentauthorized = function (event) { console.log("onpaymentauthorized in"); //var email = event.payment.shippingContact.emailAddress; //если был запрошен адрес e-mail //var phone = event.payment.shippingContact.phoneNumber; //если был запрошен телефон //все варианты на сайте https://developer.apple.com/reference/applepayjs/paymentcontact // передача параметров заказа var data = { token : event.payment.token, merchant_id : $('#merchant_id').val(), email : $('#email').val(), amount : $('#amount').val(), currency : $('#currency').val(), ordernumber : $('#ordernumber').val(), email : $('#email').val(), firstname : $('#firstname').val(), middlename : $('#middlename').val(), lastname : $('#lastname').val(), comment : $('#comment').val() }; //отправка запроса на сервер предприятия, далее запрос API для проведения оплаты console.log(JSON.stringify(event.payment.token)); $.post("/pay/tokenpay_widget_ap.cfm", JSON.stringify(data)).then(function (result) { if (!result.hasOwnProperty('firstcode') && JSON.stringify(result.order.orderstate) == '"Approved"' && JSON.stringify(result.order.orderstate) == '"Delayed"') { applePaySession.completePayment(ApplePaySession.STATUS_SUCCESS); } else { applePaySession.completePayment(ApplePaySession.STATUS_FAILURE); } }); }; applePaySession.begin(); } </script> <style> #apple-pay-button { display: none; background-color: black; background-image: -webkit-named-image(apple-pay-logo-white); background-size: 100% 100%; background-origin: content-box; background-repeat: no-repeat; width: 100%; height: 44px; padding: 10px 0; border-radius: 10px; } </style> |
Виджет Google Pay позволяет покупателям - клиентам Google осуществлять оплату в интернет-магазине без переадресации на внешние платежные страницы и без ввода данных банковской карты.
Визуально виджет представлен в виде кнопки Google Pay, нажатие на которую запускает процесс авторизации и оплаты заказа. Виджет необходимо разместить на странице интернет-магазина и передать данные заказа. Виджет самостоятельно запрашивает токен и проводит оплату. На стороне интернет-магазина производится обработка ответа и возвращение ответа покупателю.
Использование виджета Google Pay позволяет осуществлять оплату токенизированными картами Google Pay. При этом на устройствах без установленного приложения Google Pay покупателю будет предложено выбрать сохраненную карту из Google.
Google Pay работает с картами Visa и MasterCard. |
Для организации оплат с помощь виджета на странице интернет-магазина необходимо выполнить следующие подготовительные шаги:
При использовании необходимо учитывать требования Google https://payments.developers.google.com/terms/sellertos, включая список запрещенных товаров и услуг https://payments.developers.google.com/terms/aup, а также требования к брендированию https://developers.google.com/pay/api/web/guides/brand-guidelines.
Для размещения виджета на странице интернет-магазина следует выполнить следующие действия:
Виджет представляет собой HTML-код и JS-скрипт, которые необходимо разместить и настроить на странице оплаты интернет-магазина.
В том месте страницы интернет-магазина, на которой планируется разместить кнопку оплаты Google Pay, необходимо добавить следующий код:
<div id="container"></div> |
В теге id="container" будет размещена кнопка оплаты Google Pay. При необходимости идентификатору тега можно присвоить другое значение. Для этого следует внести соответствующие изменения в метод createButton функции addGooglePayButton, например:
document.getElementById('mynewcontainer').style.display = 'block'; //mynewcontainer — новое название тега |
Дополнительно на той же странице необходимо подключить JS-скрипт для вызова Google Pay API и JS-скрипт оплаты.
<script async src="https://pay.google.com/gp/p/js/pay.js" onload="onGooglePayLoaded()"></script> |
Для настройки окружения следует задать параметр environment в функции getGooglePaymentsClient. Для работы с реальными данными нужно указать значение ’PRODUCTION’, а для тестирования – значение ’TEST’.
function getGooglePaymentsClient() { if ( paymentsClient === null ) { paymentsClient = new google.payments.api.PaymentsClient({environment: 'TEST'}); } Return paymentsClient; } |
Далее необходимо указать тип аутентификации карт, которые будут приниматься к оплате в интернет-магазине. Для этого используется параметр allowedCardAuthMethods, который может принимать следующие значения:
const allowedCardAuthMethods = ["PAN_ONLY", "CRYPTOGRAM_3DS"]; |
Также следует определить, карты каких платежных систем будут приниматься к оплате в интернет-магазине. Для этого предназначен параметр allowedCardNetworks:
const allowedCardNetworks = ["MASTERCARD", "VISA"]; |
Теперь нужно вставить идентификатор интернет-магазина в скрипт виджета (параметр gatewayMerchantId):
const tokenizationSpecification = { type: 'PAYMENT_GATEWAY', parameters: { 'gateway': 'assist', 'gatewayMerchantId': '02510116604241796260' } } |
Подключенный JS-скрипт Google Pay API запускает обработчик, который выполняет проверку устройства и отображает кнопку:
function onGooglePayLoaded() { const paymentsClient = getGooglePaymentsClient() paymentsClient.isReadyToPay(getGoogleIsReadyToPayRequest()) //проверка устройства .then(funtion(response) { If (response.result) { addGooglePayButton(); //отображение кнопки prefetchGooglePaymentData(); } }) .catch(function(err) { //обработка ошибок console.error(err); //вывод ошибок в консоль }) } |
Для отображения кнопки скрипт вызывает функцию addGooglePayButton. При этом можно настроить вид кнопки Google Pay. Для этого необходимо внести изменения в метод createButton:
Подробная информация о добавлении кнопки приведена в документации Google Pay API https://developers.google.com/pay/api/web/reference/object?hl=ru#ButtonOptions.
Пример функции addGooglePayButton, которая добавляет большую кнопку черного цвета:
function addGooglePayButton() { const paymentsClient = getGooglePaymentsClient(); const button = paymentsClient.createButton({onClick: onGooglePaymentButtonClicked, buttonColor:'black', buttonType:'long'}); //создание кнопки document.getElementById('container').appendChild(button); //добавление кнопки на страницу document.getElementById('container').style.display = 'block'; } |
При настройке кнопки необходимо учитывать требования по брендированию Google. |
Если устройство поддерживает оплату с помощью Google Pay, то будет отображена кнопка в соответствии с настройками.
Нажатие на кнопку инициирует передачу информации об операции в Google Pay с помощью функции getGoogleTransactionInfo. Для операции необходимо передать следующие параметры:
Параметр totalPriceStatus может принимать следующие значения:
Пример функции getGoogleTransactionInfo:
function getGoogleTransactionInfo() { return { currencyCode: $('#currency').val(), //валюта заказа totalPriceStatus: 'FINAL', //статус суммы заказа totalPrice: $('#amount').val() //сумма заказа }; } |
После подтверждения оплаты покупателем результат будет возвращен в функцию processPayment.
Для проведения платежа в виджет следует передать данные заказа (функция processPayment).
Список параметров функции processPayment
Параметр | Описание |
merchant_id | Идентификатор интернет-магазина |
amount | Сумма заказа в единицах валюты |
currency | Валюта заказа |
ordernumber | Уникальный номер заказа на стороне интернет-магазина |
comment | Комментарий |
Email покупателя | |
firstname | Имя покупателя |
lastname | Фамилия покупателя |
middlename | Отчество покупателя |
В качестве значений могут быть указаны названия полей заполненной платежной формы. Пример функции processPayment:
function processPayment(paymentData) { var data = { paymentData : paymentData, merchant_id : $('#merchantId').val(), //идентификатор интернет-магазина amount : $('#amount').val(), //сумма заказа currency : $('#currency').val(), //валюта ordernumber : $('#ordernumber').val(), //номер заказа email : $('#email').val(), //email покупателя firstname : $('#firstname').val(), //имя покупателя middlename : $('#middlename').val(), lastname : $('#lastname').val() //фамилия клиента comment : $('#comment').val() //комментарий к заказу }; |
После завершения оплаты с помощью Google Pay сервер возвращает в ответ номер заказа и статус. Для обработки ответа необходимо добавить соответствующий код в эту функцию processPayment:
$.post("/pay/tokenpay_widget_gp.cfm", JSON.stringify(data)).then(function (result) { // здесь должна быть обработка ответа от сервиса оплаты // это пример ответа {"order":{"ordernumber":"2019.03.11-664","orderstate":"Approved"}} }); |
Если по каким-то причинам оплата заказа прошла неуспешно, то сервис вернет сообщения об ошибках (ненулевые значения параметров firstcode, secondcode).
Скрипт использует Google Pay API, который поддерживается:
В Google Pay отсутствует возможность привязать специальную тестовую карту, поэтому при тестировании будет отображаться реальная карта. Однако, в тестовой среде Google эта карта будет подменяться на тестовую и в скрипт будут возвращаться данные тестовой карты. Это позволяет использовать привязанную реальную карту без опасений, что с нее будут списаны средства. |
Ниже приведен пример скрипта виджета, который может быть размещен на платежной странице интернет-магазина.
<script type="text/javascript"> const baseRequest = { apiVersion: 2, apiVersionMinor: 0 }; const allowedCardNetworks = ["MASTERCARD", "VISA"]; const allowedCardAuthMethods = ["PAN_ONLY", "CRYPTOGRAM_3DS"]; const tokenizationSpecification = { type: 'PAYMENT_GATEWAY', parameters: { 'gateway': 'assist', 'gatewayMerchantId': '02510116604241796260' } } const baseCardPaymentMethod = { type: 'CARD', parameters: { allowedAuthMethods: allowedCardAuthMethods, allowedCardNetworks: allowedCardNetworks, billingAddressRequired: true, billingAddressParameters: {"format": "MIN"} } } const cardPaymentMethod = Object.assign( {}, baseCardPaymentMethod, { tokenizationSpecification: tokenizationSpecification } ); let paymentsClient = null; function getGoogleIsReadyToPayRequest() { return Object.assign( {}, baseRequest, { allowedPaymentMethods: [baseCardPaymentMethod] } ); } /** * Configure support for the Google Pay API * * @see {@link https://developers.google.com/pay/api/web/reference/object#PaymentDataRequest|PaymentDataRequest} * @returns {object} PaymentDataRequest fields */ function getGooglePaymentDataRequest() { const paymentDataRequest = Object.assign({}, baseRequest); paymentDataRequest.allowedPaymentMethods = [cardPaymentMethod]; paymentDataRequest.transactionInfo = getGoogleTransactionInfo(); paymentDataRequest.merchantInfo = { // @todo a merchant ID is available for a production environment after approval by Google // See {@link https://developers.google.com/pay/api/web/guides/test-and-deploy/integration-checklist|Integration checklist} merchantId: '16590966430175452581', merchantOrigin: 'www.assist.ru', merchantName: 'ASSIST Merchant' }; return paymentDataRequest; } /** * Return an active PaymentsClient or initialize * * @see {@link https://developers.google.com/pay/api/web/reference/client#PaymentsClient|PaymentsClient constructor} * @returns {google.payments.api.PaymentsClient} Google Pay API client */ function getGooglePaymentsClient() { if ( paymentsClient === null ) { paymentsClient = new google.payments.api.PaymentsClient({environment: 'TEST'}); } return paymentsClient; } /** * Initialize Google PaymentsClient after Google-hosted JavaScript has loaded * * Display a Google Pay payment button after confirmation of the viewer's * ability to pay. */ function onGooglePayLoaded() { const paymentsClient = getGooglePaymentsClient(); paymentsClient.isReadyToPay(getGoogleIsReadyToPayRequest()) .then(function(response) { if (response.result) { addGooglePayButton(); // @todo prefetch payment data to improve performance after confirming site functionality prefetchGooglePaymentData(); } }) .catch(function(err) { // show error in developer console for debugging console.error(err); }); } /** * Add a Google Pay purchase button alongside an existing checkout button * * @see {@link https://developers.google.com/pay/api/web/reference/object#ButtonOptions|Button options} * @see {@link https://developers.google.com/pay/api/web/guides/brand-guidelines|Google Pay brand guidelines} */ function addGooglePayButton() { const paymentsClient = getGooglePaymentsClient(); const button = paymentsClient.createButton({onClick: onGooglePaymentButtonClicked, buttonColor:'black', buttonType:'long'}); document.getElementById('container').appendChild(button); document.getElementById('container').style.display = 'block'; } /** * Provide Google Pay API with a payment amount, currency, and amount status * * @see {@link https://developers.google.com/pay/api/web/reference/object#TransactionInfo|TransactionInfo} * @returns {object} transaction info, suitable for use as transactionInfo property of PaymentDataRequest */ function getGoogleTransactionInfo() { return { currencyCode: $('#currency').val(), totalPriceStatus: 'FINAL', // set to cart total totalPrice: $('#amount').val() }; } /** * g payment data to improve performance * * @see {@link https://developers.google.com/pay/api/web/reference/client#prefetchPaymentData|prefetchPaymentData()} */ function prefetchGooglePaymentData() { const paymentDataRequest = getGooglePaymentDataRequest(); // transactionInfo must be set but does not affect cache paymentDataRequest.transactionInfo = { totalPriceStatus: 'NOT_CURRENTLY_KNOWN', currencyCode: $('#currency').val() }; const paymentsClient = getGooglePaymentsClient(); paymentsClient.prefetchPaymentData(paymentDataRequest); } /** * Show Google Pay payment sheet when Google Pay payment button is clicked */ function onGooglePaymentButtonClicked() { const paymentDataRequest = getGooglePaymentDataRequest(); paymentDataRequest.transactionInfo = getGoogleTransactionInfo(); const paymentsClient = getGooglePaymentsClient(); paymentsClient.loadPaymentData(paymentDataRequest) .then(function(paymentData) { // handle the response processPayment(paymentData); }) .catch(function(err) { // show error in developer console for debugging console.error(err); }); } /** * Process payment data returned by the Google Pay API * * @param {object} paymentData response from Google Pay API after user approves payment * @see {@link https://developers.google.com/pay/api/web/reference/object#PaymentData|PaymentData object reference} */ function processPayment(paymentData) { var data = { paymentData : paymentData, merchant_id : $('#merchantId').val(), amount : $('#amount').val(), currency : $('#currency').val(), ordernumber : $('#ordernumber').val(), email : $('#email').val(), firstname : $('#firstname').val(), middlename : $('#middlename').val(), lastname : $('#lastname').val(), comment : $('#comment').val() }; // For debug console.log(data); $.post("/pay/tokenpay_widget_gp.cfm", JSON.stringify(data)).then(function (result) { // For debug console.log(result); // Example result: // {"order":{"ordernumber":"2019.03.11-664","orderstate":"Approved"}} }); } </script> <script async src="https://pay.google.com/gp/p/js/pay.js" onload="onGooglePayLoaded()"></script> |