Checkout iOS SDK
A comprehensive iOS SDK for integrating payment processing into your iOS applications. This SDK provides a secure, user-friendly checkout experience with support for multiple payment methods, currencies, and customization options.
Table of Contents
- Overview
- Features
- Installation
- Quick Start
- Basic Usage
- Configuration
- Callbacks
- Advanced Features
- Example App
- Troubleshooting
- Architecture
- API Reference
Overview
The Checkout iOS SDK allows you to integrate payment processing into your iOS app with just a few lines of code. It handles the complex payment flow, security, and user interface, so you can focus on your app's core functionality.
What does it do?
- 💳 Processes payments securely
- 🌍 Supports multiple currencies and payment methods
- 📱 Handles both card and digital wallet payments
- 🔐 Manages security and encryption automatically
Features
✅ Multiple Payment Methods: Credit/Debit cards, Apple Pay, Google Pay, and more
✅ Multi-Currency Support: Process payments in various currencies
✅ Localization: Support for English and Arabic languages
✅ Security: Built-in encryption and security measures
✅ Card Scanner: Scan card details using device camera
✅ Real-time Validation: Instant feedback on payment details
Requirements
- iOS 13.0 or later
- Xcode 12.0 or later
- Swift 5.0 or later
Swift Package Manager
- Open your project in Xcode
- Go to File > Add Package Dependencies
- Enter the repository URL: https://github.com/Tap-Payments/Checkout-IOS
- Click Add Package
Manual Installation
- Download the SDK from the releases page
- Drag the Checkout-IOSfolder into your Xcode project
- Make sure to add it to your target
Quick Start
Here's how to get started with the Checkout SDK in just 5 minutes:
1. Import the SDK
import Checkout_IOS2. Create a Basic Checkout
class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupCheckoutButton()
    }
    
    func setupCheckoutButton() {
        let checkoutButton = UIButton(type: .system)
        checkoutButton.setTitle("Pay Now", for: .normal)
        checkoutButton.addTarget(self, action: #selector(startCheckout), for: .touchUpInside)
        // Add button to your view and set constraints
    }
    
    @objc func startCheckout() {
        // Minimum required configuration
        let config = [
        "hashString": "",
        "language": "en",
        "themeMode": "light",
        "supportedPaymentMethods": "ALL",
        "paymentType": "ALL",
        "selectedCurrency": "KWD",
        "supportedCurrencies": "ALL",
        "supportedPaymentTypes": [],
        "supportedRegions": [],
        "supportedSchemes": [],
        "supportedCountries": [],
        "gateway": [
            "publicKey": "pk_key",
            "merchantId": ""
        ],
        "customer": [
            "firstName": "First Name",
            "lastName": "Last Name",
            "email": "[email protected]",
            "phone": [
                "countryCode": "965",
                "number": "55567890"
            ]
        ],
        "transaction": [
            "mode": "charge",
            "charge": [
                "saveCard": true,
                "auto": [
                    "type": "VOID",
                    "time": 100
                ],
                "redirect": [
                    "url": "https://demo.staging.tap.company/v2/sdk/checkout"
                ],
                "threeDSecure": true
            ]
        ],
        "amount": "5",
        "order": [
            "id": "",
            "currency": "KWD",
            "amount": "5",
            "items": [
                [
                    "amount": "5",
                    "currency": "KWD",
                    "name": "Item Title 1",
                    "quantity": 1,
                    "description": "item description 1"
                ]
            ]
        ],
        "cardOptions": [
            "showBrands": true,
            "showLoadingState": false,
            "collectHolderName": true,
            "preLoadCardName": "",
            "cardNameEditable": true,
            "cardFundingSource": "all",
            "saveCardOption": "all",
            "forceLtr": false,
            "alternativeCardInputs": [
                "cardScanner": true,
                "cardNFC": true
            ]
        ],
        "isApplePayAvailableOnClient": true,
    ]
        
        // Start the checkout process
        CheckoutSDK().start(configurations: config, delegate: self)
    }
}3. Handle the Results
extension ViewController: CheckoutSDKDelegate {
    var controller: UIViewController {
        return self
    }
    
    func onReady() {
        print("Checkout is ready!")
    }
    
    func onSuccess(data: String) {
        print("Payment successful: \(data)")
        // Handle successful payment
    }
    
    func onError(data: String) {
        print("Payment failed: \(data)")
        // Handle payment error
    }
    
