You can collect customer payment information via the client SDK in a number of ways:

Client side payment token flow Diagram demonstrating the required interaction between the client, Braintree servers and your server.

iOS SDK setup

These instructions are for version 3.x of our iOS SDK. We recommend using the latest version of our SDK; use the selector near the top of this page.

For additional requirements and installation options, see the iOS Client SDK Guide.

Using CocoaPods

Add Braintree to your Podfile:

Ruby
Copy
Copied
pod 'Braintree', '~> 3.9'

Then run pod install.

Initialize Braintree

In your checkout controller or wherever else you handle orders and payments, declare a property:

Objective-C Swift
Copy
Copied
#import <Braintree/Braintree.h>

@interface MyViewController ()
@property (nonatomic, strong) Braintree *braintree;
@end

Get a client token

Your server is responsible for generating a client token, which contains the authorization and configuration details that your client needs to initialize the client SDK.

Your app should request a client token from your server. This example uses our sample integration server; please adapt it to use your own backend API.

Objective-C Swift
Copy
Copied
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // TODO: Switch this URL to your own authenticated API
    NSURL *clientTokenURL = [NSURL URLWithString:@"https://braintree-sample-merchant.herokuapp.com/client_token"];
    NSMutableURLRequest *clientTokenRequest = [NSMutableURLRequest requestWithURL:clientTokenURL];
    [clientTokenRequest setValue:@"text/plain" forHTTPHeaderField:@"Accept"];

    [[[NSURLSession sharedSession] dataTaskWithRequest:clientTokenRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        // TODO: Handle errors
        NSString *clientToken = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

        // Initialize `Braintree` once per checkout session
        self.braintree = [Braintree braintreeWithClientToken:clientToken];

        // As an example, you may wish to present our Drop-in UI at this point.
        // Continue to the next section to learn more...
    }] resume];
}

@end

You should obtain a new client token often, at least as often as your app restarts. For the best experience, you should kick off this network operation before it would block a user interaction.

important

You must generate a client token on your server once per user checkout session. The endpoint we provide in this example is for demonstration purposes only.

Try it now

We generated a demo client token for you so you can jump right in. This is for testing purposes only!

Objective-C Swift
Copy
Copied
NSString *clientToken = @"eyJ2ZXJzaW9uIjoyLCJhdXRob3JpemF0aW9uRmluZ2VycHJpbnQiOiIwOTUyMTBlNGVjNmE0OGFiNjFjMWZjZTJlNTYyZjMzM2Y4ZjA3NjhhYzE0ODk2ZDM2MmE1MTc2OTM2NTc4OWI3fGNyZWF0ZWRfYXQ9MjAxOS0wNC0yNFQxNDowODozOC40MDE1OTEzODQrMDAwMFx1MDAyNm1lcmNoYW50X2lkPTM0OHBrOWNnZjNiZ3l3MmJcdTAwMjZwdWJsaWNfa2V5PTJuMjQ3ZHY4OWJxOXZtcHIiLCJjb25maWdVcmwiOiJodHRwczovL2FwaS5zYW5kYm94LmJyYWludHJlZWdhdGV3YXkuY29tOjQ0My9tZXJjaGFudHMvMzQ4cGs5Y2dmM2JneXcyYi9jbGllbnRfYXBpL3YxL2NvbmZpZ3VyYXRpb24iLCJncmFwaFFMIjp7InVybCI6Imh0dHBzOi8vcGF5bWVudHMuc2FuZGJveC5icmFpbnRyZWUtYXBpLmNvbS9ncmFwaHFsIiwiZGF0ZSI6IjIwMTgtMDUtMDgifSwiY2hhbGxlbmdlcyI6W10sImVudmlyb25tZW50Ijoic2FuZGJveCIsImNsaWVudEFwaVVybCI6Imh0dHBzOi8vYXBpLnNhbmRib3guYnJhaW50cmVlZ2F0ZXdheS5jb206NDQzL21lcmNoYW50cy8zNDhwazljZ2YzYmd5dzJiL2NsaWVudF9hcGkiLCJhc3NldHNVcmwiOiJodHRwczovL2Fzc2V0cy5icmFpbnRyZWVnYXRld2F5LmNvbSIsImF1dGhVcmwiOiJodHRwczovL2F1dGgudmVubW8uc2FuZGJveC5icmFpbnRyZWVnYXRld2F5LmNvbSIsImFuYWx5dGljcyI6eyJ1cmwiOiJodHRwczovL29yaWdpbi1hbmFseXRpY3Mtc2FuZC5zYW5kYm94LmJyYWludHJlZS1hcGkuY29tLzM0OHBrOWNnZjNiZ3l3MmIifSwidGhyZWVEU2VjdXJlRW5hYmxlZCI6dHJ1ZSwicGF5cGFsRW5hYmxlZCI6dHJ1ZSwicGF5cGFsIjp7ImRpc3BsYXlOYW1lIjoiQWNtZSBXaWRnZXRzLCBMdGQuIChTYW5kYm94KSIsImNsaWVudElkIjpudWxsLCJwcml2YWN5VXJsIjoiaHR0cDovL2V4YW1wbGUuY29tL3BwIiwidXNlckFncmVlbWVudFVybCI6Imh0dHA6Ly9leGFtcGxlLmNvbS90b3MiLCJiYXNlVXJsIjoiaHR0cHM6Ly9hc3NldHMuYnJhaW50cmVlZ2F0ZXdheS5jb20iLCJhc3NldHNVcmwiOiJodHRwczovL2NoZWNrb3V0LnBheXBhbC5jb20iLCJkaXJlY3RCYXNlVXJsIjpudWxsLCJhbGxvd0h0dHAiOnRydWUsImVudmlyb25tZW50Tm9OZXR3b3JrIjp0cnVlLCJlbnZpcm9ubWVudCI6Im9mZmxpbmUiLCJ1bnZldHRlZE1lcmNoYW50IjpmYWxzZSwiYnJhaW50cmVlQ2xpZW50SWQiOiJtYXN0ZXJjbGllbnQzIiwiYmlsbGluZ0FncmVlbWVudHNFbmFibGVkIjp0cnVlLCJtZXJjaGFudEFjY291bnRJZCI6ImFjbWV3aWRnZXRzbHRkc2FuZGJveCIsImN1cnJlbmN5SXNvQ29kZSI6IlVTRCJ9LCJtZXJjaGFudElkIjoiMzQ4cGs5Y2dmM2JneXcyYiIsInZlbm1vIjoib2ZmIn0=";

