Apple Pay Tutorial: Getting Started
Enter the world of mobile payments on iOS in this Apple Pay tutorial! You’ll learn how to implement Apple Pay in your iOS apps to collect payment for physical goods and services. By Erik Kerber.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Apple Pay Tutorial: Getting Started
45 mins
- Getting Started
- Setting Up Your App for Apple Pay
- Adding the Apple Pay Button
- Creating a Payment Request
- Populating PKPaymentRequest
- Implementing Delegates to Handle Payment Requests
- Handling Shipping, Billing, and Contact Information
- Adding Shipping Costs
- Responding to Changes in the Shipping Address
- Adding Variable Shipping Costs
- Responding to Changes in the Shipping Method
- Fulfilling Payment Transactions
- Generating Apple Pay Certificates
- Creating a Basic Order Management Server
- Integrating the Stripe Apple Pay SDK
- Where to Go From Here?
Creating a Basic Order Management Server
For any app that uses Apple Pay, you’ll likely have a corresponding backend to handle the actual order fulfillment. For this tutorial, you’ll create a lightweight server to receive payment requests from your app and send them to Stripe for processing.
Stripe provides several libraries you can find on their website to help creating your payment request. For now, you’ll create a single-file Python server using the lightweight Python REST framework Flask along with the Stripe Python SDK.
First, you’ll need pip, which is a command-line utility for installing python packages. If you don’t have pip installed, you can install it by following the instructions found here.
Next, open Terminal and use pip to install Flask by entering the following command:
sudo pip install Flask
Next, install the Python Stripe library with the following command:
sudo pip install --index-url https://code.stripe.com --upgrade stripe
Next, use a text editor to create a file called ApplePaySwagServer.py. You can place this in the same directory as your Xcode project, if you like.
In your text editor of choice, add the following code:
import stripe
from flask import Flask
from flask import request
from flask import json
app = Flask(__name__)
#1
@app.route('/pay', methods=['POST'])
def pay():
#2
# Set this to your Stripe secret key (use your test key!)
stripe.api_key = "sk_test_YOUR_TEST_KEY_HERE"
#3
# Parse the request as JSON
json = request.get_json(force=True)
# Get the credit card details
token = json['stripeToken']
amount = json['amount']
description = json['description']
# Create the charge on Stripe's servers - this will charge the user's card
try:
#4
charge = stripe.Charge.create(
amount=amount,
currency="usd",
card=token,
description=description
)
except stripe.CardError, e:
# The card has been declined
pass
#5
return "Success!"
if __name__ == '__main__':
# Set as 0.0.0.0 to be accessible outside your local machine
app.run(debug=True, host= '0.0.0.0')
Following the numbered comments above, here’s what the code does:
- Creates a “route” that accepts an HTTP POST at
/pay
. - Sets your Stripe Secret Key. Make sure you use your own Secret Key!
- Parses the JSON request.
- Creates a charge using the Stripe Python SDK. The
amount
is measured in cents. - Returns the string
Success
back to your app.
Start your the server by executing the Python script in Terminal:
python ApplePaySwagServer.py
You’ll know it’s running when you see something like the following in your console:
* Running on http://0.0.0.0:5000/
* Restarting with reloader
Of course, knowing the ins and outs of Python and Flask are not important to learning Apple Pay, but the mini-server you created above helps demonstrate the role your own backend server plays with Apple Pay. In your real-world app, you’d likely add the customer’s order, along with the requisite shipping address, product IDs, and other order information, to a database so the order could be fulfilled.
Integrating the Stripe Apple Pay SDK
Now that you have a lightweight server to accept payments, you just need to send them from your app!
Stripe provides an iOS framework available on GitHub that does most of the heavy lifting for you; the best way to manage this framework is through CocoaPods.
Create a file in the same directory as your .xcodeproj file and name it Podfile.
Open Podfile and add the following line to declare the Stripe Apple Pay library as a dependency:
pod 'Stripe/ApplePay'
Next, open Terminal and navigate to the directory containing your Podfile.
Run the following command to bring in the Stripe SDK:
pod install
As always with CocoaPods, ensure you close your project in Xcode and re-open it using .xcworspace instead of the .xcodeproj
You’ll also need to add a simple preprocessor symbol to your project to enable Apple Pay within the Stripe SDK.
In the project navigator, navigate to ApplePaySwag project\ApplePaySwag target\Build Settings and add the string STRIPE_ENABLE_APPLEPAY to both Debug and Release under Preprocessor Macros, as shown below:
Since the Stripe SDK is written in Objective-C, you’ll need to create a bridging header to use in your Swift code.
In the project navigator, right-click on the root ApplePaySwag folder and select New File. Select iOS\Source\Header File to create a bridging file and name it ApplePaySwag-Bridging-Header.h.
Under your project / target settings, set the path of the Objective-C Bridging Header to ApplePaySwag/ApplePaySwag-Bridging-Header.h
as shown below:
Now open ApplePaySwag-Bridging-Header.h and replace its contents with the following import:
#import <Stripe/Stripe.h>
#import <Stripe/Stripe+ApplePay.h>
The Stripe APIs will now be available to your Swift code.
Open BuySwagViewController.swift and replace the hardcoded PKPaymentAuthorizationStatus.Success
in paymentAuthorizationViewController(controller:,didAuthorizePayment:completion)
with the following code:
// 1
let shippingAddress = self.createShippingAddressFromRef(payment.shippingAddress)
// 2
Stripe.setDefaultPublishableKey("pk_test_YOUR_API_KEY") // Replace With Your Own Key!
// 3
STPAPIClient.sharedClient().createTokenWithPayment(payment) {
(token, error) -> Void in
if (error != nil) {
println(error)
completion(PKPaymentAuthorizationStatus.Failure)
return
}
// 4
let shippingAddress = self.createShippingAddressFromRef(payment.shippingAddress)
// 5
let url = NSURL(string: "http://<your ip address>/pay") // Replace with computers local IP Address!
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
// 6
let body = ["stripeToken": token.tokenId,
"amount": self.swag!.total().decimalNumberByMultiplyingBy(NSDecimalNumber(string: "100")),
"description": self.swag!.title,
"shipping": [
"city": shippingAddress.City!,
"state": shippingAddress.State!,
"zip": shippingAddress.Zip!,
"firstName": shippingAddress.FirstName!,
"lastName": shippingAddress.LastName!]
]
var error: NSError?
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(body, options: NSJSONWritingOptions(), error: &error)
// 7
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) { (response, data, error) -> Void in
if (error != nil) {
completion(PKPaymentAuthorizationStatus.Failure)
} else {
completion(PKPaymentAuthorizationStatus.Success)
}
}
}
This modified authorization uses the Stripe SDK to convert a PKPayment
object into an STPToken
object by sending the PKPayment
to Stripe’s servers for decryption. You can then send the returned STPToken
object to your server.
If everything goes well, you invoke your completion block with PKPaymentAuthorizationStatus.Success
. If you encounter an issue such as a network error, you simply return PKPaymentAuthorizationStatus.Failure
.
Here’s a more detailed look at the code above, comment by comment:
- Grab and parse the final shipping address information from
PKPayment
. This will give you all the information from the selected address. - Set the publishable Stripe key for your app in the Stripe SDK. Make sure to replace the key above with your own publishable key.
- Invoke the Stripe API with the authorized Apple Pay token, which sends the token to Stripe. You invoke a completion block when this action completes; if successful, this returns an
STPToken
. - Create an
Address
struct from the finalshippingAddress
for the final payment amount. - Build an
NSMutableRequest
to invoke a POST call to the/pay
URL. Ensure you replace the IP above with your own server’s IP. This is your computer’s IP on your network, followed by the port listed from your Python server, such ashttp://192.168.1.18:5000/pay
. For this to work, your iOS device and your Mac need to be on the same network. - Construct the JSON for the request. This includes the
token
property ofSTPToken
to be sent to Stripe, the amount, and the description — in this case, the title of the ordered swag. In a real-life scenario, you might also include things such as product IDs in your app so your server knows which item or items were ordered. - Send the request to the server. You invoke the completion block with success or failure depending on the
error
result.
Build and run your app one last time; order all the swag you want and have it sent to your address via race car. The rocket ship option is certainly tempting, but it’s a bit of a spoiler that that the amount is over Stripe’s limit — and probably that of your credit card as well! :]
Finally, head to your Stripe dashboard at https://dashboard.stripe.com/test/dashboard and set the Live/Test switch to Test. You should now see all of your “fake” transactions in your dashboard:
W00t — look at all that money! Well, it’s fake money, but it still looks impressive. :]