Why Apple Pay?
- It’s an easy, secure and private way to pay within the app
- One touch payment
- No need to re enter payment or contact information
- Private – cause credit card number are not exposed to the merchant, instead you are sent the device number and unique token that is only valid for that particular purchase.
Why use Apple Pay as developer?
- You don’t need to handle credit card number
- Higher conversion rate and faster checkout
Apple Pay VS In-App Purchase
- Apple Pay is used for physical good’s & services where as In-App purchase is for in app content/functionality only
- Developer is responsible of processing payment in Apple Pay where as Apple is responsible for processing payments in In-App purchase.
Prerequisites
iOS device (iPhone 6 or 6+, iPad Air 2, or iPad mini 3) running iOS 8.1 or later
Quick overview of how it works
- You create a Merchant ID and matching certificate in Developer Portal
- Your ID and certificate are used to encrypt the payment data
- Display Payment sheet to user
- User uses Touch ID to authorize transaction
- Your app receives the payment token
- This token is encrypted using your Merchant ID and certificate so only your application can decrypt it
- Send token for processing using one of payment platforms like Stripe, Braintree, Shopify etc.
Create new Xcode Project
Select “Single View Application” Template
Setup your app for ApplePay
Once project is created, login into your http://developer.apple.com account. Go to Member Center and click on Certificates, Identifiers & Profiles\Identifiers\App IDs. Click on the + button to create a new App ID
Make sure that you select Explicit App ID is selected, as wildcard App IDs aren’t able to make payments with Apple Pay. Finally, check the Apple Pay checkbox under App Services, click Continue and then click Register to complete the creation of your new App ID.
Creating Merchant ID
Next click on Merchant ID under Identifiers pane. Then click on + or Continue to create new merchant ID for your app.
Now that we have both Merchant ID and App ID we can head back to the Xcode Project
Under your project Capabilities turn on the Apple Pay option and add in your MerchantID
The three items in the Steps section should all have checkmarks next to them to indicate that you’ve satisfied all of the requirements for using Apply Pay in your app.
In Main.Storyboard we are going to create textfield name, email and donation amount. We are also going to create a “Donate Again” button and Thank you message label, we are going to set there visibility hidden for now.
We are now going to create attached properties with these IBOutlets.We are also going to create UIButton property “payButton”which will be our ApplePay button later on. So our ViewController.h file now looks like this.
#import <UIKit/UIKit.h> @interface ViewController : UIViewController @property (weak, nonatomic) IBOutlet UITextField *userName; @property (weak, nonatomic) IBOutlet UITextField *userEmail; @property (weak, nonatomic) IBOutlet UITextField *donationAmount; @property (weak, nonatomic) IBOutlet UILabel *thankYouMessage; @property (weak, nonatomic) IBOutlet UIButton *donateAgainButton; - (IBAction)donateAgainPressed:(id)sender; @property (weak, nonatomic) UIButton *payButton; @end
The Apple Pay classes are part of PassKit, so you need that import to make things work.So lets add following right in our ViewController.h file.
@import PassKit;
Setting up Apple Pay button
Apple Pay is only available to a subset of iOS users. Before presenting the Apple Pay option to the current user, we are going to determine whether Apple Pay is available.
In ViewController.m file let put following
- (void)viewDidLoad { [super viewDidLoad]; // Conditionally show Apple Pay button based on device availability if ([PKPaymentAuthorizationViewController canMakePaymentsUsingNetworks:@[PKPaymentNetworkVisa, PKPaymentNetworkMasterCard, PKPaymentNetworkAmex]]) { _payButton = [self applePayButton]; //Set location of Apple Pay button _payButton.frame = CGRectMake(_donationAmount.frame.origin.x, _donationAmount.frame.origin.y + _donationAmount.frame.size.height + 22.0, _payButton.frame.size.width, _payButton.frame.size.height); [self.view addSubview:_payButton]; }else{ //Create alternate payment flow } } - (UIButton *)applePayButton { UIButton *button; if ([PKPaymentButton class]) { // Available in iOS 8.3+ button = [PKPaymentButton buttonWithType:PKPaymentButtonTypePlain style:PKPaymentButtonStyleBlack]; } else { // Create and return your own apple pay button } [button addTarget:self action:@selector(tappedApplePay) forControlEvents:UIControlEventTouchUpInside]; return button; }
In this example we are not handling older versions of iOS, but if your app targets older iOS versions you will need to create your own button using Apple’s Human Interface Guidelines and assets.
If we run our App now we will see the ApplePay button appear on our screen, but it doesn’t do anything yet.
Now let’s make the Apple Pay button work.For that we are going to implement PKPaymentAuthorizationViewControllerDelegate. We implement this protocol to respond to user interaction with the view controller.
@interface ViewController : UIViewController<PKPaymentAuthorizationViewControllerDelegate>
Implementing Delegates to Handle Payment Requests
We are going to implements the two required methods of the delegate in ViewController.m file:
paymentAuthorizationViewController:didAuthorizePayment:completion:
This handles the user authorization to complete the purchase.paymentAuthorizationViewControllerDidFinish:
This is called when the payment request completes or canceled.
- (void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller didAuthorizePayment:(PKPayment *)payment completion:(void (^)(PKPaymentAuthorizationStatus))completion { //We are assuming right now that payment was successfull. completion(PKPaymentAuthorizationStatusSuccess); } - (void)paymentAuthorizationViewControllerDidFinish:(PKPaymentAuthorizationViewController *)controller { //we are going to make all fields blank after user is done paying or canceling payment _donationAmount.text = @""; _userEmail.text = @""; _userName.text = @""; [self dismissViewControllerAnimated:YES completion:nil]; }
Setting up PKPaymentRequest
PKPaymentRequest instance is responsible for displaying the Apple Pay payment sheet.We will fill in required PKPaymentRequest elements.
- (PKPaymentRequest *)paymentRequest:(NSString *)amount { PKPaymentRequest *paymentRequest = [[PKPaymentRequest alloc] init]; paymentRequest.merchantIdentifier = @"merchant.com.xxxxxx"; paymentRequest.supportedNetworks = @[PKPaymentNetworkAmex, PKPaymentNetworkVisa, PKPaymentNetworkMasterCard]; paymentRequest.merchantCapabilities = PKMerchantCapability3DS; paymentRequest.countryCode = @"US"; paymentRequest.currencyCode = @"USD"; paymentRequest.paymentSummaryItems = @[ [PKPaymentSummaryItem summaryItemWithLabel:@"Donation" amount:[NSDecimalNumber decimalNumberWithString:amount]], ]; return paymentRequest; }
Presenting Payment Sheet
When user taps on your Apple Pay button, we are going to present a PKPaymentAuthorizationViewController
to initiate Apple Pay:
-(void)tappedApplePay{ if ([self checkFormValid]){ PKPaymentRequest *paymentRequest = [self paymentRequest:_donationAmount.text]; PKPaymentAuthorizationViewController *vc = [[PKPaymentAuthorizationViewController alloc] initWithPaymentRequest:paymentRequest]; vc.delegate = self; [self presentViewController:vc animated:YES completion:nil]; }else{ //Showing Alert to user if all values are not filled UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"Please fill in all details" message:@"" preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction* ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { [alert dismissViewControllerAnimated:YES completion:nil]; }]; [alert addAction:ok]; [self presentViewController:alert animated:YES completion:nil]; } } -(BOOL)checkFormValid{ BOOL valid = false; //We are doing some basic validation so we don't have amount blank while showing the payment sheet if ([_userName.text isEqualToString:@""] || [_userEmail.text isEqualToString:@""]|| [_donationAmount.text isEqualToString:@""]) { valid = false; }else{ valid = true; } return valid; }

pod 'Stripe'
to your Podfile
, and run pod install
. Close your project and use the .xcworkspace
file to open your project in Xcode, instead of the .xcodeproj
file, from here on out.
.certSigningRequest
file will automatically download.


.cer
file to Stripe.
Import Stripe in your AppDelegate.m file and setup publishable API key in method “didFinishLaunchingWithOptions”.
#import <Stripe/Stripe.h>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [Stripe setDefaultPublishableKey:@"pk_test_key"]; return YES; }
#import <Stripe/Stripe.h>
- (void)paymentAuthorizationViewController:(PKPaymentAuthorizationViewController *)controller didAuthorizePayment:(PKPayment *)payment completion:(void (^)(PKPaymentAuthorizationStatus))completion { [self handlePaymentAuthorizationWithPayment:payment completion:completion]; } - (void)handlePaymentAuthorizationWithPayment:(PKPayment *)payment completion:(void (^)(PKPaymentAuthorizationStatus))completion { [[STPAPIClient sharedClient] createTokenWithPayment:payment completion:^(STPToken *token, NSError *error) { if (error) { completion(PKPaymentAuthorizationStatusFailure); return; } [self createBackendChargeWithToken:token completion:completion]; }]; } - (void)createBackendChargeWithToken:(STPToken *)token completion:(void (^)(PKPaymentAuthorizationStatus))completion { //We are printing Stripe token here, you can charge the Credit Card using this token from your backend. NSLog(@"Stripe Token is %@",token); completion(PKPaymentAuthorizationStatusSuccess); //Displaying user Thank you message for payment. _thankYouMessage.hidden = false; _payButton.hidden = true; _donateAgainButton.hidden =false; }
- (IBAction)donateAgainPressed:(id)sender { _payButton.hidden =false; _donateAgainButton.hidden= true; _thankYouMessage.hidden = true; }


