iOS SDK

Integrate our drop-in Checkout SDK into your iOS app.


The Checkout SDK is our quickest way of integrating 250+ supported payment methods and 3D Secure into your iOS app.

It comes with a pre-built UI that allows for some customization. For more control over the UI, you can also present the payment form using your own UI. 

The SDK handles presenting a list of payment methods to the shopper, collecting their details, and submitting them to Adyen. It also takes care of encrypting and transmitting sensitive payment data, so it never touches your server. To use the SDK, you'll also need to set up a server that can create a payment session and verify the result of payments.

To accept online payments with the Checkout SDK, you'll need to:

  1. Integrate the iOS SDK.
  2. Create a payment session from your server.
  3. Verify the payment result on your server.

Before accepting live payments, we also recommend that you test your integration.

To see an example of an iOS SDK integration, check out our GitHub.

Before you begin

Before you start integrating with the Checkout SDK, make sure that you have performed the following steps:
  1. Sign up for an Adyen test account at https://www.adyen.com/signup
  2. Get your API Key. Save a copy as you'll need it for API calls you make to the Adyen payments platform.

For more information on these steps, refer to Get started with Adyen.

Step 1: Integrate SDK

To add the Checkout SDK to your app:

  1. Import the SDK

    Add the SDK to your project using either CocoaPods or Carthage:
    CocoaPods

    1. Add pod 'Adyen' to your Podfile.
    2. Run pod install.

    Carthage 

    1. Add github "adyen/adyen-ios" to your Cartfile.
    2. Run carthage update.
    3. Link the framework with your target as described in Carthage Readme.
  2. Integrate payment form

    Integrate the payment form into your app by initiating and starting a CheckoutController.

    var checkoutController: CheckoutController?
    
    func startCheckout() {
        checkoutController = CheckoutController(presentingViewController: self, delegate: self)
        checkoutController?.start()
    }
  3. Request payment session 

    As part of the CheckoutControllerDelegate protocol, implement the following method.

    func requestPaymentSession(withToken token: String, for checkoutController: CheckoutController, responseHandler: @escaping (String) -> Void)

    This will be called when the SDK generates a token. Pass this token to your server to create a payment session. Then, provide the retrieved paymentSession to the responseHandler closure. This will initiate the payment method selection.

    func requestPaymentSession(withToken token: String, for checkoutController: CheckoutController, responseHandler: @escaping (String) -> Void) {    let url = URL(string: "https://checkoutshopper-test.adyen.com/checkoutshopper/demoserver/paymentSession")!
     
        let parameters: [String: Any] = [
            "amount": [
                "currency": "EUR",
                "value": 17408
            ],
            "channel": "ios",
            "reference": "Your order number",
            "token": TOKEN_GENERATED_BY_SDK,
            "returnUrl": "my-shopping-app://",
            "countryCode": "NL",
            "shopperReference": "user349857934"
        ]
     
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.httpBody = try? JSONSerialization.data(withJSONObject: parameters, options: [])
        request.allHTTPHeaderFields = [
            "Content-Type": "application/json",
            "X-Demo-Server-API-Key": "Checkout_DEMO_API_key" // Replace with your own Checkout Demo API key.
        ]
     
        let session = URLSession(configuration: .default)
        session.dataTask(with: request) { data, _, error in
            if let error = error {
                fatalError("Failed to retrieve payment session: \(error)")
            } else if let data = data {
                do {
                    guard let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else { fatalError() }
                    guard let paymentSession = json["paymentSession"] as? String else { fatalError() }
     
                    responseHandler(paymentSession)
                } catch {
                    fatalError("Failed to parse payment session response: \(error)")
                }
            }
        }.resume()
    }
  4. Handle redirects

    For many local payment methods, such as iDEAL and SOFORT,  the shopper will be redirected to a webpage or app to verify the payment. Once completed, they'll be redirected back to your app. Implement the following method of your UIApplicationDelegate to handle the shopper returning to your app.

    func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey: Any] = [:]) -> Bool {
        let adyenHandled = Adyen.applicationDidOpen(url) 
        if !adyenHandled {
            //Adyen did not handle the url
            //Provide additional url handling logic for your app if needed
        }
        return true
    }
  5. Handle payment result 

    After the payment has been processed, implement the didFinish method of the CheckoutControllerDelegate protocol to get the payment result. Present the result to the shopper in your app. For a list of possible payment results and what these mean, refer to Result codes.

    You'll also receive a payload value. Send this to your server to verify the result of the payment.

    func didFinish(with result: Result<PaymentResult>, for checkoutController: CheckoutController) {
        switch result {
        case let .success(paymentResult):
            // Payment successfully sent to Adyen
            // Check the paymentResult.status for the payment result
        case let .failure(error):
            // User or SDK Error, attempt payment again.
        }
    }

