Build a secure payment client for iOS devices with the In-App Payments SDK.
In-App Payments SDK

Build on iOS

Objective C (iOS)

To use the example code in this guide, make sure you have the following information available:

  • Your application ID. Find your application ID on the Credentials page of your Square application in the Developer Dashboard.

  • An active location ID. Copy a developer account location ID from the Locations page of your Square application in the Developer Dashboard or set the Developer Dashboard to Sandbox mode and then copy a Sandbox location ID.

    Important

    While the In-App Payments SDK supports payments for physical and digital sales, using the In-App Payments SDK to process digital sales might not be allowed by some mobile application distribution services (such as App Store and Google Play) and might result in your application being removed. Examples of digital sales include intangible goods (such as in-game assets), online services (such as upgrades in application functionality), and digital subscriptions (such as cloud or streaming services).

    To avoid the potential removal from application distribution platforms, the In-App Payments SDK should only be used to process sales of goods or services that are consumed outside the application. You should review the terms of service for the respective mobile application distribution services you use to ensure that you are compliant with their guidelines.

Update REPLACE_ME in the following code with your Square application ID. If you do not set your Square application ID before initializing SQIPCardEntryViewController, your application terminates with an uncaught exception.

Important

To test an application in the Square Sandbox, set the Developer Dashboard to Sandbox mode before completing the following instructions in this step.

Replace <# REPLACE_ME #> with your application ID. For example, the application ID sq0ids-KHbh5gEaJuH7GEi1lgGMBQ replaces the placeholder as shown in the following code:

[SQIPInAppPaymentsSDK setSquareApplicationID:@"sq0ids-KHbh5gEaJuH7GEi1lgGMBQ"];

Note

When testing your application in the Square Sandbox, be sure to use Sandbox test values to enter card information.

The In-App Payments SDK supports all orientations on the iPad, but only supports portrait orientations on the iPhone.

If your application supports landscape on the iPhone, you should conform to UINavigationControllerDelegate and override the supported interface orientations.

Initialize a SQIPCardEntryViewController with a SQIPTheme instance and present the view controller as a modal. You can customize the appearance of the card entry form by setting SQIPTheme properties. For more information, see Customize the Payment Entry Form.

Important

The card entry form should always be displayed in a UINavigationController. For example, let nc = OrderNavigationController(rootViewController: orderViewController), where the orderViewController renders the In-App Payments card entry form.

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
@import SquareInAppPaymentsSDK;

@interface <
#YourViewController #>() < SQIPCardEntryViewControllerDelegate> @end

@implementation <
#YourViewController #>

    - (void)showCardEntryForm;
{
  SQIPTheme *theme = [[SQIPTheme alloc] init];

  // Customize the card entry form
  theme.tintColor = UIColor.greenColor;
  theme.saveButtonTitle = @"Submit";

  SQIPCardEntryViewController *cardEntryForm =
      [[SQIPCardEntryViewController alloc] initWithTheme:theme];
  cardEntryForm.delegate = self;

  // The card entry form should always be displayed in a UINavigationController.
  // The card entry form can also be pushed onto an existing navigation controller.
  UINavigationController *navigationController =
      [[UINavigationController alloc] initWithRootViewController:cardEntryForm];

  [self presentViewController:navigationController animated:YES completion:nil];
}

#pragma mark - SQIPCardEntryViewControllerDelegate

- (void)cardEntryViewController:(nonnull SQIPCardEntryViewController *)cardEntryViewController
          didCompleteWithStatus:(SQIPCardEntryCompletionStatus)status;
{
  // Implemented in Step 4.
}

- (void)cardEntryViewController:(nonnull SQIPCardEntryViewController *)cardEntryViewController
           didObtainCardDetails:(nonnull SQIPCardDetails *)cardDetails
              completionHandler:(void (^_Nonnull)(NSError *_Nullable))completionHandler;

{
  // Implemented in Step 4.
}
@end

This build guide has shown you how to:

  • Configure your application for the SDK (step 1).

  • Set the card entry form orientation (step 2).

  • Show the card entry form in your view controller (step 3).

  • Create a stub function to handle card entry results (step 3).

In this step, you learn how to handle the result of the card entry by getting the on-time-use secure payment token from the card entry form and sending the token to your backend to be processed as a payment. You add code to the stubbed card entry response delegates from step 3 to get the payment token and send it to your backend.

Your application must take two actions after the payment token is returned:

  • Send the token to your backend for payment processing.

  • Handle the buyer's action of the card entry completion or cancellation.

Guidance for :didObtainCardDetails:completionHandler:

Use the card entry view controller delegate methods to complete the payment processing after a buyer provides a payment card by submitting the payment token to your backend, awaiting a response, and then updating the mobile application with the results.

  • Submit the payment token to your backend. The handler is invoked after the buyer submits a payment card. Your code should send the provided card details to your backend to perform any additional work, such as charging the card. After your backend processes the card, notify the card entry view controller of the result so it can be displayed to the buyer.

  • Handle backend results. If your backend processes the card with no error, call the completion handler with a single nil argument. A success animation is shown to the buyer and cardEntryViewController:didCompleteWithStatus: is called. At this point, you should dismiss the card entry view controller.

  • Handle card processing errors. If your backend returns an error while processing the card, call the completion handler with the error. The localizedDescription error is shown in the card entry view controller. The buyer can read the error text, edit the entered card information, and then resubmit the payment.

The following mobile client example code assumes that you have created a backend service for your application to process the payment token received from the In-App Payments SDK. The backend service calls the Payments API to create a payment that charges the card input by a buyer in your mobile client. For more information about taking a payment, see Take Payments.

Guidance for :didCompleteWithStatus:

  • Invoked when the card entry form is completed. The status parameter indicates whether the card entry succeeded or was canceled.

  • Use this method to dismiss the card entry view controller and update any other application state.

The following class is an example of how you can use a REST operation to send the payment token to your backend server so it can be processed in a CreatePayment call:

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
class ChargeApi {
    static public func processPayment(_ nonce: String, completion: @escaping (String?, String?) -> Void) {
        let url = URL(string: Constants.Square.CHARGE_URL)!
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        let json = ["nonce": nonce]
        let httpBody = try? JSONSerialization.data(withJSONObject: json)
        request.addValue("Application/json", forHTTPHeaderField: "Content-Type")
        request.httpBody = httpBody
        URLSession.shared.dataTask(with: request) { data, response, error in
            if let error = error as NSError?{
                if error.domain == NSURLErrorDomain {
                    DispatchQueue.main.async {
                        completion("", "Could not contact host")
                    }
                } else {
                    DispatchQueue.main.async {
                        completion("", "Something went wrong")
                    }
                }
            } else if let data = data {
                do {
                    let json = try JSONSerialization.jsonObject(with: data, options: []) as! [String: Any]
                    if let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 {
                        DispatchQueue.main.async {
                            completion("success", nil)
                        }
                    } else {
                        DispatchQueue.main.async {
                            completion("", json["errorMessage"] as? String)
                        }
                    }
                } catch {
                    DispatchQueue.main.async {
                        completion("", "Failure")
                    }
                }
            }
        }.resume()
    }
}

When your backend service has received the payment token from your mobile application, it can take a payment but it can also use the token to store a card on file for the customer. Your mobile application must provide enough customer information for the backend to find the customer using the SearchCustomers endpoint. For example, if your mobile application has the buyer's email address and sends it to your backend along with the payment token.

To learn how to save a card on file from your backend, see Create a Card on File and a Payment.

To build with the In-App Payments SDK on iOS, the following must be true:

  • The deployment target for your application is iOS 10.0 or later.

  • You have added the In-App-Payments SDK to your iOS project. For more information, see Install the In-App-Payments SDK.

Additionally, this guide makes the following assumptions:

  • You have a Square account enabled for payment processing. If you have not enabled payment processing on your account (or you are not sure), visit squareup.com/activate.

  • You are generally familiar with developing applications on iOS. If you are new to iOS development, you should read The Basics at Swift.org.

  • You are using Xcode 9+.

If you need more assistance, contact Developer Support or ask for help in the Developer Forums.