ios

Offer Affirm as a payment option on iOS.

Overview

Starting a payment with Affirm on an iOS client consists of creating a checkout form, tokenizing customer information to transmit it securely to your server, and using that token to initiate a charge.

This guide walks you through setting up the iOS client on your checkout page.

The iOS SDK is available on Github.

1. Set up Affirm on iOS

With CocoaPods

1. If you haven't already, install the latest version of CocoaPods.
2. If you don't have an existing Podfile, run the following command to create one:

pod init

3. Add this line to your Podfile:

pod 'AffirmSDK'

4. Run the following command:

pod install

5. Don't forget to use the .xcworkspace file to open your project in Xcode, instead of the .xcodeproj file, from here on out.
6. In the future, to update to the latest version of the SDK, just run:

pod update AffirmSDK

With Carthage

1. If you haven't already, install the latest version of Carthage.
2. Add this line to your Cartfile:

github "Affirm/affirm-merchant-sdk-ios"

3. Follow the Carthage installation instructions.
4. In the future, to update to the latest version of the SDK, run the following command:

carthage update affirm-merchant-sdk-ios --platform ios

🚧

For details on the latest SDK release and past versions, see the Releases page on GitHub. To receive notifications when a new release is published, watch releases for the repository.

2. Initialize Affirm

Configure the SDK with your Affirm public API key to send requests to the Affirm server.

AffirmConfiguration.shared.configure(publicKey: "YOUR PUBLIC KEY", environment: .sandbox, merchantName: "Affirm Example Swift")
[[AffirmConfiguration sharedInstance] configureWithPublicKey:@"YOUR PUBLIC KEY" environment:AffirmEnvironmentSandbox merchantName:@"Affirm Example"];

3. Render Affirm checkout

Checkout creation is the process in which a customer uses Affirm to pay for a purchase in your app. You can create a checkout object and launch the Affirm checkout using the Checkout function.

let dollarPrice = NSDecimalNumber(string: self.amountTextField.text)
        let item = AffirmItem(name: "Affirm Test Item", sku: "test_item", unitPrice: dollarPrice, quantity: 1, url: URL(string: "http://sandbox.affirm.com/item")!)
        let shipping = AffirmShippingDetail.shippingDetail(name: "Chester Cheetah", line1: "633 Folsom Street", line2: "", city: "San Francisco", state: "CA", zipCode: "94107", countryCode: "USA")
        let checkout = AffirmCheckout(items: [item], shipping: shipping, taxAmount: NSDecimalNumber.zero, shippingAmount: NSDecimalNumber.zero, discounts: nil, metadata: nil, financingProgram: nil, orderId: "JKLMO4321")

        let controller = AffirmCheckoutViewController.start(checkout: checkout, useVCN: false, delegate: self)
        present(controller, animated: true, completion: nil)
// initialize an AffirmItem with item details
AffirmItem *item = [AffirmItem itemWithName:@"Affirm Test Item" SKU:@"test_item" unitPrice:price quantity:1 URL:[NSURL URLWithString:@"http://sandbox.affirm.com/item"]];

// initialize an AffirmShippingDetail with the user's shipping address
AffirmShippingDetail *shipping = [AffirmShippingDetail shippingDetailWithName:@"Chester Cheetah" addressWithLine1:@"633 Folsom Street" line2:@"" city:@"San Francisco" state:@"CA" zipCode:@"94107" countryCode:@"USA"];

// initialize an AffirmCheckout object with the item(s), shipping details, tax amount, shipping amount, discounts, financing program, and order ID
AffirmCheckout *checkout = [[AffirmCheckout alloc] initWithItems:@[item] shipping:shipping taxAmount:[NSDecimalNumber zero] shippingAmount:[NSDecimalNumber zero] discounts:nil metadata:nil financingProgram:nil orderId:@"JKLMO4321"];

// The minimum requirements are to initialize the AffirmCheckout object with the item(s), shipping details, and payout Amount
AffirmCheckout *checkout = [AffirmCheckout checkoutWithItems:@[item] shipping:shipping payoutAmount:price];

// initialize an UINavigationController with the checkout object and present it
UINavigationController *nav = [AffirmCheckoutViewController startCheckoutWithNavigation:checkout useVCN:NO getReasonCodes:NO delegate:self];
[self presentViewController:nav animated:YES completion:nil];

// It is recommended that you round the total in the checkout request to two decimal places. Affirm SDK converts the float total to integer cents before initiating the checkout, so may round up or down depending on the decimal places. Ensure that the rounding in your app uses the same calculation across your other backend systems, otherwise, it may cause an error of 1 cent or more in the total validation on your end.

4. Add Affirm promotional messaging

Affirm promotional messaging components---monthly payment messaging and educational modals---show customers how they can use Affirm to finance their purchases. Promos consist of promotional messaging, which appears directly in your app, and a modal, which offers users an ability to prequalify.

To create a promotional messaging view, we provided the AffirmPromotionalButton class, which only requires you to configure and add to your view for implementation.

To implement the 'AffirmPromotionalButton':

self.promotionalButton = [[AffirmPromotionalButton alloc] initWithPromoID:@"promo_set_ios"
                                                                  showCTA:YES
                                                                 pageType:AffirmPageTypeProduct
                                                 presentingViewController:self
                                                                    frame:CGRectMake(0, 0, 315, 34)];
