More Tutorials

Apple Pay integration with Chargebee.js

Payment Method Helper
Chargebee.js
Payments

Apple Pay is a mobile payment and digital wallet service by Apple Inc. that allows users to make payments in person, through iOS apps, and on the web using the Safari browser. It is supported on the iPhone, Apple Watch, iPad, and Mac.

This tutorial guides you on using Chargebee.js to integrate Apple Pay on your website and creating a subscription after the user completes the checkout.

Gateway prerequisites

Chargebee currently supports the below payment gateways for Apple Pay:

Set up Chargebee.js

Include the Chargebee.js script on your page and initialize a Chargebee instance before you start. For the script tag, the Chargebee.init options, and the tearDown() caveat, see Set up Chargebee.js.

Create a Payment Intent

You should create a payment intent before submitting the form to authorize the payments.

payment_intent performs the essential function of tracking different events involved in a transaction. This includes:

  • Automatically changing its status based on the outcome of authorization and capture events.

  • Automatically refunding in case of an error post-payment.

A payment_intent can be created at your server-side using create a payment intent API and returned to the client side. The payment method handler uses the created payment_intent internally to perform authorization.

Here's the sample code to create a payment_intent.

Example:

curl https://{site-name}.chargebee.com/api/v2/payment_intents \
  -u {fullaccess_api_key}: \
  -d  amount=500 \
  -d  currency_code="USD" \
  -d  payment_method_type="apple_pay"

The above step should be initiated as a request from your frontend.

Frontend code:

function createPaymentIntent() {
  return fetch("/create-payment-intent", {
    method: "POST",
    body: JSON.stringify({
      amount: 500,
      currency_code: "USD",
      payment_method_type: "apple_pay",
    }),
  }).then(response => response.json())
    .then(resp => resp.payment_intent);
}

Authorize Payment Intent

Authorize the payment intent by following the below steps:

1. Create a container element in the DOM

Create a container element in the DOM to render the Apple Pay button.

<div id='apple-pay-button'></div>

2. Set up Apple Pay

Set up Apple Pay using the steps below:

a. Load Apple Pay integration.

load Apple Pay integration using cbInstance.load("apple-pay").

b. Set payment intent.

Pass the payment_intent object to applePayHandler.setPaymentIntent(payment_intent).

c. Check Apple Pay capabilities.

Use applePayHandler.applePayCapabilities() to check whether Apple Pay is available and whether the customer has a supported payment credential. Use the returned status to decide whether to mount the Apple Pay button in the next step.

Pass your Apple merchant identifier in merchantIdentifier. It's optional for Adyen and required for all other gateways.

const merchantIdentifier = "YOUR_APPLE_PAY_MERCHANT_ID"; // Required except for Adyen.

const capabilitiesPromise = merchantIdentifier
  ? applePayHandler.applePayCapabilities(merchantIdentifier)
  : applePayHandler.applePayCapabilities();

capabilitiesPromise.then((capabilities) => {
  switch (capabilities.paymentCredentialStatus) {
    case "paymentCredentialsAvailable":
      // Call mountPaymentButton() and offer Apple Pay as the payment option.
      break;
    case "paymentCredentialStatusUnknown":
      // Call mountPaymentButton() and offer Apple Pay as one of the payment options.
      break;
    case "paymentCredentialsUnavailable":
      // Call mountPaymentButton(), but don't make Apple Pay the default payment option.
      break;
    case "applePayUnsupported":
      // Don't call mountPaymentButton(). Offer alternative payment methods instead.
      break;
  }
});

d. Mount the payment button.

Use the applePayHandler.mountPaymentButton() function to mount the Apple Pay button inside the container element. This function takes the query selector for the container element as an input parameter. Pass the recurringPaymentRequest parameter to use MPAN tokens.

applePayHandler.mountPaymentButton("#apple-pay-button", {
  locale: "en_US",
  buttonColor: "black",
  buttonType: "plain",
  recurringPaymentRequest: {
  paymentDescription: "Premium Membership Subscription",
   regularBilling: {
    label: "Monthly Subscription",
    amount: "9.99"
   },
   trialBilling: {
    label: "Free Trial - First Month",
    amount: "0.00"
   },
   billingAgreement: "You authorize monthly charges for the Premium Membership.",
   managementURL: "<https://example.com/account/subscription>",
   tokenNotificationURL: "<https://example.com/api/payment/token-notify>"
 }
});

3. Handle Payment.

Use the applePayHandler.handlePayment function to initiate the transaction.

The handlePayment function resolves to an authorized payment intent once the user authorizes the payment using the Apple Pay wallet.

Apple Pay on desktop browsers (QR code flow)

Browsers that support Apple Pay natively, such as Safari, use the native Apple Pay flow. On other desktop browsers, Chargebee.js falls back to a QR code flow: the browser displays a QR code or an Apple Pay modal, and the customer authorizes the payment on their iPhone.

Chargebee.js switches to the QR code flow automatically when the browser doesn't provide ApplePaySession and your gateway supports the flow in that browser. Browser support varies by gateway, so check your gateway's documentation before you rely on the QR code flow. For example, Stripe lists its supported browsers.

Handle the outcome of the QR code flow the same way as the native flow, using the handlePayment() callbacks described below.

Promises and Callbacks

applePayHandler.handlePayment(
      {
        success: function (result) {
          // result.paymentIntent contains payment intent
          // result.paymentData contains card details like last4, brand
          console.log("success", result);
        },
        error: function (d) {
          console.log("error", d);
        },
      }
    );

Example:

cbInstance.load("apple-pay").then((applePayHandler) => {
  createPaymentIntent()
    .then((payment_intent) => {
      applePayHandler.setPaymentIntent(payment_intent);
      return applePayHandler.mountPaymentButton("#apple-pay-button");
    })
    .then(() => {
      // once button mounted
      return applePayHandler.handlePayment();
    })
    .then((paymentIntent) => {
      //paymentIntent contains authorized payment intent
    })
    .catch((error) => {
      // handle error
    });
});

Learn more about other Apple Pay API references.

Create a subscription (server)

Pass the ID of the successfully authorized payment_intent to Chargebee’s create a subscription API.

curl  https://{site}.chargebee.com/api/v2/customers/__test__8asz8Ru9WhHOJO/subscription_for_items \
     -X POST \
     -u {site_api_key}: \
     -d payment_intent[id]="<Id of authorized payment_intent recieved in last step.>" \
     -d subscription_items[item_price_id][0]="basic-USD" \
     -d subscription_items[billing_cycles][0]=2 \
     -d subscription_items[quantity][0]=1 \
     -d subscription_items[item_price_id][1]="day-pass-USD" \
     -d subscription_items[unit_price][1]=100
Was this tutorial helpful ?
Need more help?

We're always happy to help you with any questions you might have! Click here to reach out to us.