Step 2: Create payment session

Tokenized payments

If you have a subscription or recurring business model, we recommend using our tokenization service. See Recurring and subscription payments for details.

A payment session is used to securely transmit payment data between the shopper and the Adyen payments platform. Create one from your server by making a POST request to the  /paymentSession endpoint.

Specify your merchantAccount name, a channel of iOS, and the URL scheme of your app for the returnUrl.

Also include the amount, your unique reference for this payment, and the countryCode of the shopper.

Finally, include the token generated by the SDK.

You can also use our demo server until you have implemented your own:
https://checkoutshopper-test.adyen.com/checkoutshopper/demoserver/

curl -H "Content-Type: application/json" -H "X-API-Key: YourAPIkey" -X POST -d '{ 
       "merchantAccount": "YourMerchantAccount",
       "returnUrl": "my-shopping-app://",
       "channel": "ios",
       "amount": { 
          "currency": "EUR", 
          "value": "17408"
       }, 
       "reference": "Your order number",
       "countryCode": "NL",
       "shopperLocale": "nl_NL",
       "token": "TOKEN_GENERATED_BY_SDK"
    }' https://checkout-test.adyen.com/v40/paymentSession

Execute this code from your server, not your app. This helps to prevent tampering with transaction data.

The response will contain a paymentSession. Use this to initialize the SDK.

Step 3: Verify payment result

Once the payment has been completed, verify its result from your server with a /payments/result request. Include the payload that was generated by the SDK.

curl \
-H "Content-Type: application/json" \
-H "X-API-Key: YourAPIkey" \
-X POST \
-d '{ "payload": "2he28Ddhwj242he28Ddhwj..." }' \
https://checkout-test.adyen.com/v40/payments/result

If the payment was successful you'll receive an Authorised resultCode and a pspReference, which is our unique identifier for the transaction. If you've set up notifications, you'll also receive a successful AUTHORISATION notification.

If you received a different resultCode, check our result codes documentation for what action you should take.

Next, let's look at how you can test your integration.

Testing your integration

Before going live, use our list of  test cards and other payment methods to test your integration. We recommend testing each payment method that you intend to offer to your shoppers.

You can check the status of a test payment in your Customer Area, under TransactionsPayments.

When you've completed testing, there are some additional steps you'll need to complete before you can accept live payments from shoppers. Refer to Getting started with Adyen for more information.

Customizing your Checkout

You can customize the list of payment methods presented in the payment form by sorting and filtering them.

If you need more control over the look of the payment form, we recommend building your own UI. 

Recurring and subscription payments

We recommend using our  tokenization service to handle recurring payments and subscriptions.

To tokenize the shopper's payment details collected by the SDK, send additional parameters when creating a payment sessionPass enableOneClick and enableRecurring as true. Also provide a shopperReference to uniquely identify this shopper. This will act as the container for the shopper's tokenized payment details. The shopperReference will be stored when the token is created. 

