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
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
- Go to your Stripe Dashboard
- Navigate to Payments β Apple Pay
- Click Add new domain
- Click Verify
<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.
- 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.