iOS Integration

Accept payments in iPhone and iPad apps, with built-in support for Apple Pay.

If you want to build a mobile app like Lyft or Fancy and enable people to make purchases directly in your app, our iOS libraries can help. The library also supports Apple Pay so that your users can make frictionless payments without having to enter in their credit card info.

Accepting payments in your app involves 3 steps, which we'll cover in this guide:

  1. Collecting credit card information from your customer
  2. Converting the credit card information to a single-use token
  3. Sending this token to your server to create a charge

Getting Started

Step 1: Install the library

Using CocoaPods

We recommend using CocoaPods to install the Stripe iOS library, since it makes it easy to keep your app's dependencies up to date.

If you haven't set up Cocoapods before, their site has installation instructions. Then, add pod 'Stripe' to your Podfile, and run pod install.

(Don't forget to use the .xcworkspace file to open your project in Xcode, instead of the .xcodeproj file, from here on out.)

Using git

Alternatively, you can simply clone the iOS library repository directly:

git clone https://github.com/stripe/stripe-ios.git

Then add the Stripe library to your Xcode project:

  1. In the menubar, click on 'File' then 'Add files to "Project"...'.
  2. Select the 'Stripe' directory in the downloaded repository.
  3. Make sure 'Copy items into destination group's folder (if needed)' is checked.
  4. Click 'Add'.
  5. In your project settings, go to the "Build Phases" tab, and make sure Foundation.framework, Security.framework, and PassKit.framework are included in the "Link Binary With Libraries" section. If you're targeting versions of iOS before iOS8, make sure PassKit.framework is listed as "Optional."

Step 2: Configure API keys

First, you'll want to configure Stripe with your publishable API key. We recommend doing this in your AppDelegate's -application:didFinishLaunchingWithOptions: method so that it'll be set for the entire lifecycle of your app.

// AppDelegate.m

#import "AppDelegate.h"
#import "Stripe.h"

NSString * const StripePublishableKey = @"pk_test_6pRNASCoBOKtIshFeQd4XMUh";

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  [Stripe setDefaultPublishableKey:StripePublishableKey];
  return YES;
}

@end

We've placed your test publishable API key as the StripePublishableKey constant in the above snippet. You'll need to swap it out with your live publishable key in production. You can see all your API keys in your dashboard.

Collecting credit card information

At some point in the flow of your app, you'll want to obtain payment details from the user. There are three ways to do this. You can (in increasing order of complexity):

  1. Use Apple Pay framework to access your users' stored payment information
  2. Use our pre-built form component, PaymentKit, to collect new credit card details
  3. Build your own credit card form from scratch

Apple Pay only supports certain US credit cards on the latest iOS devices. We recommend using Apple Pay in combination with option 2 or option 3 as a fallback on devices where Apple Pay is not available.

Using Apple Pay

With Apple Pay, you'll be able to access payment information stored on your customers' iOS devices.

Important note before starting

In order to use Apple Pay, you'll need to add the "Apple Pay" capability to your app in Xcode. This requires creating a merchant ID with Apple first, as explained in this tutorial.

If you submit your app with Apple Pay code in it, but don't have the "Apple Pay" capability, Apple will send you a warning email. (They'll still accept your submission, though). To avoid triggering this warning unnecessarily, after installing our iOS library, you'll need to opt-in in order to use our Apple Pay components.

You'll first need to add STRIPE_ENABLE_APPLEPAY to your app's build settings under "Preprocessor Macros." Next, if you're using Cocoapods, add pod 'Stripe/ApplePay' right below pod 'Stripe' and run pod update then pod install.

After you're setup, to use Apple Pay, you'll need to generate a PKPaymentRequest to submit to Apple. We've provided a convenience method to generate one with reasonable defaults. You'll need to set the paymentSummaryItems property to an NSArray of PKPaymentSummaryItems. These are analogous to line items on a receipt and are used to explain your charge to the user. For a more in-depth reference, see the PKPaymentRequest documentation.

After you create the request, query the device to see if Apple Pay is available (i.e. if your app is running on the latest hardware and the user has added a valid credit card):

// ViewController.m

PKPaymentRequest *request = [Stripe
                             paymentRequestWithMerchantIdentifier:YOUR_APPLE_MERCHANT_ID];
