Skip to main content

Collect Apple Pay

In this guide, we will set up PublicSquare Elements SDKs to capture Apple Pay in a frontend application and securely authorize and store the Apple Pay data while avoiding PCI requirements.

Getting Started

To get started, you will need a PublicSquare Account.

Get your Publishable Key

Next you will need your Publishable Key. Go to your Developers section and click Reveal for your Publishable Key and copy the value.

Save the Publishable Key as it will be used in the next steps of this guide.

Domain Verification

Domain verification is a key step in getting Apple Pay up and running on your site. It is a required step for development and production servers, to confirm that you own the domain where Apple Pay will be implemented, preventing unauthorized use and maintaining the integrity of the payment system.

  1. Download and serve the domain association file (CSR) on your server at https://<YOUR_DOMAIN>/.well-known/apple-developer-merchantid-domain-association.
  2. Add the public domain to your tenant using the merchant portal or the API

Apple requires the website to be served via HTTPS, which can be tricky during the development phase. Tunneling may represent a good option to preview local projects through a working HTTPS connection. Cloudflare tunnel may be worth checking out.

Configuring PublicSquare Elements

PublicSquare Elements are available for the following technologies. Click below for detailed instructions on how to install and configure them.

Javascript
React

Creating an Apple Pay session

To initiate the Apple Pay payment modal, an Apple Pay session must be created.

Configure Apple Pay

First, let's add the Apple Pay button and initiate the Apple Pay session.

index.html
<div ref={buttonContainerRef}></div>
index.js
import { PublicSquare } from "@publicsquare/elements-js";

declare global {
var ApplePaySession: any;
}

let publicsquare;

async function init() {
publicsquare = await new PublicSquare().init('<PUBLISHABLE_API_KEY>');

// Step 1: Render the Apple Pay button
publicsquare.applePay.renderButton(buttonContainerRef.current!, {
id: 'apple-pay-btn',
onClick: onSubmitApplePay
});

function onSubmitApplePay() {
if (!ApplePaySession) {
return;
}

// Step 2: Create an Apple Pay session
const session = createApplePaySession();

// Step 3: Validate the CSR hosted at the your website
session.onvalidatemerchant = async () => {
const merchantSession = await validateMerchant();
session.completeMerchantValidation(merchantSession);
};

session.begin();
}

function createApplePaySession() {
return new ApplePaySession(3, {
countryCode: 'US',
currencyCode: 'USD',
merchantCapabilities: ['supports3DS'],
supportedNetworks: ['visa', 'masterCard', 'amex', 'discover'],
total: {
label: 'Demo (Card is not charged)',
type: 'final',
amount: '1.99',
});
}

async function validateMerchant() {
try {
return await publicsquare?.applePay.createSession({
display_name: 'eCommerce Merchant Store',
domain: window.location.host,
});
} catch (error) {
console.error('Error validating merchant:', error);
throw error;
}
}
}

await init();

Adding the code above will render an Apple Pay button on your site with an onClick event which will start an Apple Pay session.

The createApplePaySession function creates a new Apple Pay session with information about the payment.

The validateMerchant function calls Public Square to initiate the Apple Pay session by checking the presence of the Apple Pay CSR configured during the Domain Verification step. This returns an Apple Pay session instance which is valid for 30 seconds.

Tokenization and Storing Apple Pay

After the customer has authorized the payment, your application will need to call our create method from the SDK with the encrypted Apple Pay token to create an Apple Pay payment method in your account.

To do this, we will handle the session.onpaymentauthorized event to call Public Square, passing the Apple Pay payment data:

index.js
import { PublicSquare } from "@publicsquare/elements-js"

declare global {
var ApplePaySession: any;
}

let publicsquare;

async function init() {
publicsquare = await new PublicSquare().init('<PUBLISHABLE_API_KEY>');

publicsquare.applePay.renderButton(buttonContainerRef.current!, {
id: 'apple-pay-btn',
onClick: onSubmitApplePay
});

function onSubmitApplePay() {
if (!ApplePaySession) {
return;
}

const session = createApplePaySession();

session.onvalidatemerchant = async () =>{ ... };

session.onpaymentauthorized = async (event: any) => {
try {
// Create an Apple Pay payment method from the encrypted payment token
const paymentMethod = await createApplePayPaymentMethod(event);

// Present green check to the user before the timeout (30 seconds)
session.completePayment(ApplePaySession.STATUS_SUCCESS);

// Send the payment method to the backend for payment processing
await chargePayment(paymentMethod.id);
} catch (e) {
console.error(e);
session.completePayment(ApplePaySession.STATUS_FAILURE);
}
};

session.begin();
}

function createApplePaySession() { ... }

async function validateMerchant() { ... }

async function createApplePayPaymentMethod(event: any) {
if (publicsquare) {
try {
const response = await publicsquare.applePay.create({
apple_payment_data: event.payment.token,
});
if (response) {
return response;
}
} catch (error) {
console.log(error);
}
}
}
}

await init();

The created Apple Pay object contains the non-sensitive information about the Apple Pay:

{
"id": "appl_Aw3U2eESBnq6DoYEFn8qaSMrA",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "test",
"customer_id": "cus_7Ay5mcUXAxwrN6wQEQUVEHBCJ",
"token_type": "dpan",
"last4": "4242",
"exp_month": "12",
"exp_year": "2025",
"brand": "visa",
"billing_details": {
"address_line_1": "111 Colorado Ave.",
"address_line_2": "Apt 403",
"city": "Des Moines",
"state": "IA",
"postal_code": "51111",
"country": "US"
},
"expires_at": "2024-06-31T01:02:29.212Z",
"created_at": "2024-06-30T01:02:29.212Z",
"modified_at": "2024-06-30T01:02:29.212Z"
}

You can safely store the Apple Pay payment method id value in your database to use it to process a payment or associate it with a customer.

You can optionally pass in a customer_id to associate with an existing Created Customer and billing_details to remove the requirement to pass them when Creating a Payment.

Conclusion

Following this guide, you have successfully collected a customer's Apple Pay. To use this Apple Pay payment method, proceed with the Process Apple Pay Payments guide.