    func onClose() {
        print("Checkout was closed")
        // Handle checkout cancellation
    }
}That's it! You now have a working payment system.
Basic Usage
Understanding the Flow
sequenceDiagram
    participant App as Your App
    participant SDK as Checkout SDK
    participant UI as Payment UI
    participant Server as Payment Server
    
    App->>SDK: start(configurations, delegate)
    SDK->>UI: Present checkout interface
    UI->>App: onReady()
    
    Note over UI: User enters payment details
    
    UI->>Server: Process payment
    Server->>UI: Payment result
    
    alt Payment Success
        UI->>App: onSuccess(data)
    else Payment Failed
        UI->>App: onError(data)
    end
    
    UI->>App: onClose()Step-by-Step Integration
Step 1: Configure Your Payment
let configurations = [
    // Required: Amount to charge
    "amount": "25.99",
    
    // Required: Gateway configuration
    "gateway": [
        "publicKey": "pk_test_your_key_here",
        "merchantId": "your_merchant_id"
    ],
    
    // Required: Customer information
    "customer": [
        "firstName": "John",
        "lastName": "Doe",
        "email": "[email protected]",
        "phone": [
            "countryCode": "1",
            "number": "1234567890"
        ]
    ],
    
    // Required: Order details
    "order": [
        "currency": "USD",
        "amount": "25.99",
        "items": [
            [
                "name": "Premium Subscription",
                "amount": "25.99",
                "currency": "USD",
                "quantity": 1,
                "description": "Monthly premium subscription"
            ]
        ]
    ]
]Step 2: Initialize and Start
let checkoutSDK = CheckoutSDK()
checkoutSDK.start(configurations: configurations, delegate: self)Step 3: Implement the Delegate
extension YourViewController: CheckoutSDKDelegate {
    // This tells the SDK which view controller to present from
    var controller: UIViewController {
        return self
    }
    
    // Called when the checkout UI is ready
    func onReady() {
        // Optional: Show loading indicator, log analytics, etc.
        print("Checkout interface is ready")
    }
    
    // Called when payment is successful
    func onSuccess(data: String) {
        // Parse the success data and update your UI
        print("Payment completed successfully!")
        
        // Example: Show success message
        showSuccessAlert(message: "Payment successful!")
        
        // Example: Navigate to success screen
        navigateToSuccessScreen()
    }
    
    // Called when payment fails
    func onError(data: String) {
        // Parse the error data and handle accordingly
        print("Payment failed: \(data)")
        
        // Example: Show error message
        showErrorAlert(message: "Payment failed. Please try again.")
    }
    