// Configure your request here.
NSString *label = @"Premium Llama Food";
NSDecimalNumber *amount = [NSDecimalNumber decimalNumberWithString:@"10.00"];
request.paymentSummaryItems = @[
  [PKPaymentSummaryItem summaryItemWithLabel:label 
                                      amount:amount]
];

if ([Stripe canSubmitPaymentRequest:request]) {
  ...
} else {
  // Show the user your own credit card form (see options 2 or 3)
}
          

YOUR_MERCHANT_ID is an identifier that you obtain directly from Apple—log in to your account to do so. Next, you should create and display the payment request view controller.

Apple Pay doesn't fully work in the iOS simulator. To that end, we've released a library called ApplePayStubs that will help you build, test, and debug your Apple Pay flow without a device. The STPTestPaymentAuthorizationViewController class it defines exposes the same API as PKPaymentAuthorizationViewController but returns test cards. Here, when our app is building in the debug configuration, we'll show that instead.

If you'd like to use ApplePayStubs, you can read the installation guide here.

// ViewController.m

if ([Stripe canSubmitPaymentRequest:request]) {
  UIViewController *paymentController;
#if DEBUG
  paymentController = [[STPTestPaymentAuthorizationViewController alloc]
                         initWithPaymentRequest:paymentRequest];
  paymentController.delegate = self;
#else
  paymentController = [[PKPaymentAuthorizationViewController alloc]
                         initWithPaymentRequest:paymentRequest];
  paymentController.delegate = self;
#end
  [self presentViewController:paymentController animated:YES completion:nil];
} else {
  // Show the user your own credit card form (see options 2 or 3)
}
          

You may have noticed that paymentControllerWithRequest:delegate: needs to be given a PKPaymentAuthorizationViewControllerDelegate. You'll handle the PKPayment that the controller returns by implementing this protocol. In this case, we'll implement it in our ViewController:

// ViewController.m

- (void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller
                       didAuthorizePayment:(PKPayment *)payment
                                completion:(void (^)(PKPaymentAuthorizationStatus))completion {
    /*
    We'll implement this method below in 'Creating a single-use token'.
    Note that we've also been given a block that takes a
    PKPaymentAuthorizationStatus. We'll call this function with either
    PKPaymentAuthorizationStatusSuccess or PKPaymentAuthorizationStatusFailure
    after all of our asynchronous code is finished executing. This is how the
    PKPaymentAuthorizationViewController knows when and how to update its UI.
    */
    [self handlePaymentAuthorizationWithPayment:payment completion:completion];
}

- (void)paymentAuthorizationViewControllerDidFinish:(PKPaymentAuthorizationViewController *)controller {
    [self dismissViewControllerAnimated:YES completion:nil];
}
          

You can also choose to implement some optional PKPaymentAuthorizationViewControllerDelegate methods for custom events (for example, to recalculate shipping costs based on user selection). See the PKPaymentAuthorizationViewController documentation for more information about these callbacks.

After the controller has returned with a PKPayment, we can move ahead to the next step.

Using PaymentKit

First, we'll need to add PaymentKit to your project. Doing this is similar to installing stripe-ios: You can either add pod 'PaymentKit' to your Podfile (don't forget to re-run pod install afterwards), or clone the repository and add it to your project as above.

Next, let's create a class called PaymentViewController inheriting from UIViewController. Open PaymentViewController.m, create a weakPTKView property in its class-continuation category, and declare the PaymentViewController as its PTKViewDelegate.

// PaymentViewController.m

#import "PaymentViewController.h"
#import "PTKView.h"

@interface PaymentViewController ()<PTKViewDelegate>
@property(weak, nonatomic) PTKView *paymentView;
@end
          

Next, let's instantiate the PTKView and append it as a subview.

// PaymentViewController.m

- (void)viewDidLoad
{
  [super viewDidLoad];
  PTKView *view = [[PTKView alloc] initWithFrame:CGRectMake(15,20,290,55)];
  self.paymentView = view;
  self.paymentView.delegate = self;
  [self.view addSubview:self.paymentView];
}

This will add a PTKView to the controller to accept card numbers, dates, CVCs, and zip codes. It'll format the input, and validate it on the fly.

When all the card data is added and valid the stripeView:withCard:isValid: delegate method will be called. In the callback, for example, we could enable a save button that allows users to submit their valid cards:

