/stripe-guides

How to enable Apple Pay in Stripe?

Learn how to enable Apple Pay in Stripe with this step-by-step guide for iOS and web, including setup, configuration, and testing for seamless payments.

Matt Graham, CEO of Rapid Developers

Book a call with an Expert

Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.

Book a free consultation

How to enable Apple Pay in Stripe?

How to Enable Apple Pay in Stripe: A Comprehensive Guide

 

Step 1: Create a Stripe Account

 

Before setting up Apple Pay, ensure you have a Stripe account. If not, go to the Stripe website (https://stripe.com) and sign up for an account. Complete the verification process to activate your account.

 

Step 2: Install and Set Up Stripe SDK

 

For iOS applications, you'll need to install the Stripe SDK. You can use CocoaPods, Swift Package Manager, or Carthage.

Using CocoaPods:


Add to your Podfile
pod 'Stripe'
pod 'StripeApplePay'

Then run
pod install

Using Swift Package Manager:


// In Xcode, go to File > Swift Packages > Add Package Dependency
// Enter the Stripe SDK URL: https://github.com/stripe/stripe-ios

 

Step 3: Configure Your iOS Project for Apple Pay

 

  1. Open your project in Xcode
  2. Select your project in the Project Navigator
  3. Select your app target and click the "Signing & Capabilities" tab
  4. Click the "+ Capability" button and add "Apple Pay"
  5. Add your merchant ID by clicking the "+" button under the Apple Pay capability

 

Step 4: Create a Merchant ID in Apple Developer Account

 

  1. Log in to your Apple Developer account
  2. Navigate to "Certificates, Identifiers & Profiles"
  3. Select "Identifiers" from the sidebar
  4. Click the "+" button to add a new identifier
  5. Select "Merchant IDs" and click "Continue"
  6. Enter a description and identifier (e.g., merchant.com.yourcompany.yourapp)
  7. Click "Continue" and then "Register"

 

Step 5: Create a Payment Processing Certificate

 

  1. In your Apple Developer account, navigate to the Merchant ID you just created
  2. Under "Apple Pay Payment Processing Certificate", click "Create Certificate"
  3. Follow the instructions to create a Certificate Signing Request (CSR) using Keychain Access
  4. Upload the CSR file
  5. Download the generated certificate and double-click to install it in your Keychain

 

Step 6: Configure Your Domain for Web-based Apple Pay

 

If you're implementing Apple Pay on a website:

  1. In your Apple Developer account, go to your Merchant ID
  2. Scroll to "Merchant Domains" and click "Add Domain"
  3. Enter your domain name (e.g., yourdomain.com)
  4. Download the verification file
  5. Upload this file to your web server at the specified location
  6. Click "Verify" in the Apple Developer portal

 

Step 7: Register Your Domain with Stripe

 

For web implementations, register your domain with Stripe:


// Server-side code (Node.js example)
const stripe = require('stripe')('sk_test_your\_key');

// Register domain with Stripe
stripe.applePayDomains.create({
  domain\_name: 'yourdomain.com',
});

 

Step 8: Initialize Apple Pay in Your iOS App

 

First, import the necessary frameworks:


import Stripe
import StripeApplePay
import PassKit

Next, set up the Apple Pay button and check if the device can make payments:


// Check if the device supports Apple Pay
func canMakeApplePayPayments() -> Bool {
    return StripeAPI.deviceSupportsApplePay() && PKPaymentAuthorizationController.canMakePayments()
}

// Set up Apple Pay button
func setupApplePayButton() {
    let applePayButton = PKPaymentButton(paymentButtonType: .buy, paymentButtonStyle: .black)
    applePayButton.addTarget(self, action: #selector(handleApplePayButtonTapped), for: .touchUpInside)
    
    // Add to your view
    view.addSubview(applePayButton)
    
    // Set constraints
    applePayButton.translatesAutoresizingMaskIntoConstraints = false
    NSLayoutConstraint.activate([
        applePayButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
        applePayButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20),
        applePayButton.widthAnchor.constraint(equalToConstant: 200),
        applePayButton.heightAnchor.constraint(equalToConstant: 44)
    ])
}

 

Step 9: Handle Apple Pay Button Tap

 

Implement the handler for the Apple Pay button:


@objc func handleApplePayButtonTapped() {
    // Create a payment request
    let paymentRequest = StripeAPI.paymentRequest(withMerchantIdentifier: "merchant.com.yourcompany.yourapp", country: "US", currency: "USD")
    
    // Configure the payment request
    paymentRequest.requiredBillingContactFields = [.postalAddress]
    
    // Add items to the payment request
    paymentRequest.paymentSummaryItems = [
        PKPaymentSummaryItem(label: "Your Product", amount: NSDecimalNumber(string: "10.00")),
        PKPaymentSummaryItem(label: "Your Company Name", amount: NSDecimalNumber(string: "10.00"))
    ]
    
    // Present the Apple Pay payment sheet
    if let paymentController = PKPaymentAuthorizationViewController(paymentRequest: paymentRequest) {
        paymentController.delegate = self
        present(paymentController, animated: true, completion: nil)
    } else {
        // Apple Pay not available
        print("Apple Pay is not available")
    }
}

 

Step 10: Implement PKPaymentAuthorizationViewControllerDelegate

 

Implement the delegate methods to handle the payment authorization:


extension YourViewController: PKPaymentAuthorizationViewControllerDelegate {
    func paymentAuthorizationViewController(\_ controller: PKPaymentAuthorizationViewController, didAuthorizePayment payment: PKPayment, handler completion: @escaping (PKPaymentAuthorizationResult) -> Void) {
        
        // Convert the PKPayment to a Stripe token
        STPAPIClient.shared.createToken(with: payment) { (token, error) in
            if let error = error {
                // Handle error
                print("Error creating token: (error.localizedDescription)")
                completion(PKPaymentAuthorizationResult(status: .failure, errors: [error]))
                return
            }
            
            guard let token = token else {
                // Handle missing token
                completion(PKPaymentAuthorizationResult(status: .failure, errors: nil))
                return
            }
            
            // Send the token to your server for processing
            self.processPayment(with: token.tokenId) { (success, error) in
                if success {
                    completion(PKPaymentAuthorizationResult(status: .success, errors: nil))
                } else {
                    completion(PKPaymentAuthorizationResult(status: .failure, errors: [error].compactMap { $0 }))
                }
            }
        }
    }
    
    func paymentAuthorizationViewControllerDidFinish(\_ controller: PKPaymentAuthorizationViewController) {
        // Dismiss the Apple Pay UI
        controller.dismiss(animated: true, completion: nil)
    }
    
    // Function to process payment with your server
    func processPayment(with token: String, completion: @escaping (Bool, Error?) -> Void) {
        // Send the token to your server
        // Implement your API call here
        
        // Example:
        let url = URL(string: "https://yourserver.com/process-payment")!
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        
        let parameters: [String: Any] = [
            "token": token,
            "amount": 1000, // Amount in cents
            "currency": "USD"
        ]
        
        request.httpBody = try? JSONSerialization.data(withJSONObject: parameters)
        
        URLSession.shared.dataTask(with: request) { (data, response, error) in
            if let error = error {
                completion(false, error)
                return
            }
            
            // Process the response
            // This is just an example, implement your own logic
            completion(true, nil)
        }.resume()
    }
}

 

Step 11: Set Up Server-Side Processing

 

Create a server endpoint to process the payment. Here's an example using Node.js and Express:


const express = require('express');
const bodyParser = require('body-parser');
const stripe = require('stripe')('sk_test_your_secret_key');

const app = express();
app.use(bodyParser.json());

app.post('/process-payment', async (req, res) => {
  try {
    const { token, amount, currency } = req.body;
    
    // Create a charge using the token
    const charge = await stripe.charges.create({
      amount: amount,
      currency: currency,
      source: token,
      description: 'Apple Pay charge',
    });
    
    // Handle successful charge
    res.json({ success: true, charge: charge });
  } catch (error) {
    // Handle error
    console.error('Error processing payment:', error);
    res.status(500).json({ success: false, error: error.message });
  }
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

 

Step 12: Implement Apple Pay for Web (Optional)

 

If you're also implementing Apple Pay on a website, add the following JavaScript:


// Initialize Stripe.js
const stripe = Stripe('pk_test_your_publishable_key');

// Check if Apple Pay is available
const paymentRequest = stripe.paymentRequest({
  country: 'US',
  currency: 'usd',
  total: {
    label: 'Your Company Name',
    amount: 1000,
  },
  requestPayerName: true,
  requestPayerEmail: true,
});

paymentRequest.canMakePayment().then(function(result) {
  if (result && result.applePay) {
    // Apple Pay is available, show the button
    const elements = stripe.elements();
    const prButton = elements.create('paymentRequestButton', {
      paymentRequest: paymentRequest,
      style: {
        paymentRequestButton: {
          type: 'buy',
          theme: 'dark',
        },
      },
    });
    
    // Mount the button
    prButton.mount('#payment-request-button');
    
    // Handle the payment request
    paymentRequest.on('paymentmethod', async function(event) {
      // Send the payment method ID to your server
      const response = await fetch('/process-payment', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          paymentMethodId: event.paymentMethod.id,
          amount: 1000, // Amount in cents
          currency: 'usd',
        }),
      }).then((res) => res.json());
      
      if (response.error) {
        // Show error to your customer
        event.complete('fail');
      } else {
        // Payment successful
        event.complete('success');
      }
    });
  } else {
    // Apple Pay not available, hide the button
    document.getElementById('payment-request-button').style.display = 'none';
  }
});