The above demo client token is for temporary use. You must change this client token in order to process payments with your Braintree sandbox or production account.

Present Drop-in UI

At this point, you are ready to collect payment information from your customer.

Drop-in is the easiest way to get started. It provides a fully fledged payments experience out of the box. You can also choose to create a custom UI and then tokenize the payment information directly.

Declare a class that conforms to the BTDropInViewControllerDelegate protocol to receive the user's payment method.

Objective-C Swift
Copy
Copied
#import <Braintree/Braintree.h>

@interface MyViewController () <BTDropInViewControllerDelegate>

@property (nonatomic, strong) Braintree *braintree;

@end

In your implementation, use the client token obtained from your server to initialize the Braintree SDK. Then, create a BTDropInViewController.

Objective-C Swift
Copy
Copied
#import "MyViewController.h"

@implementation MyViewController

// ...

// With this example, you should ensure that your users can't tap the pay button until
// the client token has been obtained from your server and has been used to create a
// Braintree instance.

- (IBAction)tappedMyPayButton {

  // If you haven't already, create and retain a `Braintree` instance with the client token.
  // Typically, you only need to do this once per session.
  //self.braintree = [Braintree braintreeWithClientToken:CLIENT_TOKEN_FROM_SERVER];

  // Create a BTDropInViewController
  BTDropInViewController *dropInViewController = [self.braintree dropInViewControllerWithDelegate:self];
  // This is where you might want to customize your Drop in. (See below.)

  // The way you present your BTDropInViewController instance is up to you.
  // In this example, we wrap it in a new, modally presented navigation controller:
  dropInViewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
                                                                                                        target:self
                                                                                                        action:@selector(userDidCancelPayment)];

  UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:dropInViewController];
  [self presentViewController:navigationController animated:YES completion:nil];
}

- (void)userDidCancelPayment {
    [self dismissViewControllerAnimated:YES completion:nil];
}

Then implement BTDropInViewControllerDelegate to obtain the payment method nonce on success, and dismiss the Drop In UI in either case:

Objective-C Swift
Copy
Copied
- (void)dropInViewController:(__unused BTDropInViewController *)viewController didSucceedWithPaymentMethod:(BTPaymentMethod *)paymentMethod {
    [self postNonceToServer:paymentMethod.nonce]; // Send payment method nonce to your server
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)dropInViewControllerDidCancel:(__unused BTDropInViewController *)viewController {
    [self dismissViewControllerAnimated:YES completion:nil];
}

Test your integration

Create a sandbox account

If you haven't already, sign up for a free Braintree sandbox account:

Sign Up for a Braintree Sandbox Account

Log in to obtain your sandbox API credentials. You'll need your:

  • Sandbox merchant ID
  • Public key
  • Private key

Use these credentials for your development and testing.

important

When you go live, you will need to replace your sandbox API credentials with production API credentials.

Test values

When testing in the sandbox, be sure to use our test card numbers (e.g. 4111111111111111) and nonces (e.g. fake-valid-nonce). Real payment method data will not work in the sandbox. See our Testing page for more details.

Send payment method nonce to server

Send the resulting payment method nonce to your server (again, adapt this example to your own setup):

Objective-C Swift
Copy
Copied
- (void)postNonceToServer:(NSString *)paymentMethodNonce {
    // Update URL with your server
    NSURL *paymentURL = [NSURL URLWithString:@"https://your-server.example.com/checkout"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:paymentURL];
    request.HTTPBody = [[NSString stringWithFormat:@"payment_method_nonce=%@", paymentMethodNonce] dataUsingEncoding:NSUTF8StringEncoding];
    request.HTTPMethod = @"POST";

    [[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        // TODO: Handle success and failure
    }] resume];
}

world.greeted = true

At this point, you should have a working client-side checkout flow. When your user provides payment information, you receive a payment method nonce and send it to your server.

Next, your server closes the loop by using the payment method nonce to create a transaction.

Next Page: Simple Server →

Still have questions?

If you can’t find an answer, contact us