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. 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 the PKPayment into a PaymentMethod. From there, create and confirm a Payment Intent like you would for a credit card.

    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. Check if Apple Pay is supported
    5. Create the payment request
    6. Present the payment sheet
    7. Optional: Support Strong Customer Authentication
    8. Handle the customer’s payment information

    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

    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 your app is ready to accept Apple Pay!

    Xcode capabilities pane

    Enable the Apple Pay capability in Xcode

    Step 4: Check if Apple Pay is supported

    Before displaying Apple Pay as a payment option in your app, determine if the user’s device supports Apple Pay and they have a card added to their wallet.

    import UIKit
    import PassKit
    
    class MyCheckoutViewController: UIViewController {
        let applePayButton: PKPaymentButton = PKPaymentButton(paymentButtonType: .plain, paymentButtonStyle: .black)
        var paymentSucceeded = false
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Toggle apple pay button state
            applePayButton.isEnabled = Stripe.deviceSupportsApplePay()
        }
    
        // ...continued in next step
    }
    
    #import <Stripe/Stripe.h>
    #import <PassKit/PassKit.h>
    
    @interface MyCheckoutViewController () <PKPaymentAuthorizationViewControllerDelegate, STPAuthenticationContext>
    @property (nonatomic) BOOL paymentSucceeded;
    @property (nonatomic) PKPaymentButton *applePayButton;
    @end
    
    @implementation MyCheckoutViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        // Toggle apple pay button state
        self.applePayButton.enabled = [Stripe deviceSupportsApplePay];
    }
    
    

    Step 5: Create the payment request

    When the user taps Pay, create a PKPaymentRequest instance that describes the payment you want to make and configures the Payment Sheet. Stripe provides a helper method that does much of the configuration for you. See Apple’s documentation for a full guide on creating payment requests.

    func handleApplePayButtonTapped() {
        let merchantIdentifier = "merchant.com.your_app_name"
        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
    }
    

    Step 6: Present the payment sheet

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

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

    Step 7: (Optional) Support Strong Customer Authentication

    To support Strong Customer Authentication, implement STPAuthenticationContext.

    extension MyCheckoutViewController: STPAuthenticationContext {
        func authenticationPresentingViewController() -> UIViewController {
            return self
        }
    
        func prepareAuthenticationContextForPresentation(completion: @escaping STPVoidBlock) {
            // For security, it's not possible to present UI over the Apple Pay sheet
            if presentedViewController != nil {
                dismiss(animated: true) {
                    completion()
                }
            } else {
                completion()
            }
        }
    }
    
    #pragma mark - STPAuthenticationContext
    
    - (UIViewController *)authenticationPresentingViewController {
        return self;
    }
    
    - (void)prepareAuthenticationContextForPresentation:(STPVoidBlock)completion {
        if (self.presentedViewController != nil) {
            // For security, it's not possible to present UI over the Apple Pay sheet
            [self dismissViewControllerAnimated:YES completion:^{
                completion();
            }];
        } else {
            completion();
        }
    }
    

    Step 8: Handle the customer’s payment information

    Finally, implement PKPaymentAuthorizationViewControllerDelegate methods to receive a PKPayment instance representing the customer’s payment information. Use createPaymentMethod to turn the PKPayment into an STPPaymentMethod. Then, confirm a PaymentIntent 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 created a PaymentIntent at the beginning of your checkout flow.

    extension MyCheckoutViewController: PKPaymentAuthorizationViewControllerDelegate {
        @available(iOS 11.0, *)
        func paymentAuthorizationViewController(_ controller: PKPaymentAuthorizationViewController, didAuthorizePayment payment: PKPayment, handler: @escaping (PKPaymentAuthorizationResult) -> Void) {
            let finishWithStatus: (PKPaymentAuthorizationStatus, Error?) -> Void = { status, error in
                if controller.presentingViewController != nil {
                    // Notify PKPaymentAuthorizationViewController
                    let errors = [STPAPIClient.pkPaymentError(forStripeError: error)].compactMap({ $0 })
                    handler(PKPaymentAuthorizationResult(status: status, errors: errors))
                } else {
                    // PKPaymentAuthorizationViewController was dismissed to present authentication UI
                    self.finish()
                }
            }
    
            // Convert the PKPayment into a PaymentMethod
            STPAPIClient.shared().createPaymentMethod(with: payment) { (paymentMethod: STPPaymentMethod?, error: Error?) in
    See all 58 lines guard let paymentMethod = paymentMethod, error == nil else { // Present error to customer... return } let clientSecret = "client secret of the PaymentIntent created at the beginning of the checkout flow" let paymentIntentParams = STPPaymentIntentParams(clientSecret: clientSecret) paymentIntentParams.paymentMethodId = paymentMethod.stripeId // Confirm the PaymentIntent with the payment method STPPaymentHandler.shared().confirmPayment(withParams: paymentIntentParams, authenticationContext: self) { (status, paymentIntent, error) in switch (status) { case .succeeded: // Save payment success self.paymentSucceeded = true finishWithStatus(.success, nil) case .canceled: finishWithStatus(.failure, nil) case .failed: // Save/handle error finishWithStatus(.failure, error) @unknown default: finishWithStatus(.failure, error) } } } } func paymentAuthorizationViewControllerDidFinish(_ controller: PKPaymentAuthorizationViewController) { // Dismiss payment authorization view controller dismiss(animated: true, completion: { self.finish() }) } func finish() { if (self.paymentSucceeded) { // Show a receipt page... } else { // Present error to customer... } } }
    #pragma mark - PKPaymentAuthorizationViewControllerDelegate
    
    - (void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller didAuthorizePayment:(PKPayment *)payment handler:(void (^)(PKPaymentAuthorizationResult * _Nonnull))completion {
        void (^finishWithStatus)(PKPaymentAuthorizationStatus, NSError *) = ^(PKPaymentAuthorizationStatus status, NSError *error) {
            if (controller.presentingViewController != nil) {
                // Notify PKPaymentAuthorizationViewController
                NSError *pkError = [STPAPIClient pkPaymentErrorForStripeError:error];
                NSArray<NSError *> *errors = pkError ? @[pkError] : @[];
                completion([[PKPaymentAuthorizationResult alloc] initWithStatus:status errors:errors]);
            } else {
                // PKPaymentAuthorizationViewController was dismissed
                [self _finish];
            }
        };
    
        // Convert the PKPayment into a PaymentMethod
    See all 59 lines [[STPAPIClient sharedClient] createPaymentMethodWithPayment:payment completion:^(STPPaymentMethod *paymentMethod, NSError *error) { if (paymentMethod == nil || error != nil) { // Present error to customer... finishWithStatus(PKPaymentAuthorizationStatusFailure, error); return; } NSString *clientSecret = @"client secret of the PaymentIntent created at the beginning of the checkout flow"; STPPaymentIntentParams *paymentIntentParams = [[STPPaymentIntentParams alloc] initWithClientSecret:clientSecret]; paymentIntentParams.paymentMethodId = paymentMethod.stripeId; // Confirm the PaymentIntent with the PaymentMethod [[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, nil); break; case STPPaymentHandlerActionStatusCanceled: finishWithStatus(PKPaymentAuthorizationStatusFailure, nil); break; case STPPaymentHandlerActionStatusFailed: finishWithStatus(PKPaymentAuthorizationStatusFailure, error); 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. If you’d like to read more about Apple Pay and its other configuration options, we recommend the NSHipster article on Apple Pay and the Apple Pay Within Apps presentation from WWDC 2015.

    Learn more about integrating Stripe into your iOS app, setting up Apple Pay, or accepting Apple Pay on your website:

    Was this page helpful?

    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