Stripe iOS Integration with Swift & Apple Pay (Updated 10/03/2015)

A Swift supplement to Stripe’s iOS Integration tutorial, including ApplePay.

Note: There are three ways to collect card information:

  1. Use Apple Pay framework to access stored payment information
  2. Use Stripe’s pre-built form components, to collect credit card details
  3. Build your own credit card form from scratch

 Step 1: Install Stripe Cocapod

CocoaPods is a common library dependency management tool for iOS development. To use the Stripe CocoaPods, simply add the following to your Podfile and run pod install:

pod 'Stripe'

Note: be sure to use the .xcworkspace to open your project in Xcode instead of the .xcproject.

 Step 2: Create Objective-C to Swift Bridging Header

  1. In the menu click File > New > File > (iOS or OSX) > Source > Header File
  2. Click Next
  3. Name the file “bridge”
  4. Click Create
  5. Select the Project folder and navigate to Build Settings. Then use the search field to locate to Objective-C Bridging Header setting.
  6. Double click on the “Objective-C Bridging Header” line for a popup
  7. Type the absolute path to your bridge.h file (e.g. /Users/me/Workspace/Project/iOS/bridge.h)
  8. Press enter to save the path in the popup and make sure it shows up
  9. In the bridge.h delete everything and type the following import statement:
#import <Stripe/Stripe.h>

 Step 3: Implement Checkout

 Checkout via Stripe’s pre-built form components

  1. In AppDelegate.swift set the publishable key from the Stripe Dashboard.
  2. Set the PTKViewDelegate for your PayViewController.
  3. Create your paymentView and a payment button.
  4. Then check if the paymentView details are valid in order to enable the payment button.
  5. Finally implement the pay button action to create the Stripe Card Token in order to pass back to the back end server for creating a new charge or customer.

Here’s what the sample code might look like:

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool 
    {
        Stripe.setDefaultPublishableKey("ENTER_PUBLISHABLE_KEY_HERE")
        ...
        returns true
    }
}
class PayViewController: UIViewController, STPPaymentCardTextFieldDelegate {

    var payButton: UIButton!
    var paymentTextField: STPPaymentCardTextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        paymentTextField = STPPaymentCardTextField(frame: frame1)
        paymentTextField.center = view.center
        paymentTextField.delegate = self
        view.addSubview(paymentTextField)

        payButton = UIButton(frame: frame2)
        payButton.setTitle("Pay", forState:.Normal)
        payButton.addTarget(self, action: "createToken", forControlEvents: .TouchUpInside)
        payButton.enabled = false
        view.addSubview(payButton)
    }

    func paymentCardTextFieldDidChange(textField: STPPaymentCardTextField) {
        payButton.enabled = textField.isValid
    }

    func createToken() {
        let card = paymentTextField.card!
        Stripe.createTokenWithCard(card) { token, error in
            if let token = token {
                //send token to backend and create charge
            }
        }
    }
}

 Checkout via Apple Pay

  1. Create Merchant ID. See here for details.
  2. Add STRIPE_ENABLE_APPLEPAY to your app’s build settings under “Preprocessor Macros.”
  3. Generate a PKPaymentRequest to submit to Apple. See here and here for greater detail.
  4. Declare PKPaymentAuthorizationViewControllerDelegate and implement the two delegate methods to handle actions taken in the ApplePayController
  5. Take the PKPayment received in the delegate method and convert it to a STPToken using the Stripe.createTokenWithPayment: method.
  6. Finally, pass the token to the back end server for creating a new charge or customer.

Note: Apple Pay doesn’t work in the iOS simulator before iOS 9

Here’s what the sample code might look like:

import PassKit

class CartViewController: UIViewController, PKPaymentAuthorizationViewControllerDelegate {

    var payButton: UIButton!
    let SupportedPaymentNetworks = [PKPaymentNetworkVisa, PKPaymentNetworkMasterCard, PKPaymentNetworkAmex]
    let ApplePayMerchantID = "merchant.com.DOMAIN.APPNAME"

    override func viewDidLoad() {
        super.viewDidLoad()

        payButton = UIButton(frame: frame2)
        payButton.setTitle("Pay", forState:.Normal)
        payButton.addTarget(self, action: "createToken", forControlEvents: .TouchUpInside)
        payButton.enabled = PKPaymentAuthorizationViewController.canMakePaymentsUsingNetworks(SupportedPaymentNetworks)
        view.addSubview(payButton)
    }

    func applePay(price: Double) {
        let item = PKPaymentSummaryItem(label: "CHARGE_NAME_HERE", amount: NSDecimalNumber(double: price))

        let request = PKPaymentRequest()
        request.merchantIdentifier = ApplePayMerchantID
        request.supportedNetworks = SupportedPaymentNetworks
        request.merchantCapabilities = .Capability3DS
        request.countryCode = "US"
        request.currencyCode = "USD"
        request.paymentSummaryItems = [item]
        if Stripe.canSubmitPaymentRequest(request) {
            let applePayController = PKPaymentAuthorizationViewController(paymentRequest: request)
            applePayController.delegate = self
            presentViewController(applePayController, animated: true, completion: nil)
        } else {
            //default to Stripe's PaymentKit Form
        }
    }

    func paymentAuthorizationViewController(controller: PKPaymentAuthorizationViewController!, didAuthorizePayment payment: PKPayment!, completion: ((PKPaymentAuthorizationStatus) -> Void)!) {
        Stripe.createTokenWithPayment(payment) { token, error in
            if let token = token {
               //handle token to create charge in backend
               completion(.Success)
            } else {
                completion(.Failure)
            }
        }
    }

    func paymentAuthorizationViewControllerDidFinish(controller: PKPaymentAuthorizationViewController!) {
        controller.dismissViewControllerAnimated(true, completion: nil)
    }
}

I hope this tutorial made integrating Swift + Stripe + ApplePay a little easier for you. Cheers, and happy hacking.

 
196
Kudos
 
196
Kudos

Now read this

Uber and Land Wars in Asia

You fell victim to one of the classic blunders! The most famous of which is “Never get involved in a land war in Asia,” but only slightly less well-known is this: “Never go against a Sicilian when death is on the line!” - Vizzini in The... Continue →