In-App Payments SDK

Build on iOS

Build with In-App Payments SDK on iOS to provide a secure, managed payments client.

iOS
In-App Payments SDK
Objective C (iOS)

Prerequisites and assumptions
Permalink Get a link to this section

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

  • The deployment target for your app is iOS 10.0 or newer.

  • You have added the In-App-Payments SDK to your iOS project. See Installing In-App-Payments SDK for more information.


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 apps on iOS. If you are new to iOS development, we recommend reading the The Basics at Swift.org.

  • You are using Xcode 9+.

Important

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

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

Information you will need
Permalink Get a link to this section

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 setting page of your Square application.

  • An active location ID. Copy a valid Developer Account location ID from the Locations setting page of your Square application in the Developer Dashboard, or set the dashboard to Sandbox Settings mode and then copy a sandbox location ID.

Step 1: Set your Square Application ID in your app delegate
Permalink Get a link to this section

Update REPLACE_ME in the code below with your Square Application ID. If you do not set your Square application ID before initializing the SQIPCardEntryViewController, your app will terminate with an uncaught exception.

Important

For testing an app in the v2 Sandbox: In your app Application Dashboard, set the dashboard to Sandbox Settings mode before completing the following instructions in this step.

@import SquareInAppPaymentsSDK;

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  [SQIPInAppPaymentsSDK setSquareApplicationID:@"<# REPLACE_ME #>"];
  return YES;
}

Step 2: Create and display the card entry form to collect card information
Permalink Get a link to this section

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. See the Customize the payment entry form recipe for more information.

Important

The card entry form should always be displayed in a UINavigationController.

@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

Note

When testing your app in the v2 Sandbox, be sure to use sandbox test values to input card information.

Step 3: Set supported orientations for the card entry form
Permalink Get a link to this section

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

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

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

@implementation <
#YourViewController #>

    - (UIInterfaceOrientationMask)navigationControllerSupportedInterfaceOrientations : (
          UINavigationController *)navigationController;
{ return UIInterfaceOrientationMaskPortrait; }

@end

Step 4: Implement SQIPCardEntryViewControllerDelegate methods
Permalink Get a link to this section

In this step, you will implement the stubs you added previously.

Implementation guidance for _:didObtainCardDetails:completionHandler:
Permalink Get a link to this section

  • Invoked after the user has submitted their card information. Your implementation should send the provided card details to your server to perform any additional work such as charging the card. After your server has processed the card, notify the card entry view controller of the result so it can be displayed to the user.

  • If your server processed the card with no error, call the completion handler with a single nil argument. A success animation is shown to the user, and cardEntryViewController:didCompleteWithStatus: is called, at which point you should dismiss the card entry view controller.

  • If your server returned an error while processing the card, call the completion handler with the error. Its localizedDescription is shown in the card entry view controller. The user reads the error text and can edit their card information and then re-submit.

Implementation guidance for _:didCompleteWithStatus:
Permalink Get a link to this section

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

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

#pragma mark - SQIPCardEntryViewControllerDelegate

- (void)cardEntryViewController:(nonnull SQIPCardEntryViewController *)cardEntryViewController
          didCompleteWithStatus:(SQIPCardEntryCompletionStatus)status;
{
  // Note: If you pushed the card entry form onto an existing navigation controller,
  // use [self.navigationController popViewControllerAnimated:YES] instead
  [self dismissViewControllerAnimated:YES completion:nil];
}

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

{
  // Send card nonce to your server to charge the card or store the card on file.
  // When a response is received, call the completionHandler with `nil` for success,
  // or an error to indicate failure.

  /*
  [MyAPIClient.shared chargeCardWithNonce:cardDetails.nonce
                               completion:^(id transaction, NSError *chargeError) {
      if (chargeError) {
          completionHandler(chargeError);
      } else {
          completionHandler(nil);
      }
  }];
  */

  completionHandler(nil);
}

Next steps

Now that you have a basic build in place, expand on it with these recipes!