curl https://checkout-test.adyen.com/v40/paymentSession \
-H "X-API-key: [Your API Key here]" \
-H "Content-Type: application/json" \
-d '{ 
       "merchantAccount": "YourMerchantAccount",
       "returnUrl": "my-shopping-app://",
       "channel": "ios",
       "amount": { 
          "currency": "EUR", 
          "value": 17408
       }, 
       "reference": "Your order number",
       "countryCode": "NL",
       "shopperLocale": "nl_NL",
       "shopperReference":"yourShopperId_IOfW3k9G2PvXFu2j",
       "enableRecurring": true,
       "enableOneClick": true,
       "token": "TOKEN_GENERATED_BY_SDK"
    }'
# Set your X-API-KEY with the API key from the Customer Area.
adyen = Adyen::Client.new
adyen.api_key = "YOUR X-API-KEY"

response = adyen.checkout.paymentSession({
  :merchantAccount => "YourMerchantAccount",
  :returnUrl => "my-shopping-app://",
  :channel => "ios",
  :amount => {
    :currency => "EUR",
    :value => 17408
  },
  :reference => "Your order number",
  :countryCode => "NL",
  :shopperLocale => "nl_NL",
  :shopperReference => "yourShopperId_IOfW3k9G2PvXFu2j"
  :enableRecurring => true,
  :enableOneClick => true,
  :token => "TOKEN_GENERATED_BY_SDK"
}) 
// Set your X-API-KEY with the API key from the Customer Area.
Config config = new Config();
config.setApiKey("Your X-API-KEY"));
Client client = new Client(config);

Checkout checkout = new Checkout(client);
PaymentSessionRequest paymentSessionRequest = new PaymentSessionRequest();
Amount amount = new Amount();
amount.setCurrency("EUR");
amount.setValue(17408);
paymentSessionRequest.setReference("Your order number");
paymentSessionRequest.setCountryCode("NL");
paymentSessionRequest.setShopperLocale("nl_NL");
paymentSessionRequest.setAmount(amount);
paymentSessionRequest.setChannel("YourSDKPlatform");
paymentSessionRequest.setEnableRecurring(true);
paymentSessionRequest.setEnableOneClick(true);
paymentSessionRequest.setShopperReference("yourShopperId_IOfW3k9G2PvXFu2j");
paymentSessionRequest.setReturnUrl("YourReturnURL");
paymentSessionRequest.setMerchantAccount("YourMerchantAccount");
paymentSessionRequest.setToken("TOKEN_GENERATED_BY_SDK");
PaymentSessionResponse response = checkout.payments(paymentsRequest);
// Set your X-API-KEY with the API key from the Customer Area.
$client = new \Adyen\Client();
$client->setXApiKey("YOUR X-API-KEY");
$service = new \Adyen\Service\Checkout($client);

$params = array(
  "amount" => array(
    "currency" => "EUR",
    "value" => 17408
  ),
  "reference" => "Your order number",
  "channel" => "ios",
  "shopperReference" => "YourUniqueIdForTheShopper",
  "countryCode" => "NL",
  "shopperLocale" => "nl_NL",
  "returnUrl" => "my-shopping-app://",
  "merchantAccount" => "YourMerchantAccount",
  "enableRecurring" => true,
  "enableOneClick" => true,
  "token" => "TOKEN_GENERATED_BY_SDK"
);
$result = $service->payments($params); 

Next, find out if the shopper's payment details was successfully tokenized by verifying the payment result. If  the  resultCode  is  Authorised,  a  recurringDetailReference value  is also returned in the response. This is the identifier for the shopper's tokenized payment details.

If the resultCode is Pending, the payment details will be tokenized when the payment reaches an Authorised status. You will be informed of the status change through a webhook via our notification service. The recurringDetailReference is included in the notification if the payment has been authorised. For other result codes, see Pending and Refusal result codes.

Lastly, save the recurringDetailReference. You will use this and your corresponding shopperReference to make future payments. For more information, see Making payments with tokens.

Next steps

Set up notifications

Receive confirmation when a payment is authorised or fails.

link

Add payment methods

Learn about payment methods and how to integrate them.

link

Payment modifications

Find out how to cancel, refund, or capture a payment using our API.

link