    // Called when user closes the checkout
    func onClose() {
        // Handle checkout cancellation
        print("User closed the checkout")
    }
}Configuration
Basic Configuration Options
let configurations = [
    // REQUIRED FIELDS
    "amount": "10.00",                    // Amount to charge
    "gateway": [...],                     // Gateway configuration
    "customer": [...],                    // Customer details
    "order": [...],                       // Order information
    
    // OPTIONAL FIELDS
    "language": "en",                     // "en" or "ar"
    "themeMode": "light",                 // "light", "dark", "dynamic"
    "supportedPaymentMethods": "ALL",     // "ALL" or specific methods
    "selectedCurrency": "USD",            // Default currency
    "paymentType": "ALL"                  // "ALL", "WEB", "CARD", "DEVICE"
]Gateway Configuration
"gateway": [
    "publicKey": "pk_test_your_public_key",    // Your public key from the dashboard
    "merchantId": "your_merchant_id"           // Your merchant ID
]⚠️ Important: Use pk_test_ for testing and pk_live_ for production.
Customer Configuration
"customer": [
    "firstName": "John",
    "lastName": "Doe",
    "email": "[email protected]",
    "phone": [
        "countryCode": "1",               // Country code without +
        "number": "1234567890"            // Phone number
    ]
]Order Configuration
"order": [
    "id": "order_123",                    // Optional: Your order ID
    "currency": "USD",                    // Currency code (USD, EUR, GBP, etc.)
    "amount": "25.99",                    // Order amount
    "items": [                            // Array of items
        [
            "name": "Product Name",
            "amount": "25.99",
            "currency": "USD",
            "quantity": 1,
            "description": "Product description"
        ]
    ]
]Callbacks
Understanding what each callback means and how to handle them:
onReady()
func onReady() {
    // The checkout interface has loaded and is ready for user interaction
    // This is a good place to:
    // - Hide loading indicators
    // - Log analytics events
    // - Update UI state
}onSuccess(data: String)
func onSuccess(data: String) {
    // Payment was processed successfully
    // The 'data' parameter contains payment details in JSON format
    
    // Example of parsing the data:
    if let jsonData = data.data(using: .utf8) {
        do {
            let paymentResult = try JSONSerialization.jsonObject(with: jsonData) as? [String: Any]
            let transactionId = paymentResult?["id"] as? String
            print("Transaction ID: \(transactionId ?? "Unknown")")
        } catch {
            print("Failed to parse payment data")
        }
    }
    
    // Update your app's state
    // - Save transaction details
    // - Update user's account
    // - Show success message
    // - Navigate to confirmation screen
}onError(data: String)
func onError(data: String) {
    // Payment failed or encountered an error
    // The 'data' parameter contains error details
    
    // Common error handling:
    if data.contains("cancelled") {
        // User cancelled the payment
        print("Payment was cancelled by user")
    } else if data.contains("declined") {
        // Payment was declined
        print("Payment was declined")
        showAlert(title: "Payment Declined", message: "Please check your card details")
    } else {
        // Other errors
        print("Payment error: \(data)")
        showAlert(title: "Error", message: "Something went wrong. Please try again.")
    }
}onClose()
func onClose() {
    // The checkout interface was closed
    // This is called after onSuccess, onError, or when user manually closes
    
    // Clean up any resources
    // - Remove loading indicators
    // - Reset UI state
    // - Log analytics
}Advanced Features
Theme Customization
"themeMode": "light"        // Default light theme
"themeMode": "dark"         // Dark theme
"themeMode": "dynamic"   // Dynamic themePayment Method Selection
// Allow all payment methods
"supportedPaymentMethods": "ALL"
// Specific payment methods
"supportedPaymentMethods": ["VISA", "MASTERCARD", "APPLE_PAY"]Card Options
"cardOptions": [
    "showBrands": true,                    // Show card brand logos
    "collectHolderName": true,             // Ask for cardholder name
    "cardNameEditable": true,              // Allow editing card name
    "saveCardOption": "all",               // Show save card option
    "alternativeCardInputs": [
        "cardScanner": true,               // Enable card scanning
        "cardNFC": true                    // Enable NFC reading
    ]
]Multi-language Support
"language": "en"    // English
"language": "ar"    // ArabicExample App
The following example app demonstrates all SDK features:
https://github.com/Tap-Payments/Checkout-IOS/tree/main/CheckoutExample
Running the Example
- Open CheckoutExample.xcodeproj
- Add your test API keys in ViewController.swift
- Run the app on simulator or device
Key Features Demonstrated
- Basic Integration: Simple payment flow
- Configuration Options: All customization options
- Callback Handling: Proper response handling
- UI Customization: Theme and language options
Example App Structure
CheckoutExample/
├── ViewController.swift              # Main example implementation
├── CheckoutSettingsViewController.swift  # Configuration options
└── Storyboards/                     # UI layoutsTroubleshooting
Common Issues
1. SDK Not Starting
Problem: Nothing happens when calling start()
Solution:
- Check that all required fields are provided
- Verify your public key is correct
- Ensure the delegate is properly set
2. Payment Fails Immediately
Problem: onError is called immediately
Solution:
- Verify your API keys are correct
- Check network connectivity
- Ensure amount is properly formatted
3. UI Not Displaying Properly
Problem: Checkout interface looks broken Solution:
- Check iOS version compatibility
- Verify theme mode settings
- Test on different devices
4. Callbacks Not Working
Problem: Delegate methods not being called Solution:
- Ensure your class conforms to CheckoutSDKDelegate
- Check that controllerproperty returns the correct view controller
- Verify delegate is set before calling start()
Debug Mode
// Enable debug logging (for development only)
CheckoutSDK.debugMode = trueTesting
- Use test API keys for development
- Test with different card numbers
- Verify error handling with invalid data
Architecture
SDK Structure Overview
graph TB
    A[Your App] --> B[CheckoutSDK]
    B --> C[CheckoutViewController]
    C --> D[WebView Payment Interface]
    C --> E[Network Layer]
    C --> F[Security Layer]
    
    B --> G[CheckoutSDKDelegate]
    G --> H[onReady]
    G --> I[onSuccess]
    G --> J[onError]
    G --> K[onClose]
    
    E --> L[Payment Gateway]
    F --> M[Encryption/Security]API Reference
CheckoutSDK
Methods
func start(configurations: [String: Any], delegate: CheckoutSDKDelegate)Starts the checkout process with the given configuration.
Parameters:
- configurations: Dictionary containing payment configuration
- delegate: Object implementing CheckoutSDKDelegate protocol
CheckoutSDKDelegate
Required protocol for handling checkout events.
Properties
var controller: UIViewController { get }The view controller that should present the checkout interface.
Methods
func onReady()Called when the checkout interface is ready for user interaction.
func onSuccess(data: String)Called when payment is processed successfully.
- data: JSON string containing payment details
func onError(data: String)Called when payment fails or encounters an error.
- data: String containing error information
func onClose()Called when the checkout interface is closed.
Support
For questions, issues, or feature requests:
- 📧 Email: [email protected]
Updated 30 days ago