WePay

iOS Integration (beta)

PCI Compliance

While using our iOS SDK greatly reduces the scope of PCI Compliance and increases your security, you're still required to be compliant with the Payment Card Industry Data Security Standards (PCI-DSS) and the Payment Application Data Security Standards (PA-DSS) whenever applicable.

Use of our iOS SDK will require you to apply for credit card tokenization API access. Please apply for approval on your application's dashboard.

This tutorial will explain how to integrate the new iOS SDK to accept payments in your mobile application. On a high level, it will accomplish the following:

  1. Collect user credit card information.
  2. Send user credit card details to WePay to be converted into a single use token.
  3. Send token to your server for charge.

You can find the full source code for this tutorial on GitHub.

This tutorial assumes some knowledge of Xcode and iOS development. If you have never built a mobile application before, please check out Apple's beginners tutorial.

Let's get started!

In Xcode 5.0, create a project and select "Single View Application" as your template. Where it asks you to choose the options for your project, type "WP" (without the quotes) as the class prefix. We will use StoryBoard in this tutorial.

Open Main.storyboard. Add the following text fields to Main.storyboard, and then create IBOutlet properties for each text field:

TextField Outlet property name
Name on Card name
User Email email
Credit Card Number creditCardNumber
Expiration Month expirationMonth
Expiration Year expirationYear
Security Code securityCode
Zipcode zipcode

Make sure to specify the appropriate Placeholder text and Keyboard type for each text field.

Add a submit button to the Storyboard. Then, Control+Right click on the button and drag and drop into the Assistant Editor to create an IBAction for it. Name the action "submit".

If you need more assistance on how to create the IBOutlets and IBAction, click here for a step-by-step guide of this part of the tutorial.

Integrating the WePay API

Integrating the new WePay iOS SDK greatly reduces your scope of PCI Compliance and increases your security because WePay tokenizes credit card information and provides the token for your application to use when charging the card. However, you're still required to be compliant with the Payment Card Industry Data Security Standards (PCI-DSS) and the Payment Application Data Security Standards (PA-DSS) whenever applicable.

Download the WePay iOS SDK on Github and add the files to your Xcode project:

  1. In your Xcode menu bar, click on "File" then "Add files to Project".
  2. Select the "WePay" directory in the downloaded repository.
  3. Make sure the "Copy items into the destination group's folder" option is checked.
  4. Click Add.

To help prevent fraud, WePay iOS SDK requires the AdSupport.framework to send a user's IP and device ID to WePay whenever the user makes a payment. Navigate to your application's target, scroll down to 'Linked Frameworks and Libraries', and add the AdSupport.framework. Please see the Github Readme file for information on how to disable the collection of this data.

Now that you have the iOS SDK files included in your project, you can use the SDK to submit the form to WePay.

Send card to WePay

To make API calls, you will need to create an API application on WePay.com. WePay provides two environments: stage (stage.wepay.com) and production (wepay.com). Stage is used for testing, and production is used when you're ready to go live.

Since this is a test application, create an application on stage.

After creating an application on stage.wepay.com, open the WPAppDelegate.m file in Xcode, and import WePay.h.

WPAppDelegate.m
#import "WePay.h"

In the same file, set your client ID in - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions to use WePay's testing environment (stage.wepay.com).

[WePay setStageClientId: @"CLIENT_ID"];

Of course, you can call the function below instead to use WePay's production environment (wepay.com):

[WePay setProductionClientId: @"CLIENT_ID"];

Before you use our production environment to accept payments in your mobile application, you will need to go to your application dashboard and apply for credit card tokenization API access. The approval process is instant. Check out this short tutorial for instructions.

Submit payment form to WePay

Open the WPViewController class header, and import WPCreditCard.h.

#import "WPCreditCard.h"

Next, add the code to submit the payment form to WePay:

WPViewController.m
- (IBAction)submit:(id)sender {

    // Pass in the user's information
    WPUserDescriptor * userDescriptor = [[WPUserDescriptor alloc] init];
    userDescriptor.name = self.name.text;
    userDescriptor.email = self.email.text;
    userDescriptor.address = [[WPAddressDescriptor alloc] initWithZip: self.zipcode.text];

    // Pass in the customer's card details
    WPCreditCardDescriptor * cardDescriptor = [[WPCreditCardDescriptor alloc] init];
    cardDescriptor.number = self.creditCardNumber.text;
    cardDescriptor.expirationMonth = [self.expirationMonth.text intValue];
    cardDescriptor.expirationYear = [self.expirationYear.text intValue];
    cardDescriptor.securityCode = self.securityCode.text;
    cardDescriptor.user = userDescriptor;

    // Send the user's card details to WePay and receive back a token.
    [WPCreditCard createCardWithDescriptor: cardDescriptor success: ^(WPCreditCard * tokenizedCard) {

        // Card token from WePay.
        NSLog(@"Token: %@", tokenizedCard.creditCardId);

        // Send token to your servers.
        [self sendToken: tokenizedCard.creditCardId];

    } failure:^(NSError * error) {

        // Handle errors

        NSLog(@"%@", error);

        // Show an alert view with the error description.
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message: [error localizedDescription] delegate:self cancelButtonTitle:@"Return" otherButtonTitles:nil];
        [alert show];

    }];
}

In our SDK, we have several "descriptor" classes that are used to pass in user input. For example, in the code above, we pass in the user's details into "descriptor" classes (WPAddressDescriptor, WPUserDescriptor, and WPCardDescriptor) and then call WPCreditCard createCardWithDescriptor static method with the card descriptor as parameter. The createCardWithDescriptor function will validate and send all of this information to WePay. WePay responds with a token (ID of the credit card) that can be assessed inside the success callback. If the user's input does not validate, or if WePay API responds with an error, or if there is a network error, the error callback is executed.

Send token to your server

The success callback in the createCardWithDescriptor function (see previous code example) executes whenever WePay returns a token. You need to send the token off to your own server to charge the card. To do so, add the sendToken function below to WPViewController.

WPViewController.h
#import <UIKit/UIKit.h>
#import "WPCreditCard.h"

@interface WPViewController : UIViewController

// Sends token from WePay to your server
- (void) sendToken: (NSString *) creditCardId;

@end
WPViewController.m
- (void) sendToken: (NSString *) creditCardId {

    // Change https://example.com to your server url
    // where you want to send token
    NSURL * callUrl = [NSURL URLWithString: @"https://example.com"];
    NSMutableURLRequest * request = [[NSMutableURLRequest alloc] initWithURL: callUrl];

    [request setHTTPMethod: @"POST"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [request setValue:@"charset" forHTTPHeaderField:@"utf-8"];

    NSString *body     = [NSString stringWithFormat:@"creditCardId=%@", creditCardId];
    request.HTTPBody   = [body dataUsingEncoding:NSUTF8StringEncoding];

    NSOperationQueue *queue = [NSOperationQueue mainQueue];

    [NSURLConnection sendAsynchronousRequest:request
                                       queue: queue
                           completionHandler:^(NSURLResponse *response, NSData  *data, NSError * requestError)
    {
           if(requestError) {
               // Handle error
           }
           else
           {
               // Handle success
               UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Success!" message:@"Thanks for your payment." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
               [alert show];

           }
    }];
}

Change the "https://example.com" to your server url where you want to send the token and add the code to handle success and failure. Make sure any communication to your server is SSL secured to prevent eavesdropping.

At this point, if you Build and Run the application in iPhone Simulator, you should see the payment form, but if you fill out a text field, you won't be able to remove the keyboard that appears.

Removing the Keyboard

When the user taps on the background of the view, the keyboard should go away. We don't want it to stick on the screen. Let's make the keyboard disappear.

WPViewController.m
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    NSLog(@"touchesBegan:withEvent:");
    [self.view endEditing:YES];
    [super touchesBegan:touches withEvent:event];
}

Last Step

We are almost done! You need to set up an endpoint on your server that can receive an HTTP POST call containing a parameter called creditCardId. To charge the card, make a /checkout/create call with the payment_method_id (ID of the credit card) and payment_method_type ("credit_card") as request parameters. This will execute the payment immediately. See sample code below.

Authorize a card for future use

If you just want to store the card (and not charge it right now), you should make the /credit_card/authorize call. If you don't charge the card (via /checkout/create) or authorize it (via /credit_card/authorize) within 30 minutes of making the /credit_card/create call, the credit card will not be saved, and you will not be able to use it later.

API Call:

  • PHP
  • Ruby
  • Python
<?php
// WePay PHP SDK - http://git.io/mY7iQQ
require 'wepay.php';

// application settings
$account_id = 123456789;
$client_id = 123456789;
$client_secret = "1a3b5c7d9";
$access_token = "1a3b5c7d9";

// credit card id from IOS app to charge
$credit_card_id = $_POST['creditCardId'];

// change to useProduction for live environments
Wepay::useStaging($client_id, $client_secret);

$wepay = new WePay($access_token);

// charge the credit card
$response = $wepay->request('checkout/create', array(
  'account_id'    => $account_id,
  'amount'    => '25.50',
  'currency'      =>  'USD',
  'short_description' => 'A brand new soccer ball',
  'type'      => 'GOODS',
  'payment_method_id' => $credit_card_id, // user's credit_card_id
  'payment_method_type' => 'credit_card'
));

// display the response
print_r($response);
?>
# WePay Ruby SDK - http://git.io/a_c2uQ
require 'WePay_API_v2_Ruby_SDK.rb'

# application settings
account_id = 123456789
client_id = 123456789
client_secret = '1a3b5c7d9'
access_token = '1a3b5c7d9'

# get credit card id sent by your IOS app
credit_card_id = params[:creditCardId]

# set _use_stage to false for live environments
wepay = WePay.new(client_id, client_secret, _use_stage = true)

# charge the credit card
response = wepay.call('/checkout/create', access_token, {
:account_id       => account_id,
:amount         => '25.50',
:short_description    => 'A brand new soccer ball',
:type         => 'GOODS',
:payment_method_id    => credit_card_id, # the user's credit_card_id
:payment_method_type  => 'credit_card'
})

# display the response
p response
# WePay Python SDK - http://git.io/v7Y1jA
from wepay import WePay

# application settings
account_id = 123456789
access_token = '1a3b5c7d9'
production = False

# get credit card id sent by your IOS app
credit_card_id = request.POST['creditCardId']

# set production to True for live environments
wepay = WePay(production, access_token)

# charge the credit card
response = wepay.call('/checkout/create', {
'account_id': account_id,
'amount': '25.50',
'short_description': 'A brand new soccer ball',
'type': 'GOODS',
'payment_method_id': credit_card_id, # the user's credit_card_id
'payment_method_type': 'credit_card'
})

# display the response
print response

Response:

{
"checkout_id":12345,
"state":"authorized"
}

Voila! There you have it, a simple integration of the new WePay iOS SDK.

Next steps

Not only can you use the token the app sends to your servers to charge the user immediately, but you can also use it to create a subscription!

What's
Next?