[self.stackView insertArrangedSubview:self.promotionalButton atIndex:0];

Use the following to display or refresh promotional messaging:

[self.promotionalButton configureByHtmlStylingWithAmount:[NSDecimalNumber decimalNumberWithString:amountText]
                                          affirmLogoType:AffirmLogoTypeName
                                             affirmColor:AffirmColorTypeBlue
                                           remoteFontURL:[NSURL URLWithString:@"https://fonts.googleapis.com/css?family=Saira+Stencil+One&display=swap"]
                                            remoteCssURL:url];
self.promotionalButton.configure(amount: NSDecimalNumber(string: amountText),
                         affirmLogoType: .name,
                            affirmColor: .blue,
                                   font: UIFont.italicSystemFont(ofSize: 15),
                              textColor: .gray)

Use the following steps to use local fonts:

1. Add the font files to your project (make sure that the files are targeted properly to your application).
2. Add the font files to your App-Info.plist.
3. Use the font in your CSS file. For example:

@font-face
{
font-family: 'OpenSansCondensed-Bold';
src: local('OpenSansCondensed-Bold'),url('OpenSansCondensed-Bold.ttf') format('truetype');
}

body {
font-family: 'OpenSansCondensed-Light';
font-weight: normal;
!important;
}

📘

If no promotional message is returned, the button will be hidden automatically.

Tapping on the Promotional button automatically opens a modal in an AffirmPrequalModalViewController with more information, including (if you have it configured) a button that prompts the user to prequalify for Affirm financing.

Retrieve raw string from 'As low as' message

You can retrieve raw string using AffirmDataHandler.

NSDecimalNumber *dollarPrice = [NSDecimalNumber decimalNumberWithString:self.amountTextField.text];
[AffirmDataHandler getPromoMessageWithPromoID:@"promo_set_ios"
                                       amount:dollarPrice
                                      showCTA:YES
                                     pageType:AffirmPageTypeBanner
                                     logoType:AffirmLogoTypeName
                                    colorType:AffirmColorTypeBlue
                                         font:[UIFont boldSystemFontOfSize:15]
                                    textColor:[UIColor grayColor]
                     presentingViewController:self
                            completionHandler:^(NSAttributedString *attributedString, UIViewController *viewController, NSError *error) {
                                [self.promoButton setAttributedTitle:attributedString forState:UIControlStateNormal];
                                self.promoViewController = viewController;
}];

After that, you could present promo modal using the following:

UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:self.promoViewController];
[self presentViewController:nav animated:YES completion:nil];
  • initWithPromoId - Affirm provides this Promo ID

    • showCTA - To display link to modal
    • pageType - Affirm provides this Page type
  • Configure Button:

    • configureWithAmount: The price of the product or cart in NSDecimalNumber format
    • affirmLogoType: Set as either AffirmDisplayTypeLogo, AffirmDisplayTypeText, AffirmDisplayTypeSymbol, or AffirmDisplayTypeSymbolHollow
    • affirmColor: Set as either AffirmColorTypeBlue, AffirmColorTypeBlack, or AffirmColorTypeWhite

Add an educational modal

Tapping on AffirmAsLowAsButton opens an educational modal based on the following:

  • When alaEnabled is set to true and the amount is greater than or equal to 50, the customer sees a product modal with pricing information
  • When alaEnabled is set to true and the amount is less than 50, the customer sees a site modal without pricing information
  • When alaEnabled is set to false, the customer sees a site modal without pricing information

To display a modal elsewhere in the application, initialize and display an instance of the modal VC as follows:

Tapping on the Promotional button automatically opens a modal in an AffirmPrequalModalViewController with more information, including (if you have it configured) a button that prompts the user to prequalify for Affirm financing.

AffirmPromoModalViewController *viewController = [[AffirmPromoModalViewController alloc] initWithPromoId:@"promo_id" amount:amount delegate:delegate];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:viewController];
[self.presentingViewController presentViewController:nav animated:YES completion:nil];
  • amount: The price of the product or cart in NSDecimal (value less than 50 opens a site modal with no pricing information)
  • promoId: Affirm provides this Promo ID

Track Order Confirmed

The trackOrderConfirmed event triggers when a customer completes their purchase. The SDK provides the AffirmOrderTrackerViewController class to track it, it requires AffirmOrder and an array with AffirmProduct.

[AffirmOrderTrackerViewController trackOrder:order products:@[product0, product1]];

📘

This feature will be improved after the endpoint is ready for app and will disappear after 5 seconds.

5. Handle callbacks

The AffirmCheckoutDelegate object which receives messages at various stages in the checkout process. It will return checkout_token from this delegate.

func checkout(_ checkoutViewController: AffirmCheckoutViewController, completedWithToken checkoutToken: String)
- (void)checkout:(AffirmCheckoutViewController *)checkoutViewController completedWithToken:(NSString *)checkoutToken

For more callbacks, please see the code reference.

👍

Once the checkout has been successfully confirmed by the user, the AffirmCheckoutDelegate object will receive a checkout_token. This token should be forwarded to your server, which should then be used to authorize a charge on the user's account.

6. Create a charge

When a customer successfully completes a checkout, it is recorded as a new purchase attempt. This needs to be handled on your server-side to be fulfilled via our Charges API.