Apple Pay Plugin (iOS only)
This plugin provides an interface to the native Apple Pay API.
The high level flow of Apple Pay is the following:
- Create a payment request, and call startPayment
- Handle shipping address, and shipping method events (setOnDidSelectShippingAddress, setOnDidSelectShippingMethod)
- If the user authorizes the payment, handle the final payment process (setOnDidAuthorizePayment)
Notes
- If you want to know when the dialog is closed (whether by authorization or cancellation), use onPaymentAuthorizationDidFinish
- All methods of specifying currency amounts will be in cents (for dollar currencies), or the base currency type / 100.
- This plugin currently only supports the Apple Pay iOS8 feature set, so it does not have support for iOS9.x+ features, like debit card support, payment summary item types, and more.
- As of iOS9.1, if you need a shipping address (by setting ApplePayPlugin.requiredShippingAddressFields), then you must also specify shipping methods on the payment request. You must also always provide at least one shipping method in didSelectShippingAddress, because Apple Pay will crash if you pass an empty array of shipping methods. This is an acknowledged (by Apple) bug in Apple Pay. (in other words, if you need a shipping address but have no shipping choices (there is just one default) you still have to set up at least one shipping method in Apple Pay).
- If you specify ApplePayPlugin.requiredShippingAddressFields then didSelectShippingAddress will be called as soon as the dialog appears, to validate the default shipping address.
- The plugin is a fairly light wrapper for the native API, official Apple Pay documentation here.
- The iOS9 (and later) simulator supports Apple Pay, however as of iOS9.1 there is a crash when completing a payment, if the payment request has ApplePayPlugin.requiredBillingAddressFields set.
- The last paymentSummaryItem must be greater than zero. Apple Pay does not support zero or negative transactions. Preceding paymentSummaryItems can be zero or negative.
Sample Usage
const applePayPlugin = await ApplePayPlugin.init()
const supportedNetworks = [ApplePayPlugin.supportedNetworkAmEx,
ApplePayPlugin.supportedNetworkVisa,
ApplePayPlugin.supportedNetworkMasterCard]
webView.on('navigationCompleted', () => {
availability = await applePayPlugin.getAvailability(supportedNetworks)
mainNavigationView.trigger('setupApplePayButton', availability)
})
mainNavigationView.on('apple-pay-button-pressed', (params) => {
const availability = await applePayPlugin.getAvailability(supportedNetworks)
if (availability === 'ready') {
const paymentSummaryItems = [
ApplePayPlugin.makePaymentItem('SUBTOTAL', 5000),
ApplePayPlugin.makePaymentItem('SHIPPING', 101),
ApplePayPlugin.makePaymentItem('TAXES', 433),
ApplePayPlugin.makePaymentItem('ASTRO TEAM', 5534)
]
const shippingMethods = [
ApplePayPlugin.makeShippingMethod('DEFAULT SHIPPING', 101, 'default'),
ApplePayPlugin.makeShippingMethod('PREMIUM SHIPPING', 501, 'premium', 'Premium')
]
const paymentRequest = {}
paymentRequest[ApplePayPlugin.merchantIdentifier] = 'merchant.com.businessname'
paymentRequest[ApplePayPlugin.paymentSummaryItems] = paymentSummaryItems
paymentRequest[ApplePayPlugin.countryCode] = 'US'
paymentRequest[ApplePayPlugin.currencyCode] = 'USD'
paymentRequest[ApplePayPlugin.shippingMethods] = shippingMethods
paymentRequest[ApplePayPlugin.supportedNetworks] = supportedNetworks
paymentRequest[ApplePayPlugin.merchantCapabilities] = [ApplePayPlugin.merchantCapability3DS,
ApplePayPlugin.merchantCapabilityEMV]
// You can set ApplePayPlugin.requiredBillingAddressFields here, but as of iOS 9.1 the simulator will crash when you try to complete the payment
paymentRequest[ApplePayPlugin.requiredShippingAddressFields] = [ApplePayPlugin.requiredAddressFieldsPostalAddress,
ApplePayPlugin.requiredAddressFieldsPhone]
applePayPlugin.startPayment(paymentRequest)
} else if (availability === 'can_set_up') {
applePayPlugin.setUpApplePay();
}
})
applePayPlugin.setOnDidSelectShippingAddress((address) => {
const paymentSummaryItems = [
ApplePayPlugin.makePaymentItem('SUBTOTAL', 5000),
ApplePayPlugin.makePaymentItem('SHIPPING', 101),
ApplePayPlugin.makePaymentItem('TAXES', 433),
ApplePayPlugin.makePaymentItem('BUSINESS NAME', 5534)
]
const shippingMethods = [
ApplePayPlugin.makeShippingMethod('DEFAULT SHIPPING', 500, 'default'),
ApplePayPlugin.makeShippingMethod('PREMIUM SHIPPING', 600, 'premium', 'Premium')
]
return new Promise(function(resolve, reject) {
const xhr = new XMLHttpRequest()
// In practice you would POST the address
xhr.open('GET', 'https://httpbin.org/get')
xhr.onload = function() {
// And parse the response
const response = JSON.parse(this.responseText)
if (this.status !== 200) {
reject(ApplePayPlugin.statusInvalidShippingPostalAddress)
return
}
const authorizationStatus = ApplePayPlugin.statusSuccess
resolve(authorizationStatus)
}
xhr.send()
}).then(function(authorizationStatus) {
return {
authorizationStatus: authorizationStatus,
shippingMethods: shippingMethods,
paymentSummaryItems: paymentSummaryItems
};
}).catch(function(error) {
return {
authorizationStatus: ApplePayPlugin.statusFailure,
shippingMethods: [],
paymentSummaryItems: []
};
});
});
applePayPlugin.setOnDidAuthorizePayment((payment) => {
return ApplePayPlugin.statusSuccess
})
applePayPlugin.setOnDidSelectShippingMethod((shippingMethod) => {
const paymentSummaryItems = [
ApplePayPlugin.makePaymentItem('Shipping', 50000)
]
return {
authorizationStatus: ApplePayPlugin.statusSuccess,
paymentSummaryItems: paymentSummaryItems
}
})
applePayPlugin.onPaymentAuthorizationDidFinish(() => {
console.log('Payment is finished')
})
Methods
ApplePayPlugin.init()
#
Creates and returns an instance of the Apple Pay plugin that is used to make subsequent method calls.
getAvailability(networks) → {availability}
#
Get the availability of Apple Pay on this device, based on the supported networks passed in. Will return:
- 'ready': A supported card has been set up.
- 'can_set_up' No supported cards are available.
- 'unavailable': Apple Pay is not available on this device.
Note: There is a case where Apple Pay is supported by a device, but there is no card set up yet, and it doesn't support the "Set Up Apple Pay" functionality (< iOS 8.3) in which case this function will return 'unavailable'.
- networks: an array of strings representing the supported networks by your merchant (non-null, non-empty, must be values of ApplePayPlugin.supportedNetwork*)
setUpApplePay()
#
Requests iOS to send the user to their Wallet App, to initiate setup of a payment card in Apple Pay. This will end up switching the active app on the device to the Apple Wallet app. This is only available on iOS 8.3 and later. Note: as of iOS 9.1 this does not work in the simulator.
ApplePayPlugin.makePaymentItem(label, amount)
#
Returns an object with ApplePayPlugin.paymentItemLabel and ApplePayPlugin.paymentItemAmount set with the incoming parameters.
- label: a string to be displayed for this item (non-null, non-empty)
- amount: a number in cents representing the currency amount of this item (non-null)
ApplePayPlugin.makeShippingMethod(label, amount, identifier, detail)
#
Returns an object with ApplePayPlugin.shippingMethodLabel,
ApplePayPlugin.shippingMethodAmount, ApplePayPlugin.shippingMethodIdentifier,
and ApplePayPlugin.shippingMethodDetail set with the incoming parameters.
- label: a string to be displayed for this item (non-null, non-empty)
- amount: a number in cents representing the currency amount of this item (non-null)
- identifier: a string denoting something (non-null)
- detail: a string denoting something (non-null)
startPayment(paymentRequest)
#
Starts a payment request based on the incoming parameter, which will trigger the Apple Pay pay sheet to appear.
- paymentRequest: an object representing a payment request (non-null, non-empty) A payment request is formatted as the following:
const paymentRequest = {};
paymentRequest[ApplePayPlugin.merchantIdentifier] = /*Your merchant id, see Apple docs (String)*/
paymentRequest[ApplePayPlugin.paymentSummaryItems] = /*An array of payment summary item objects, (Minimum of 1 entry)*/
paymentRequest[ApplePayPlugin.countryCode] = /*The ISO code for the user's country (String)*/
paymentRequest[ApplePayPlugin.currencyCode] = /*The ISO code for the user's currency (String)*/
paymentRequest[ApplePayPlugin.shippingMethods] = /* An array of shipping method objects (Optional)*/
paymentRequest[ApplePayPlugin.supportedNetworks] = /* An array of supported network (Strings)*/
paymentRequest[ApplePayPlugin.merchantCapabilities] = /* An array of merchant capabilities (Strings)*/
paymentRequest[ApplePayPlugin.requiredBillingAddressFields] = /*An array of required address field types (Strings), (Optional)*/
paymentRequest[ApplePayPlugin.requiredShippingAddressFields] = /*An array of required address field types (Strings), (Optional)*/
Events
setOnDidAuthorizePayment(callback) → {payment} → authorizationStatus
#
Pass a function to be called when didAuthorizePayment occurs. Must return a valid authorization status (see ApplePayPlugin.status*), can also return a promise that eventually returns a valid authorization status. You must implement this callback prior to calling startPayment.
- payment: the requested destination url
payment structure:
- shippingAddress (Object, Optional)
- billingAddress (Object, Optional)
- shippingMethod (Object, Optional)
- token (Object)
- paymentInstrumentName (String)
- paymentNetwork (String)
- transactionIdentifier (String)
- paymentData (Base64-encoded String)
Sample usage:
applePayPlugin.setOnDidAuthorizePayment((payment) => {
return ApplePayPlugin.statusSuccess
})
setOnDidSelectShippingAddress(callback) → {address} → {authorizationStatus, shippingMethods, paymentSummaryItems}
#
Pass a function to be called when didSelectShippingAddress occurs. Must return a valid authorization status (see ApplePayPlugin.status*), array of shipping methods, and array of paymentSummaryItems. Can also return a promise that resolves those return types. If your use case supports shipping addresses, you must implement this callback prior to calling startPayment.
- address: the (partial, see Apple docs) address the user has selected to ship to
address structure:
- city (String)
- state (String)
- postal (String) (Will be partial)
- countryCode (String)
- country (String)
Sample usage:
applePayPlugin.setOnDidSelectShippingAddress((address) => {
// Determine what the updated values should be
const paymentSummaryItems = [
ApplePayPlugin.makePaymentItem('SUBTOTAL', 5000),
ApplePayPlugin.makePaymentItem('SHIPPING', 101),
ApplePayPlugin.makePaymentItem('TAXES', 433),
ApplePayPlugin.makePaymentItem('ASTRO TEAM', 5534)
]
const shippingMethods = [
ApplePayPlugin.makeShippingMethod('DEFAULT SHIPPING', 500, 'default'),
ApplePayPlugin.makeShippingMethod('PREMIUM SHIPPING', 600, 'premium', 'Premium')
]
const authorizationStatus = ApplePayPlugin.statusSuccess
return {
authorizationStatus: authorizationStatus,
shippingMethods: shippingMethods,
paymentSummaryItems: paymentSummaryItems
}
})
setOnDidSelectShippingMethod(callback) → {shippingMethod} → {authorizationStatus, paymentSummaryItems}
#
Pass a function to be called when didSelectShippingMethod occurs. Must return a valid authorization status (see ApplePayPlugin.status*) and array of paymentSummaryItems. Can also return a promise that resolves those return types. If your use case supports shipping methods, you must implement this callback prior to calling startPayment.
- shippingMethod: the chosen shipping method
shippingMethod structure:
- label (String)
- amount (Number)
- identifier (String)
- detail (String, Optional)
Sample usage:
applePayPlugin.setOnDidSelectShippingMethod((shippingMethod) => {
const paymentSummaryItems = [
ApplePayPlugin.makePaymentItem('Shipping', 5000)
]
return {
authorizationStatus: ApplePayPlugin.statusSuccess,
paymentSummaryItems: paymentSummaryItems
}
})
onPaymentAuthorizationDidFinish(callback)
#
Pass a function to be called when paymentAuthorizationViewControllerDidFinish occurs.
Sample usage:
applePayPlugin.onPaymentAuthorizationDidFinish(() => {
// Check if a payment happened, and go to the confirmation page if one did.
})