Add the corresponding HTML:


 

Step 13: Test Your Implementation

 

For iOS:

  1. Use a physical device (simulator doesn't support Apple Pay)
  2. Make sure you're signed in to an iCloud account
  3. Add a card to Apple Pay in Wallet app
  4. Run your app in debug mode
  5. Use Stripe's test cards for testing

For Web:

  1. Use Safari on macOS or iOS
  2. Make sure you're signed in to an iCloud account
  3. Have a card added to Apple Pay
  4. Visit your website and test the payment flow

 

Step 14: Go Live

 

When you're ready to go live:

  1. Switch from Stripe test keys to live keys
  2. Create a production certificate in your Apple Developer account
  3. Update your app with the production certificate
  4. Submit your app for review (if applicable)
  5. Monitor transactions through your Stripe dashboard

Remember to thoroughly test the payment flow in both development and production environments before making it available to users.

Want to explore opportunities to work with us?

Connect with our team to unlock the full potential of no-code solutions with a no-commitment consultation!

Book a Free Consultation

Client trust and success are our top priorities

When it comes to serving you, we sweat the little things. That’s why our work makes a big impact.

Rapid Dev was an exceptional project management organization and the best development collaborators I've had the pleasure of working with. They do complex work on extremely fast timelines and effectively manage the testing and pre-launch process to deliver the best possible product. I'm extremely impressed with their execution ability.

CPO, Praction - Arkady Sokolov

May 2, 2023

Working with Matt was comparable to having another co-founder on the team, but without the commitment or cost. He has a strategic mindset and willing to change the scope of the project in real time based on the needs of the client. A true strategic thought partner!

Co-Founder, Arc - Donald Muir

Dec 27, 2022

Rapid Dev are 10/10, excellent communicators - the best I've ever encountered in the tech dev space. They always go the extra mile, they genuinely care, they respond quickly, they're flexible, adaptable and their enthusiasm is amazing.

Co-CEO, Grantify - Mat Westergreen-Thorne

Oct 15, 2022

Rapid Dev is an excellent developer for no-code and low-code solutions.
We’ve had great success since launching the platform in November 2023. In a few months, we’ve gained over 1,000 new active users. We’ve also secured several dozen bookings on the platform and seen about 70% new user month-over-month growth since the launch.

Co-Founder, Church Real Estate Marketplace - Emmanuel Brown

May 1, 2024 

Matt’s dedication to executing our vision and his commitment to the project deadline were impressive. 
This was such a specific project, and Matt really delivered. We worked with a really fast turnaround, and he always delivered. The site was a perfect prop for us!

Production Manager, Media Production Company - Samantha Fekete

Sep 23, 2022