- (void)paymentView:(PTKView *)view withCard:(PTKCard *)card isValid:(BOOL)valid
{
  // Toggle navigation, for example
  self.saveButton.enabled = valid;
}

Building your own form

If you build your own payment form, you'll need to collect at least your customers' card numbers and expiration dates. You should likely also collect the CVC to prevent fraud. You can also optionally collect the user's name and billing address for addititional fraud protection.

Creating Tokens

Our libraries shoulder the burden of PCI compliance by helping you avoid the need to send card data directly to your server. Instead, our libraries send credit card data directly to our servers, where we can convert them to tokens. You can charge these tokens later in your server-side code.

Using a PKPayment (Apple Pay)

After you've received a PKPayment, you can turn it into a single-use Stripe token with a simple method call:

// ViewController.m

- (void)handlePaymentAuthorizationWithPayment:(PKPayment *)payment
                                   completion:(void (^)(PKPaymentAuthorizationStatus))completion {
    [[STPAPIClient sharedClient] createTokenWithPayment:payment
            completion:^(STPToken *token, NSError *error) {
                if (error) {
                    completion(PKPaymentAuthorizationStatusFailure);
                    return;
                }
                /*
                We'll implement this below in "Sending the token to your server".
                Notice that we're passing the completion block through.
                See the above comment in didAuthorizePayment to learn why.
                */
                [self createBackendChargeWithToken:token completion:completion];
            }];
}

Using an STPCard

If you're using PaymentKit or your own form, you can assemble the data into an STPCard. Once you've collected the card number, expiration, and CVC, package them up in an STPCard object and invoke the createTokenWithCard: method on the Stripe class, instructing the library to send off the credit card data to Stripe and return a token.

- (IBAction)save:(id)sender {
  STPCard *card = [[STPCard alloc] init];
  card.number = self.paymentView.card.number;
  card.expMonth = self.paymentView.card.expMonth;
  card.expYear = self.paymentView.card.expYear;
  card.cvc = self.paymentView.card.cvc;
  [[STPAPIClient sharedClient] createTokenWithCard:card
      completion:^(STPToken *token, NSError *error) {
    if (error) {
      [self handleError:error];
    } else {
      [self createBackendChargeWithToken:token];
    }
  }];
}

In the example above, we're calling createTokenWithCard: when a save button is tapped. The important thing to ensure is the createToken isn't called before the user has finished inputting their details.

Handling error messages and showing activity indicators while we're creating the token is up to you.

Sending the token to your server

The block you gave to createToken will be called whenever Stripe returns with a token (or error). You'll need to send the token off to your server so you can, for example, charge the card.

Here's how it looks for a token created with Apple Pay:

// ViewController.m

- (void)createBackendChargeWithToken:(STPToken *)token
                          completion:(void (^)(PKPaymentAuthorizationStatus))completion {
  NSURL *url = [NSURL URLWithString:@"https://example.com/token"];
  NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
  request.HTTPMethod = @"POST";
  NSString *body     = [NSString stringWithFormat:@"stripeToken=%@", token.tokenId];
  request.HTTPBody   = [body dataUsingEncoding:NSUTF8StringEncoding];

  [NSURLConnection sendAsynchronousRequest:request
                                     queue:[NSOperationQueue mainQueue]
                         completionHandler:^(NSURLResponse *response,
                                                    NSData *data,
                                                   NSError *error) {
    if (error) {
      completion(PKPaymentAuthorizationStatusFailure);
    } else {
      completion(PKPaymentAuthorizationStatusSuccess);
    }
  }];
}

If you're not using Apple Pay, the above code would be mostly the same, though you'll want a slightly different signature—the completion callback shown above is Apple Pay-specific. You would instead want to implement custom error and success handling.

On the server, you just need to implement an endpoint that will accept a parameter called stripeToken. Make sure any communication with your server is SSL secured to prevent eavesdropping.

Once you have a Stripe token representing a card on our server we can go ahead and charge it, save it for charging later, or sign the user up for a subscription. For more information, proceed to our creating charges tutorial.

Take a look at the full example application to see everything put together.


Next up

Once you've retrieved a token from Stripe, you're going to want to do something with the payment details you just collected. This is usually one of two things: