Apple Pay on the Web using Stripe.js
Ravi Jordan 2 weeks ago

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.

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:

  • A Stripe account
  • A verified Apple Pay domain in Stripe
  • HTTPS on your domain (Apple Pay works only on HTTPS)
  • A basic HTML/JavaScript setup or a frontend framework (React, Vue, etc.)
  • A backend endpoint (Node.js, PHP, etc.) for creating the Payment Intent



πŸ”§ 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
  • Use test card 4242 4242 4242 4242 in regular Stripe environments.
  • Use a real device + Safari for testing Apple Pay.
  • In production, always validate domain and HTTPS before launching.


πŸ“š Resources
Top 10+ Innovative Mobile Apps That Took Over the Market in 2025

Top 10+ Innovative Mobile Apps That Took Over the Market in 2025

1724522695.jpg
Ravi Jordan
1 week ago
Ravi Jordan - Web & App Developer in India | Portfolio & Contact

Ravi Jordan - Web & App Developer in India | Portfolio & Contact

1724522695.jpg
Ravi Jordan
8 months ago
The artificial intelligence chatbot provider shows off 346,000 customer documents, including identification documents, resumes, and medical records.

The artificial intelligence chatbot provider shows off 346,000 custome...

1724522695.jpg
Ravi Jordan
5 months ago
Issues with the printer? Watch out for fake help.

Issues with the printer? Watch out for fake help.

1724522695.jpg
Ravi Jordan
5 months ago
Python Libraries for Data Science

Python Libraries for Data Science

1724522695.jpg
Ravi Jordan
2 weeks ago