Виджет 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, так и токенизированными картами 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, который может принимать следующие значения:
«PAN_ONLY» - аутентификация карт, сохраненных в аккаунте Google;
«CRYPTOGRAM_3DS» - аутентификация карт, хранящихся в виде токенов Google Pay, используется только на мобильных устройствах с установленным приложением Google Pay.
const allowedCardAuthMethods = ["PAN_ONLY", "CRYPTOGRAM_3DS"]; |
Также следует определить, карты каких платежных систем будут приниматься к оплате в интернет-магазине. Для этого предназначен параметр allowedCardNetworks:
const allowedCardNetworks = ["MASTERCARD", "VISA"]; |
Теперь нужно вставить идентификатор интернет-магазина в скрипт виджета (параметр gatewayMerchantId):
const tokenizationSpecification = { type: 'PAYMENT_GATEWAY', parameters: { 'gateway': 'belassist', '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': 'belassist', '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> |