stripe-ios/README.md

162 lines
9.6 KiB
Markdown
Raw Normal View History

2012-11-15 11:50:42 +08:00
# Stripe iOS Bindings
The Stripe iOS bindings make it easy to collect your users' credit card details inside your iOS app. By creating [tokens](https://stripe.com/docs/api#tokens), Stripe handles the bulk of PCI compliance by preventing sensitive card data from hitting your server (for more, see [our article about PCI compliance](https://support.stripe.com/questions/do-i-need-to-be-pci-compliant-what-do-i-have-to-do)).
We've written a [tutorial](https://stripe.com/docs/mobile/ios) that explains how to get started with Stripe on iOS, or read on!
2012-11-13 00:54:08 +08:00
## Installation
2014-08-21 17:05:11 +08:00
You can add Stripe to your project via Cocoapods or include it manually. These bindings support all versions of iOS after and including iOS 5.0.
### CocoaPods
[CocoaPods](http://cocoapods.org/) is a common library dependency management tool for Objective-C. To use the Stripe iOS bindings with CocoaPods, simply add the following to your `Podfile` and run `pod install`:
2014-05-05 09:51:34 +08:00
pod 'Stripe'
2014-08-21 16:52:14 +08:00
Note: be sure to use the `.xcworkspace` to open your project in Xcode instead of the `.xcodeproj`.
### Copy manually
2014-08-21 17:11:00 +08:00
1. Clone this repository (`git clone https://github.com/stripe/stripe-ios`)
2012-11-17 02:06:03 +08:00
1. In the menubar, click on 'File' then 'Add files to "Project"...'
2014-08-21 17:11:00 +08:00
1. Select the 'Stripe' directory in your cloned stripe-ios repository (make sure not to include the stripe-ios top-level directory, you want the Stripe subfolder).
2012-11-17 02:06:03 +08:00
1. Make sure "Copy items into destination group's folder (if needed)" is checked"
1. Click "Add"
2012-11-13 00:54:08 +08:00
2014-08-21 16:52:14 +08:00
You will also need to add the `Security` framework to your project.
## Integration
2014-08-21 16:52:14 +08:00
First, you need to create a series of views to collect your users' card details. We've created a reusable component for this purpose called PaymentKit, or you can roll your own.
2013-03-21 02:55:15 +08:00
Note: previous versions of Stripe-iOS included PaymentKit as a dependency. This, along with the `STPView` class (which interfaced with PaymentKit), has been removed as of version 1.2. If you are using any `STPView`s in your project and would like to upgrade, please see the "Migrating from versions < 1.2" section below.
2014-08-21 16:52:14 +08:00
### Using PaymentKit
2013-03-21 02:55:15 +08:00
2014-08-22 17:42:30 +08:00
See the README at https://github.com/stripe/PaymentKit.
2013-03-21 02:55:15 +08:00
2014-08-21 16:52:14 +08:00
### Tokenization
2013-03-21 02:55:15 +08:00
2014-08-21 16:52:14 +08:00
Once you have your card details, you'll want to package them into an STPCard object:
2012-11-15 11:50:42 +08:00
2014-08-21 16:52:14 +08:00
STPCard *card = [STPCard new];
card.number = myCardField.number;
card.expMonth = myCardField.expMonth;
card.expYear = myCardField.expYear;
card.cvc = myCardField.cvc;
2014-02-12 12:49:44 +08:00
2014-08-21 16:52:14 +08:00
Then, send it off to Stripe:
[Stripe createTokenWithCard:card
publishableKey:@"my_publishable_key"
completion:^(STPToken *token, NSError *error) {
if (error) {
2014-08-21 16:52:14 +08:00
// alert the user to the error
} else {
2014-08-21 16:52:14 +08:00
// use the token to create a charge (see below)
}
}];
2014-08-21 16:52:14 +08:00
(Replace `@"my_publishable_key"` in the above example with [your publishable key](https://manage.stripe.com/account/apikeys).)
2014-08-21 16:52:14 +08:00
### Using tokens
Once you've collected a token, you can send it to your server to [charge immediately](https://stripe.com/docs/api#create_charge) or [create a customer](https://stripe.com/docs/api#create_customer) to charge in the future.
These operations need to occur in your server-side code (not the iOS bindings) since these operations require [your secret key](https://manage.stripe.com/account/apikeys).
2014-02-12 12:49:44 +08:00
## Misc. notes
2012-11-15 11:50:42 +08:00
2014-02-12 12:49:44 +08:00
If you do not wish to send your publishableKey every time you make a call to createTokenWithCard, you can also call `[Stripe setDefaultPublishableKey:]` with your publishable key. All Stripe subsequent API requests will use this key.
2012-11-15 11:50:42 +08:00
### Retrieving a token
If you're implementing a complex workflow, you may want to know if you've already charged a token (since they can only be charged once). You can do so if you have the token's ID:
2013-03-21 02:55:15 +08:00
[Stripe getTokenWithId:@"token_id"
2013-02-22 07:15:08 +08:00
publishableKey:@"my_publishable_key"
completion:^(STPToken *token, NSError *error)
2012-11-15 11:50:42 +08:00
{
if (error)
2012-11-15 11:56:23 +08:00
NSLog(@"An error!");
2012-11-15 11:50:42 +08:00
else
2012-11-15 11:56:23 +08:00
NSLog(@"A token for my troubles.");
}];
2012-11-15 11:50:42 +08:00
### Handling errors
2014-04-22 03:19:33 +08:00
See [StripeError.h](https://github.com/stripe/stripe-ios/blob/master/Stripe/StripeError.h).
2012-11-15 11:50:42 +08:00
### Operation queues
2014-04-22 03:19:33 +08:00
API calls are run on `[NSOperationQueue mainQueue]` by default, but all methods have counterparts that can take a custom operation queue.
2012-11-15 23:52:23 +08:00
2012-11-15 11:50:42 +08:00
### Validation
2012-11-15 23:52:23 +08:00
You have a few options for handling validation of credit card data on the client, depending on what your application does. Client-side validation of credit card data is not required since our API will correctly reject invalid card information, but can be useful to validate information as soon as a user enters it, or simply to save a network request.
The simplest thing you can do is to populate your `STPCard` object and, before sending the request, call `- (BOOL)validateCardReturningError:` on the card. This validates the entire card object, but is not useful for validating card properties one at a time.
To validate `STPCard` properties individually, you should use the following:
- (BOOL)validateNumber:error:
- (BOOL)validateCvc:error:
- (BOOL)validateExpMonth:error:
- (BOOL)validateExpYear:error:
These methods follow the validation method convention used by [key-value validation](http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/KeyValueCoding/Articles/Validation.html). So, you can use these methods by invoking them directly, or by calling `[card validateValue:forKey:error]` for a property on the `STPCard` object.
When using these validation methods, you will want to set the property on your card object when a property does validate before validating the next property. This allows the methods to use existing properties on the card correctly to validate a new property. For example, validating `5` for the `expMonth` property will return YES if no `expYear` is set. But if `expYear` is set and you try to set `expMonth` to 5 and the combination of `expMonth` and `expYear` is in the past, `5` will not validate. The order in which you call the validate methods does not matter for this though.
2014-08-22 17:42:30 +08:00
## Example app
The example app is a great way to see the flow of recording credit card details, converting them to a token with the Stripe iOS bindings, and then using that token to charge users on your backend. It uses [PaymentKit](https://github.com/stripe/PaymentKit) to create a simple credit card form, and a small backend hosted with Parse Cloud Code to process the actual transactions.
### Running the example
Before you can run the app, you need to provide it with your own Stripe and Parse API keys.
#### Stripe
1. If you haven't already, sign up for a [Stripe account](https://dashboard.stripe.com/register) (it takes seconds). Then go to https://dashboard.stripe.com/account/apikeys.
2. Replace the `StripePublishableKey` constant in Example/StripeExample/Constants.m with your Test Publishable Key.
3. Replace the `stripe_secret_key` variable in Example/Parse/cloud/main.js with your Test Secret Key.
#### Parse
1. Sign up for a [Parse account](https://parse.com/#signup), then create a new Parse app.
2. Head to the "Application keys" section of your parse app's settings page. Replace the `ParseApplicationId` and `ParseClientKey` constants in Example/StripeExample/Constants.m with your app's Application ID and Client Key, respectively.
3. Replace the appropriate values in Example/Parse/config/global.json with your Parse app's name, Application ID, and Master Secret. IMPORTANT: these values, along with your Stripe Secret Key, can be used to control your Stripe and Parse accounts. Thus, once you edit these files, you shoudn't check them back into git.
4. Install the Parse command line tool at https://www.parse.com/docs/cloud_code_guide#started, then run `parse deploy` from the Example/Parse directory.
After this is done, you can make test payments through the app (use credit card number 4242 4242 4242 4242, along with any cvc and any future expiration date) and then view them in your Stripe Dashboard!
2012-11-15 11:50:42 +08:00
## Running the tests
2012-11-13 00:54:08 +08:00
1. Open Stripe.xcodeproj
1. Select either the iOS or OS X scheme in the toolbar at the top
1. Go to Product->Test
## Migrating from versions < 1.2
As mentioned above, versions of Stripe-iOS prior to 1.2 included a class called `STPView`, which provided a pre-built credit card form. This functionality has been moved from Stripe-iOS to PaymentKit, a separate project. If you were using `STPView` prior to version 1.2, migrating is simple:
1. Add PaymentKit to your project, as explained on its [project page](https://github.com/stripe/PaymentKit).
2. Replace any references to `STPView` with a `PKView` instead. Similarly, any classes that implement `STPViewDelegate` should now instead implement the equivalent `PKViewDelegate` methods. Note that unlike `STPView`, `PKView` does not take a Stripe API key in its constructor.
3. To submit the credit card details from your `PKView` instance, where you would previously call `createToken` on your `STPView`, replace that with the following code (assuming `self.paymentView` is your `PKView` instance):
if (![self.paymentView isValid]) {
return;
}
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;
[Stripe createTokenWithCard:card completion:^(STPToken *token, NSError *error) {
if (error) {
// handle the error as you did previously
} else {
// submit the token to your payment backend as you did previously
}
}];