Integrate Apple Pay on the Web using Stripe.js 2025 – A Step-by-Step Guide

Apple Pay offers a fast, secure, and user-friendly way to check out on the web. With Stripe.js, implementing Apple Pay is smoother than ever. In this blog, we'll walk through integrating Apple Pay using stripe.js on a web application.

2025-06-05 13:39:14 - Ravi Jordan

Apple Pay offers a fast, secure, and user-friendly way to check out on the web. With Stripe.js, implementing Apple Pay is smoother than ever. In this blog, we'll walk through integrating Apple Pay using stripe.js on a web application.

Whether you're building an e-commerce store or a custom checkout flow, this guide will get you up and running.


Github: https://github.com/ravijordan/stripe-apple-pay


πŸš€ Prerequisites

Before starting, make sure you have:



πŸ”§ Step 1: Register and Verify Your Domain on Stripe
  1. Go to your Stripe Dashboard
  2. Navigate to Payments β†’ Apple Pay
  3. Click Add new domain
  4. Click Verify



πŸ“¦ Step 2: Add Stripe.js to Your Site
<script src="https://js.stripe.com/v3/"></script>

πŸ§ͺ Step 3: Check for Apple Pay Availability
const stripe = Stripe('your-publishable-key');

if (window.ApplePaySession && ApplePaySession.canMakePayments()) {
  document.getElementById('apple-pay-button').style.display = 'block';
}

Add a placeholder button:

<button id="apple-pay-button" style="display: none;">Buy with ο£ΏPay</button>
πŸ›’ Step 4: Create a Payment Request
const paymentRequest = stripe.paymentRequest({
  country: 'US',
  currency: 'usd',
  total: {
    label: 'Demo Product',
    amount: 1999, // amount in cents
  },
  requestPayerName: true,
  requestPayerEmail: true,
});
πŸ”Œ Step 5: Create Apple Pay Button Handler
const elements = stripe.elements();
const prButton = elements.create('paymentRequestButton', {
  paymentRequest: paymentRequest,
});

paymentRequest.canMakePayment().then(function(result) {
  if (result) {
    prButton.mount('#apple-pay-button');
  } else {
    document.getElementById('apple-pay-button').style.display = 'none';
  }
});
🧾 Step 6: Backend Endpoint to Create PaymentIntent

(Example in Node.js/Express):

Node JS

app.post('/create-payment-intent', async (req, res) => {
  const { amount } = req.body;

  const paymentIntent = await stripe.paymentIntents.create({
    amount: amount,
    currency: 'usd',
    automatic_payment_methods: { enabled: true },
  });

  res.send({
    clientSecret: paymentIntent.client_secret,
  });
});

PHP

        $customer = \Stripe\Customer::create([
            'name' => 'John Doe',
            'email' => 'john@example.com'
        ]);


        // Create a PaymentIntent with the order amount and currency
        $paymentIntent = \Stripe\PaymentIntent::create([
            'amount' => $amount,
            'currency' => $currency,
            'customer' => $customer->id,
            'payment_method_types' => ['card'], // 'card' is necessary for Apple Pay
        ]);


        header('Content-Type: application/json');
        echo json_encode([
            'clientSecret' => $paymentIntent->client_secret
        ]);



πŸ”„ Step 7: Handle the Payment on Frontend
paymentRequest.on('paymentmethod', async (ev) => {
  const res = await fetch('/create-payment-intent', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ amount: 1999 })
  });

  const { clientSecret } = await res.json();

  const { error: confirmError } = await stripe.confirmCardPayment(clientSecret, {
    payment_method: ev.paymentMethod.id,
  }, { handleActions: false });

  if (confirmError) {
    ev.complete('fail');
  } else {
    ev.complete('success');
    alert('Payment successful!');
  }
});






BackEnd Server Code

<?php
require_once 'vendor/autoload.php';
require_once 'config.php';


\Stripe\Stripe::setApiKey(STRIPE_SECRET_KEY);


$payment_intent_id = $_GET['payment_intent'] ?? $_GET['payment_intent_id'];


try {
    $paymentIntent = \Stripe\PaymentIntent::retrieve($payment_intent_id);
    
        // Retrieve Customer details
    $customer = \Stripe\Customer::retrieve($paymentIntent->customer);
    
    // Prepare customer data
    $customerName = $customer->name ?? 'Unknown';
    $customerEmail = $customer->email ?? 'No email';
    
    
    // print_r($paymentIntent);
    
    // Save to database
    $stmt = $mysqli->prepare("INSERT INTO payments (
        payment_intent_id, 
        amount, 
        currency, 
        status, 
        customer_name, 
        customer_email
    ) VALUES (?, ?, ?, ?, ?, ?)");
    
    $stmt->bind_param(
        'sissss',
        $paymentIntent->id,
        $paymentIntent->amount,
        $paymentIntent->currency,
        $paymentIntent->status,
        $customerName,
        $customerEmail
    );
    
    $stmt->execute();
    $stmt->close();


    if ($paymentIntent->status === 'succeeded') {
        echo "Payment succeeded!";
        // Additional success logic here
    } else {
        echo "Payment failed!";
    }
} catch (\Stripe\Exception\ApiErrorException $e) {
    // Handle error
    echo "API Error: " . $e->getMessage();
} catch (Exception $e) {
    // Handle general error
    echo "Error: " . $e->getMessage();
}






βœ… Final Result

You now have a working Apple Pay integration using Stripe.js! When users click the Apple Pay button, they’ll see a native Apple Pay sheet and can complete their purchase in seconds.


🧠 Tips


πŸ“š Resources

More Posts