Apple Pay

Learn how to accept Apple Pay in your website or iOS app.
If you still have questions after reading this guide, check out our [FAQs page](https://support.bluesnap.com/v5.0/docs/faqs-mobile-wallets).

Apple Pay is a simple, secure payment experience, allowing shoppers to purchase with credit and debit cards linked to their supported Apple devices. Apple Pay is accessible from newer versions of Safari and iOS, allowing shoppers to buy both from your website or native iOS app.

Apple Pay requirements

2.1: Add the Apple Pay button to your site

Begin by adding a hidden Apple Pay button to your site. Note that Safari now comes with built-in Apple Pay images, which can be accessed using -webkit-named-image. The following black Apple Pay button with white text can be created using this feature.

2.2: Display the Apple Pay button on a compatible device

Detect the shopper's browser and device capabilities to determine if the Apple Pay button should be displayed. Check that window.ApplePaySession class exists in the browser (this class manages the Apple Pay payment process in your website). Call its canMakePayments method to perform a basic hardware check to see if the shopper's device is capable of purchasing with Apple Pay.

If you want to default to Apple Pay during your checkout flow, or if you want to add Apple Pay buttons to your product detail page, use the canMakePaymentsWithActiveCard method. This asynchronous call requires your BlueSnap Merchant ID, and detects both that the shopper's device supports Apple Pay and that there is at least one card provisioned in their account. If checking Apple Pay compatibility at any other point, use canMakePayments instead.

Create a payment request object (an object that contains all the information needed to display the payment sheet).

Create a new ApplePaySession instance.

For the payment request object, BlueSnap requires the following information to complete a transaction, in addition to Apple Pay's requirements:

Payment API

Extended Payment API

requiredBillingContactFields

postalAddress

name

requiredBillingContactFields

postalAddress

name

requiredShippingContactFields

postalAddress

name

phoneticName

phone

email

Note:

You do not need to enter the actual information, you need to specify the parameters that you want to pull from the shopper. For example, if you want to request the shopper's billing address, you specify: requiredBillingContactFields: [ 'postalAddress']

Step 4: Set up the onvalidatemerchant callback

Setting up event handlers

Apple's documentation provides a list of events for which you may set up event handlers. We'll go over how to set up the onvalidatemerchant and onpaymentauthorized event handlers. You may set up additional event handlers if you wish.

The callback function onvalidatemerchant is automatically called with an event object when the payment sheet is displayed. Merchant validation is initiated so Apple can verify your eligibility to accept Apple Pay on your website.

The following steps outline the flow for onvalidatemerchant:

Client-side:

Server-side:

1. Extract the URL from event.validationURL.2. Send the URL to your server. ⟶7. Pass the decoded token to your session's ⟵completeMerchantValidation method as a JavaScript object.

3. Send a Create Wallet request to BlueSnap with the URL.4. BlueSnap returns a token (a base64 encoded string) in the response. Extract this token.5. Base64 decode the token.6. Send decoded token to the client.

Display Name — (optional) The name of your store. On certain models of MacBook Pro, the system displays this name to the user in the Touch Bar. The value is up to 65 UTF-8 characters. If this is not included, the system displays your BlueSnap-registered Merchant Name. We recommend that you include this information to avoid confusion for your customers.

Supported status codes for completePayment

Step 6: Show the payment sheet

After you've added all your event handlers, call your session's begin method to show the payment sheet to the shopper. Note that if the session isn’t explicitly requested by the customer (i.e. inside a click event), the begin method throws a JavaScript exception.

After the begin method is called, your session's onvalidatemerchant callback function is called. The other callback functions are called when their corresponding events are triggered as the shopper proceeds through checkout.

Testing in Sandbox

Getting started

Note: To test the entire Apple Pay flow, we recommend you test only on real devices. A simulator may be unable to process the transaction.

Device regionTo provision test cards on your device, you'll need to make sure that your device’s region is set to a country that supports Apple Pay. Currently, Apple supports testing in the countries listed here.

Note: To test Amex cards for Apple Pay, your device region must be set to the United States.

iCloud account credentialsContact Merchant Support to have Apple Pay testing enabled on your account. We'll provide you with credentials for an iCloud account that can be used for testing.

Note: Each testing device (i.e. MacBook, iPhone, Apple Watch) must be logged in to this iCloud account. To learn about how to connect Apple Devices with Handoff, visit Apple's Support website.

Test cardsThe following cards may be used to test Apple Pay transactions.

Apple Pay requirements

Accepting donations?

If you're accepting donations, Apple requires that you register with Benevity before you begin implementing Apple Pay in your iOS app.

Apple Pay vs. In-App Purchases

It's necessary to understand the difference between Apple Pay and In-App Purchase. Use Apple Pay within apps to sell physical goods (such as groceries, clothing, and appliances), or for services (such as club memberships, hotel reservations, and event tickets).

Use In-App purchases to sell virtual goods (such as premium app content and subscriptions for digital content). See Apple's In-App Purchase for more information.

Step 1: Register Apple Merchant IDs

Fill out the form by entering a description and an identifier for each environment. We recommend indicating the relevant environment in each description (such as "Apple Merchant ID for sandbox" and "Apple Merchant ID for production").

Note: Your descriptions are for your own records and may be changed in the future. Your identifiers (Merchant IDs) must be unique and cannot be changed later. You'll use your Merchant IDs when developing your app.

Step 2: Create a new Apple Pay certificate

For both your BlueSnap sandbox and production accounts, you'll need to generate a certificate with Apple and upload it to your BlueSnap Console in order to encrypt outgoing payment information.

Complete these steps for both your BlueSnap sandbox and production accounts:

Download the CSR (certificate signing request) file from BlueSnap.

Using this CSR, generate a certificate with Apple.

Upload the new Apple certificate to BlueSnap.

2.1 Download the CSR file from BlueSnap

In your BlueSnap Console, go to Integrations > Apple Pay.

In the iOS Applications section, click Download certificate signing request, and the file is automatically downloaded.

2.2 Generate certificate with Apple

The next page explains that you may obtain a CSR from your Payment Provider (you obtained this from Step 2.1). The page also explains that you may create one manually — Do not create your own because it will not work. You need to use the CSR obtained from BlueSnap. Ignore the instructions at the bottom of the page and continue.

You'll be prompted to upload the .certSigningRequest file. Select the file you downloaded from BlueSnap in Step 2.1 and continue.

After the success page is displayed, you'll have the option to download your certificate. Do that.

2.3 Upload certificate to BlueSnap

Go back to Integrations > Apple Pay in your BlueSnap Console.

In the iOS Applications section, click Choose a file, and select the certificate you obtained from Apple.

Step 3: Configure Xcode

To enable Apple Pay for your app in Xcode, follow these steps:

In Xcode, open your project settings, and open the Capabilities pane.

In the Apple Pay row, enable the switch to ON.

Select the Merchant IDs that you created in Step 1.Note: Make sure that the selected Merchant IDs are the same identifiers that you used when uploading the Apple certificates to your BlueSnap Consoles in Step 2.

iOS SDK installation and usage

Testing in Sandbox

Getting started

Note: To test the entire Apple Pay flow, we recommend you test only on real devices. A simulator may be unable to process the transaction.

Device regionTo provision test cards on your device, you'll need to make sure that your device’s region is set to a country that supports Apple Pay. Currently, Apple supports testing in the countries listed here.

Note: To test Amex cards for Apple Pay, your device region must be set to United States.

Working with payment requests

This section is intended for merchants not using our iOS SDK. Note that we recommend using our iOS SDK to get up-and-running quickly and to offer your shopper's Apple Pay, credit cards, and PayPal in your app.

We'll cover some key topics in working with payment requests, including what information is required in the payment request, as well as how to send the payment token data to BlueSnap to complete a transaction.

Creating payment requests

Once you're ready to create a payment request, you'll need to include the necessary information to ensure BlueSnap can properly complete the transaction.

If you would like to learn more about the setup process for creating payment requests, refer to Apple's documentation.

BlueSnap requires the following information in the payment request to complete a transaction:For a complete list of supported properties, click here.

Sending payment token data to BlueSnap

Once you have the shopper's authorization, you're on your way to sending payment token data to BlueSnap for processing.

If you would like to learn more about the payment authorization process before moving forward, visit Apple's documentation.

The payment token is an instance of the PKPaymentToken class, and has a nested structure. The encrypted payment data that you send to BlueSnap for processing must be extracted from this structure, then wrapped in an intermediate object that BlueSnap recognizes.

The paymentData property of your payment token is a JSON dictionary, and it contains a data key. The value of this data key contains the encrypted payment data that you'll send to your server. After you have sent the encrypted payment data to your server, you must include it in the request when you send to BlueSnap for processing. Depending on BlueSnap's response, you'll return an appropriate response in the completion handler (i.e. success, failure, etc.).

/* PKPaymentAuthorizationControllerDelegate conformance. */extensionPaymentHandler:PKPaymentAuthorizationControllerDelegate{funcpaymentAuthorizationController(_controller:PKPaymentAuthorizationController,didAuthorizePaymentpayment:PKPayment,completion:@escaping(PKPaymentAuthorizationStatus)->Void){// Perform some very basic validation on the provided contact informationifpayment.shippingContact?.emailAddress==nil||payment.shippingContact?.phoneNumber==nil{paymentStatus=.invalidShippingContact}else{// Here you would send the payment token to your server or payment provider to process// Once processed, return an appropriate status in the completion handler (success, failure, etc) This is just a sample code that decodes the token and reconstruct it. You should add some validations and make sure you pick up the information you need.NSLog("Now calling BS with PKPayment:")/do{lettoken:PKPaymentToken=payment.tokenletamount=paymentSummaryItems.last?.amountletcurrency=paymentRequest.currencyCodeletpkpaymentData=tryJSONSerialization.jsonObject(with:token.paymentData,options:JSONSerialization.ReadingOptions())varbillingAddressLines=[String]()billingAddressLines.append("")if(payment.billingContact?.postalAddress?.street!=nil){billingAddressLines.append(payment.billingContact!.postalAddress!.street)}letencodedPaymentToken=["billingContact":["emailAddress":payment.billingContact?.emailAddress,"country":payment.billingContact?.postalAddress?.country??"","phoneNumber":payment.billingContact?.phoneNumber?.stringValue,"addressLines":billingAddressLines],"shippingContact":["emailAddress":payment.shippingContact?.emailAddress,"phoneNumber":payment.shippingContact?.phoneNumber?.stringValue],"token":["transactionIdentifier":token.transactionIdentifier,"paymentData":pkpaymentData,"paymentMethod":["displayName":token.paymentMethod.displayName??"unkown","network":token.paymentMethod.network?._rawValue??"unknown","type":"debit",],]]as[String:Any]letencodedPaymentTokenJson=tryJSONSerialization.data(withJSONObject:encodedPaymentToken,options:JSONSerialization.WritingOptions())letbase64EncodedPaymentToken=String(data:encodedPaymentTokenJson,encoding:.utf8)!.data(using:String.Encoding.utf8)!.base64EncodedString()letbody=["amount":amount,"currency":currency,"wallet":["applePay":["encodedPaymentToken":base64EncodedPaymentToken]]]as[String:Any]lethttpBody=tryJSONSerialization.data(withJSONObject:body,options:JSONSerialization.WritingOptions())print(String(data:httpBody,encoding:.utf8))letloginData=String(format:"%@:%@","user","password").data(using:String.Encoding.utf8)!letbase64LoginString=loginData.base64EncodedString()varrequest=URLRequest(url:URL(string:"https://[Merchant server]")!)request.httpMethod="POST"request.httpBody=httpBodyrequest.setValue("Basic \(base64LoginString)",forHTTPHeaderField:"Authorization")request.addValue("application/json",forHTTPHeaderField:"Content-Type")request.addValue("application/json",forHTTPHeaderField:"Accept")lettask=URLSession.shared.dataTask(with:request){data,response,erroringuardletdata=data,error==nilelse{NSLog("Network error")return}NSLog(response!.debugDescription)iflethttpResponse=responseas?HTTPURLResponse{NSLog("statusCode: \(httpResponse.statusCode)")ifhttpResponse.statusCode==200{self.paymentStatus=.success}else{self.paymentStatus=.failure}}completion(self.paymentStatus)}task.resume()}catch{NSLog("json error")}}}

As demonstrated in the code sample below, you need to generate an intermediate object (encodedPaymentToken) in the appropriate way that the BlueSnap server expects it, with the Apple Pay info embedded: