Name: appr-wrapper
Owner: GoogleChromeLabs
Description: Payment Request wrapper for Apple Pay JS
Created: 2017-05-09 04:39:09.0
Updated: 2018-05-02 11:05:00.0
Pushed: 2018-03-30 16:09:20.0
Homepage: https://web-payment-apis.appspot.com
Size: 94
Language: TypeScript
GitHub Committers
User | Most Recent Commit | # Commits |
---|
Other Committers
User | Most Recent Commit | # Commits |
---|
“appr-wrapper” wraps Apple Pay JS and allows you to write Payment Request API code to use the API.
Try a demo from Safari on iOS and Chrome for Android. See that it works on both platforms in a single code base.
The repo comes with a build script (./dist/appr.js
) but in case you want to
build one yourself, follow this instruction:
Clone the repo
clone git@github.com:GoogleChrome/appr-wrapper.git
Pull dependencies
install
Build the code
run build
To try the demo on your own server, you need to go through Apple Pay JS merchant registration process. Follow Apple's instructions and setup yours. There are 3 things required:
apple-developer-merchantid-domain-association
in ./demo/well-known
folder../certs
directory with a name
apple-pay-cert.pem
at project's root../demo.js
and replace params with your own configuration:
APPLE_PAY_CERTIFICATE_PATH
, MERCHANT_IDENTIFIER
, MERCHANT_DOMAIN
,
MERCHANT_DISPLAY_NAME
One the set up is done, run the server:
run serve
./dist/appr.js
will be the code to import. You can either load it from
script
tag or import
it via module loader.
ipt src="./scripts/appr.js"></script>
rt PaymentRequest from './appr.js';
Then, simply implement Payment Request API
following the standard. You can handle
Apple Pay JS by adding a
payment method specifying “https://apple.com/apple-pay
” as following example:
method = [{
pportedMethods: ['https://apple.com/apple-pay'],
ta: {
supportedNetworks: [
'amex', 'discover', 'masterCard', 'visa'
],
countryCode: 'US',
validationEndpoint: '/applepay/validate/',
merchantIdentifier: 'merchant.com.agektmr.payment'
details = {
splayItems: [{
label: 'Original donation amount',
amount: { currency: 'USD', value: '0.01' }
,
ippingOptions: [{
id: 'standard',
label: 'Standard shipping',
amount: { currency: 'USD', value: '0.01' }
{
id: 'express',
label: 'Express shipping',
amount: { currency: 'USD', value: '0.99' }
,
tal: {
label: 'Total due',
amount: { currency: 'USD', value : '0.01' }
options = {
questShipping: true,
questPayerEmail: true,
questPayerPhone: true,
questPayerName: true,
ippingType: 'shipping'
request = new PaymentRequest(methods, details, options);
response;
est.addEventListener('shippingaddresschange', e => {
updateWith(new Promise(resolve => {
let result;
let addr = request.shippingAddress;
let price = new priceCalc(details);
if (addr.country.toUpperCase() === 'US') {
result = price.selectShippingOption('standard');
} else if (addr.country.toUpperCase() === 'JP') {
result = price.selectShippingOption('express');
} else {
details.shippingOptions = [];
resolve(details);
return;
}
resolve(result);
);
est.addEventListener('shippingoptionchange', e => {
updateWith(new Promise(resolve => {
let calc = new priceCalc(details);
let result = calc.selectShippingOption(request.shippingOption);
resolve(result);
);
est.show().then(result => {
(response.methodName === 'https://apple.com/apple-pay') {
// Apple Pay JS case
// Do whatever you need to do with the token:
// `response.applePayRaw`
else {
// Everything else will be pure Payment Request API response
hen(response => {
sponse.complete('success');
atch(e => {
(e) {
alert(`Could not make payment: ${e}`);
(response) {
response.complete('fail');
The first argument to the PaymentRequest
constructor.
supportedNetworks
is required.data
:countryCode
is required.billingContact
is optional.shippingContact
is optional. It allows you to provide default shipping contact information in Apple Pay JS.merchantCapabilities
defaults to ['supports3DS'] unless you provide any.validationEndpoint
is optional. Specify the merchant validation endpoint on your server. If you omit this, handle validatemerchant event yourself.merchantIdentifier
is required. Specify your merchant id.With validationEndpoint
, appr-wrapper automatically handles validatemerchant
event for you. On your server's specified endpoint, you'll receive a POST
request with validationURL
, so you can validate yourself and respond with a
merchant session object returned following these instructions.
You can optionally handle the validatemerchant
event by yourself by adding an
event handler.
method = [{
pportedMethods: ['https://apple.com/apple-pay'],
ta: {
supportedNetworks: [
'amex', 'discover', 'masterCard', 'visa'
],
countryCode: 'US',
validationEndpoint: '/applepay/validate/',
merchantIdentifier: 'merchant.com.agektmr.payment'
The second argument to the PaymentRequest
constructor.
total.amount.currency
is converted to
currencyCode
in Apple Pay JS.details = {
splayItems: [{
label: 'Original donation amount',
amount: { currency: 'USD', value: '0.01' }
,
ippingOptions: [{
id: 'standard',
label: 'Standard shipping',
amount: { currency: 'USD', value: '0.01' }
{
id: 'express',
label: 'Express shipping',
amount: { currency: 'USD', value: '0.99' }
,
tal: {
label: 'Total due',
amount: { currency: 'USD', value : '0.01' }
Let's look into what each parameters convert to, one by one.
The third argument to the PaymentRequest
constructor.
requestPayerEmail
, requestPayerPhone
, requestPayerName
are respectively
converted to
requireBillingContactFields
and
requireShippingContactFields
values in Apple Pay JS.pickup
in shippingType
will be converted to servicePickup
in Apple Pay
JS. Others are handled as they are.options = {
questShipping: true,
questPayerEmail: true,
questPayerPhone: true,
questPayerName: true,
ippingType: 'shipping'
canMakePayment()
will invoke canMakePaymentsWithActiveCard()
in Apple Pay JS.
est.canMakePayment().then(result => {
(result) {
return request.show();
else {
// fallback to checkout form or start setting up ApplePayJS
You can handle
shippingcontactselected
event in Apple Pay JS as shippingaddresschange
event in Payment Request.shippingmethodselected
event in Apple Pay JS as shippingoptionchange
event in Payment Request.est.addEventListener('shippingaddresschange', e => {
updateWith(new Promise(resolve => {
let result;
let addr = request.shippingAddress;
let price = new priceCalc(details);
if (addr.country.toUpperCase() === 'US') {
result = price.selectShippingOption('standard');
} else if (addr.country.toUpperCase() === 'JP') {
result = price.selectShippingOption('express');
} else {
details.shippingOptions = [];
resolve(details);
return;
}
resolve(result);
);
est.addEventListener('shippingoptionchange', e => {
updateWith(new Promise(resolve => {
let calc = new priceCalc(details);
let result = calc.selectShippingOption(request.shippingOption);
resolve(result);
);
Once show()
resolves, you will recive an object which is slightly different
from actual PaymentResponse
object. Equivalent to this resolution is
paymentauthorized
event where you will receive an event object that contains an
ApplePayPayment
object in Apple Pay JS.
To determine if the response is for Apple Pay JS, you can examine methodName
property of the payment response. If it is “https://apple.com/apple-pay
“, this
is Apple Pay JS. The payment response object is constructed to replicate
PaymentResponse
as much as possible, but it's not perfect due to technical
restrictions. If you prefer using actual payment response from Apple Pay JS API,
try applePayRaw
property which holds actual ApplePayPayment
object.
est.show().then(result => {
process payment
sponse = result;
(response.methodName === 'https://apple.com/apple-pay') {
// Apple Pay JS case
// Do whatever you need to do with the token:
// `response.applePayRaw`
else {
// Everything else will be pure Payment Request API response
hen(response => {
sponse.complete('success');
atch(e => {
(e) {
alert(`Could not make payment: ${e}`);
(response) {
response.complete('fail');