Apple Pay

    Allow customers to securely make payments using Apple Pay on their iPhone, iPad, and Apple Watch.

    Stripe users can accept Apple Pay in iOS applications in iOS 8 and above, and on the web in Safari starting with iOS 10 or macOS Sierra. There are no additional fees to process Apple Pay payments, and the pricing is the same as other card transactions.

    Apple Pay is compatible with most Stripe products and features (e.g., subscriptions), allowing you to use it in place of a traditional payment form whenever possible. Use it to accept payments for physical or digital goods, donations, subscriptions, and more (note that Apple Pay cannot be used instead of in-app purchases).

    Apple Pay is available to cardholders at participating banks in supported countries. Refer to Apple’s participating banks documentation to learn which banks and countries are supported.

    Using Stripe and Apple Pay vs. in-app purchases

    Apple Pay doesn’t replace Apple’s In-App Purchase API. You can use any of Stripe’s supported payment methods and Apple Pay in your iOS app to sell physical goods (e.g., groceries and clothing) or for services your business provides (e.g., club memberships and hotel reservations). These payments are processed through Stripe and you only need to pay Stripe’s processing fee.

    Apple’s developer terms require their In-App Purchase API be used for digital “content, functionality, or services,” such as premium content for your app or subscriptions for digital content. Payments made using the In-App Purchase API are processed by Apple and subject to their transaction fees.

    Accept Apple Pay in your iOS app

    Stripe’s iOS SDK makes it easy to accept both Apple Pay and regular credit card payments.

    Before you start, you’ll need to be enrolled in the Apple Developer Program. Next, follow these steps:

    1. Register for an Apple Merchant ID
    2. Create a new Apple Pay certificate
    3. Integrate with Xcode
    4. Add Apple Pay to your UI

    Step 1: Register for an Apple Merchant ID

    First, you’ll need to obtain an Apple Merchant ID. Start by heading to the Registering a Merchant ID page on the Apple Developer website.

    Fill out the form with a description and identifier. Your description is for your own records and can be modified in the future (we recommend just using the name of your app). The identifier must be unique (across all apps, not just yours) and can’t be changed later (although you can always make another one). We recommend using merchant.com.{{your_app_name}}. Save this value for later use when developing your app.

    Step 2: Create a new Apple Pay certificate

    You need to include a certificate in your app to encrypt outgoing payment data. This involves 3 steps:

    1. Obtain a CSR (certificate signing request) file from Stripe
    2. Use this CSR to generate a certificate through Apple
    3. Upload the certificate back to Stripe

    First, head to the Apple Pay Settings page in the Dashboard. Choose Add new application and download the .certSigningRequest file.

    Next, back on the Apple Developer site, visit the Add iOS Certificate page. Choose Apple Pay Certificate from the options and click Continue. On the next page, choose the Merchant ID you created earlier from the dropdown and continue.

    The next page explains that you can obtain a CSR from your Payment Provider (which at this point you’ve done already) or create one manually. Important note: you must use the CSR provided by Stripe - creating your own won’t work. So ignore the directions at the bottom of this page and continue on.

    You’ll be prompted to upload a .certSigningRequest file. Choose the file you downloaded from the Dashboard and continue. You’ll see a success page, with an option to download your certificate. Download it. Finally, return to the Dashboard and upload this .cer file to Stripe.

    Step 3: Integrate with Xcode

    The last step of this process is to add the Apple Pay capability to your app. In Xcode, open your project settings, choose the Capabilities tab, and enable the Apple Pay switch. You may be prompted to log in to your developer account at this point. Enable the checkbox next to the merchant ID you created earlier, and you’re done!

    Xcode capabilities pane

    Enable the Apple Pay capability in Xcode

    Step 4: Add Apple Pay to your UI

    Accepting Apple Pay on Stripe has a lot of similarities to working with cards. When the user approves a payment, your application will receive a PKPayment instance that contains their encrypted card details. You can use the STPAPIClient class to turn a PKPayment instance into an STPPaymentMethod. From there, create and confirm a Payment Intent as usual. Let’s walk through the full Apple Pay flow.

    First, determine if the user’s device supports Apple Pay and they have a card added to their wallet.

    override func viewDidLoad() {
        super.viewDidLoad()
    
        // Toggle apple pay button state
        applePayButton.enabled = Stripe.deviceSupportsApplePay()
    }
    - (void)viewDidLoad {
      [super viewDidLoad];
    
      // Toggle apple pay button state
      self.applePayButton.enabled = [Stripe deviceSupportsApplePay];
    }

    When the user taps Pay, create a PKPaymentRequest instance that describes the payment you want to make. Stripe provides a helper function that does much of the configuration for you.

    func handleApplePayButtonTapped() {
        let merchantIdentifier = "com.merchant.your_application"
        let paymentRequest = Stripe.paymentRequest(withMerchantIdentifier: merchantIdentifier, country: "US", currency: "USD")
    
        // Configure the line items on the payment request
        paymentRequest.paymentSummaryItems = [
            PKPaymentSummaryItem(label: "Fancy Hat", amount: 50.00),
            // The final line should represent your company;
            // it'll be prepended with the word "Pay" (i.e. "Pay iHats, Inc $50")
            PKPaymentSummaryItem(label: "iHats, Inc", amount: 50.00),
        ]
    
        // Continued in next step
    }
    - (void)handleApplePayButtonTapped {
        NSString *merchantIdentifier = @"com.merchant.your_application";
        PKPaymentRequest *paymentRequest = [Stripe paymentRequestWithMerchantIdentifier:merchantIdentifier country:@"US" currency:@"USD"];
    
        paymentRequest.paymentSummaryItems = @[
          [PKPaymentSummaryItem summaryItemWithLabel:@"Fancy Hat" amount:[NSDecimalNumber decimalNumberWithString:@"50.00"]],
          // The final line should represent your company;
          // it'll be prepended with the word "Pay" (i.e. "Pay iHats, Inc $50")
          [PKPaymentSummaryItem summaryItemWithLabel:@"iHats, Inc" amount:[NSDecimalNumber decimalNumberWithString:@"50.00"]],
        ];
    
        // Continued in next step
    }

    Next, create and present a PKPaymentAuthorizationViewController instance with your payment request.

    func handleApplePayButtonTapped() {
        let paymentRequest = ... // From previous step
    
        if Stripe.canSubmitPaymentRequest(paymentRequest) {
            // Setup payment authorization view controller
            let paymentAuthorizationViewController = PKPaymentAuthorizationViewController(paymentRequest: paymentRequest)
            paymentAuthorizationViewController.delegate = self
    
            // Present payment authorization view controller
            present(paymentAuthorizationViewController, animated: true)
        }
        else {
            // There is a problem with your Apple Pay configuration
        }
    }
    - (void)handleApplePayButtonTapped {
        PKPaymentRequest *paymentRequest = ...; // From previous step
    
        if ([Stripe canSubmitPaymentRequest:paymentRequest]) {
            // Setup payment authorization view controller
            PKPaymentAuthorizationViewController *paymentAuthorizationViewController = [[PKPaymentAuthorizationViewController alloc] initWithPaymentRequest:paymentRequest];
            paymentAuthorizationViewController.delegate = self;
    
            // Present payment authorization view controller
            [self presentViewController:paymentAuthorizationViewController animated:YES completion:nil];
        }
        else {
            // There is a problem with your Apple Pay configuration
        }
    }

    To support Strong Customer Authentication, implement STPAuthenticationContext.

    extension MyCheckoutViewController: STPAuthenticationContext {
    func authenticationPresentingViewController() -> UIViewController {
        return self
    }
    
    func prepareAuthenticationContextForPresentation(completion: @escaping STPVoidBlock) {
        if presentedViewController != nil {
            dismiss(animated: true) {
                completion()
            }
        } else {
            completion()
        }
    }
    }
    
    #pragma mark - STPAuthenticationContext
    
    - (UIViewController *)authenticationPresentingViewController {
    return self;
    }
    
    - (void)prepareAuthenticationContextForPresentation:(STPVoidBlock)completion {
    if (self.presentedViewController != nil) {
        [self dismissViewControllerAnimated:YES completion:^{
            completion();
        }];
    } else {
        completion();
    }
    }
    

    Finally, implement the necessary PKPaymentAuthorizationViewControllerDelegate methods. Use createPaymentMethod to turn the PKPayment instance into an STPPaymentMethod. Then, confirm a Payment Intent with that payment method using STPPaymentHandler.

    See Using Payment Intents on iOS to learn more about the Payment Intents API, and Supporting 3D Secure Authentication on iOS to learn more about STPPaymentHandler.

    This example assumes you are using automatic confirmation and you created a PaymentIntent at the beginning of your checkout flow.

    func paymentAuthorizationViewController(_ controller: PKPaymentAuthorizationViewController, didAuthorizePayment payment: PKPayment, handler: @escaping (PKPaymentAuthorizationResult) -> Void) {
        let finishWithStatus: (PKPaymentAuthorizationStatus) -> Void = { status in
            if controller.presentingViewController != nil {
                // Notify PKPaymentAuthorizationViewController
                completion(PKPaymentAuthorizationResult(status: status, errors: nil))
            } else {
                // PKPaymentAuthorizationViewController was dismissed
                self.finish()
            }
        };
    
        STPAPIClient.shared().createPaymentMethod(with: payment) { (paymentMethod: STPPaymentMethod?, error: Error?) in
            guard let paymentMethod = paymentMethod, error == nil else {
                // Present error to customer...
                return
            }
    
            let clientSecret = ...// the client secret of the Payment Intent you created at the beginning of your checkout flow
            let paymentIntentParams = STPPaymentIntentParams(clientSecret: clientSecret)
            paymentIntentParams.paymentMethodParams = paymentMethodParams
    
            // Confirm the Payment Intent with the payment method
            STPPaymentHandler.shared().confirmPayment(paymentIntentParams, with: self) { (status, paymentIntent, error) in
                switch (status) {
                    case .succeeded:
                        // Save payment success
                        self.paymentSucceeded = true
                        finishWithStatus(.success)
                    case .canceled:
                        finishWithStatus(.failure)
                    case .failed:
                        // Save error
                        self.paymentError = error
                        finishWithStatus(.failure)
                }
            }
        }
    }
    
    func paymentAuthorizationViewControllerDidFinish(_ controller: PKPaymentAuthorizationViewController) {
        // Dismiss payment authorization view controller
        dismiss(animated: true, completion: {
            self.finish()
        })
    }
    
    func finish() {
        if (paymentSucceeded) {
            // Show a receipt page...
        } else {
            // Present error to customer...
        }
    }
    - (void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller didAuthorizePayment:(PKPayment *)payment handler:(void (^)(PKPaymentAuthorizationResult *result))completion {
        void (^finishWithStatus)(PKPaymentAuthorizationResult) = ^(PKPaymentAuthorizationStatus status) {
            if (controller.presentingViewController != nil) {
                // Notify PKPaymentAuthorizationViewController
                completion([PKPaymentAuthorizationResult alloc] initWithStatus:status errors:nil]);
            } else {
                // PKPaymentAuthorizationViewController was dismissed
                [self _finish];
            }
        };
    
        [[STPAPIClient sharedClient] createPaymentMethodWithPayment:payment completion:^(STPPaymentMethod *paymentMethod, NSError *error) {
            if (paymentMethod == nil || error != nil) {
                // Present error to customer...
                return;
            }
    
            NSString *clientSecret = ...// the client secret of the Payment Intent you created at the beginning of your checkout flow
            STPPaymentIntentParams *paymentIntentParams = [[STPPaymentIntentParams alloc] initWithClientSecret:clientSecret];
            paymentIntentParams.paymentMethodParams = paymentMethodParams;
    
            // Confirm the Payment Intent with the payment method
            [[STPPaymentHandler sharedHandler] confirmPayment:paymentIntentParams
                                    withAuthenticationContext:self
                                                    completion:^(STPPaymentHandlerActionStatus status, STPPaymentIntent * paymentIntent, NSError * error) {
                switch (status) {
                    case STPPaymentHandlerActionStatusSucceeded:
                        // Save payment success
                        self.paymentSucceeded = YES;
    
                        finishWithStatus(PKPaymentAuthorizationStatusSuccess);
                        break;
                    case STPPaymentHandlerActionStatusCanceled:
                        finishWithStatus(PKPaymentAuthorizationStatusFailure);
                        break;
                    case STPPaymentHandlerActionStatusFailed:
                        // Save error
                        self.paymentError = error;
    
                        finishWithStatus(PKPaymentAuthorizationStatusFailure);
                        break;
                }
            }];
        }
    }
    
    - (void)paymentAuthorizationViewControllerDidFinish:(PKPaymentAuthorizationViewController *)controller {
        [self dismissViewControllerAnimated:YES completion:^{
            [self _finish];
        }];
    }
    
    - (void)_finish {
        if (self.paymentSucceeded) {
            // Show a receipt page...
        } else {
            // Present error to customer...
        }
    }

    Troubleshooting

    If you’re seeing errors from the Stripe API when attempting to create tokens, there’s likely something wrong with your Apple Pay Certificate. You’ll need to generate a new certificate and upload it to Stripe, as described above. Make sure you use a CSR obtained from your Dashboard and not one you generated yourself. Xcode often incorrectly caches old certificates, so in addition to generating a new certificate, we recommend creating a new Apple Merchant ID as well.

    If you receive the error “You haven’t added your Apple merchant account to Stripe,” it’s likely your app is sending data encrypted with a previous (non-Stripe) CSR/Certificate. Make sure any certs generated by non-Stripe CSRs are revoked under your Apple Merchant ID. If this does not resolve the issue, delete the merchant ID in your Apple account and recreate it. Then, create a new certificate based on the same (Stripe-provided) CSR that was previously used. You do not need to re-upload this new certificate to Stripe. Once done, toggle the Apple Pay Credentials off and on in your app to make sure they refresh properly.

    Accept Apple Pay on the web

    You can start accepting Apple Pay payments on the web using Checkout or Elements. With Checkout, there are no additional steps necessary. With Elements, refer to our Payment Request Button documentation to learn how to add Apple Pay to your site.

    Use of Apple Pay on the Web is subject to the Apple Pay on the Web terms of service.

    Recurring payments

    Apple Pay tokens can be used to create one-off payments or subscriptions. For repeat purchases that are not related to a subscription, we recommend you create single-use tokens. Your customer must authenticate with the Apple Pay payment sheet each time—attempting to reuse payment information for a non-subscription payment can result in it being declined.

    Testing Apple Pay

    Stripe test card information cannot be saved to Wallet in iOS. Instead, Stripe recognizes when you are using your test API keys and returns a successful test card token for you to use. This allows you to make test payments using a live card without it being charged.

    Next steps

    Congrats! You’re now ready to implement Apple Pay. You may want to learn more about integrating Stripe into your iOS app, setting up Apple Pay, or accepting Apple Pay on your website:

    Was this page helpful? Yes No

    Send

    Thank you for helping improve Stripe's documentation. If you need help or have any questions, please consider contacting support.

    Questions?

    We're always happy to help with code or other questions you might have. Search our documentation, contact support, or connect with our sales team. You can also chat live with other developers in #stripe on freenode.

    On this page