Apple Pay in your native app

This document is intented for Apple Pay in your iOS native application. For Apple Pay in your web application please see the web guide

Integrating Apple Pay with PayEngine

Introduction

This document is designed to help our partners seamlessly integrate Apple Pay into their applications using PayEngine's services.

Prerequisites

Step-by-Step Integration Process

  • Enroll in Apple Developer Program: Ensure you have a developer account with Apple.

  • Configure Apple Pay in Xcode: Enable Apple Pay capability in your app's project settings.

  • Add Merchant ID: Create and configure your merchant ID in the Apple Developer portal.

    1. Go to Apple's Developer Portal and log in to the Member Center to create a new Merchant ID.

    2. Navigate to the Certificates, Identifiers, and Profiles area of the Member Center, and then begin the Register Merchant ID process.

    3. You must then provide this Merchant ID to PayEngine associate to enable Apple Pay for your merchant.

  • Generating the Certificate Signing Request Once you provide Merchant ID to PayEngine you will be provided a CSR to associate with the merchant in your Apple Developer Portal

    1. In Apple's Developer Portal, click on the Merchant ID and then click "Edit".

    2. Click "Create Certificate".

    3. You are obtaining a CSR file from a Payment Provider so you will not have to create one. Click "Continue" to proceed to the upload page.

    4. Click "Choose File..." and select the CSR file provided by PayEngine.

2. Integration with PayEngine

API Integration

  • Integrating APIs: Use PayEngine’s APIs to connect your app with our payment processing system.

    // Example Swift code for integrating PayEngine API
    import PayEngine
    
    class ApplePayViewController: UIViewController, PEApplePayDelegate {
        let amount = 1.00
        
        let config = PEConfig(publicKey: "<API Public key")
        let payengine = PayEngine(config: config)
        
        func paymentSheetDidMDismiss() {
            //Handle Payment Sheet dismiss 
        }
        
        func paymentTokenDidReturn(token: String, completion: @escaping (PEApplePayResult) -> Void) {
            print("paymentTokenDidReturn \(token)")
            makePaymentWithToken(token: token, completion: completion)
        }
        
        func paymentTokenNotAvailable() {
            //Handle Payment token not available 
            print("paymentTokenNotAvailable")
        }
        
        //This is just an example of you calling your backend to complete the transaction.
        //Call completion(.success) or completion(.failure) to close the payment sheet
        private func makePaymentWithToken(token: String, completion: @escaping (PEApplePayResult) -> Void) {
            let json: [String: Any] = [
                "merchant_id": MERCHANT_ID,
                "data": [
                    "cardToken": token,
                    "transactionAmount": amount
                ]
            ]
    
            let jsonData = try? JSONSerialization.data(withJSONObject: json)
    
            let url = URL(string: <your-backend-url>)!
            var request = URLRequest(url: url)
            request.httpMethod = "POST"
            request.setValue("Basic " + <your-api-key>, forHTTPHeaderField: "Authorization")
            request.setValue("\(String(describing: jsonData?.count))", forHTTPHeaderField: "Content-Length")
            request.setValue("application/json", forHTTPHeaderField: "Content-Type")
             request.httpBody = jsonData
    
            let task = URLSession.shared.dataTask(with: request) { data, response, error in
                guard let data = data, error == nil else {
                    print(error?.localizedDescription ?? "No data")
                    return
                }
                let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
                if let responseJSON = responseJSON as? [String: Any] {
                    print(responseJSON) //Code after Successfull POST Request
                    if let responseData = responseJSON["data"] as? [String: Any] {
                        print("responseData: \(responseData)")
                        completion(.success)
                        return
                    }
                }
                
                completion(.failure)
            }
    
            task.resume()
        }
        
        // Sample UI code
        @IBOutlet weak var stackView: UIStackView!
        
        required init?(coder: NSCoder) {
            super.init(coder: coder)
        }
        
        override func viewDidLoad() {
            payengine.applePay(merchantId: <merchant-id>) { result in
                switch result {
                    
                case .success(let applePay):
                    // register callbacks to this view controller
                    applePay.delegate = self
                    
                    let request = ApplePayPaymentRequest()
                    request.build(paymentItems: [
                        // leave empty or list of PKPaymentSummaryItem
                    ], paymentAmount: self.amount, currencyCode: "USD")
                    DispatchQueue.main.async {
                        if let button = applePay.setupApplePayButton(for: request, type: .checkout) {
                            /// apple pay is available, add the button to your UI
                            self.stackView.addSubview(button)
                        }
                    }
                case .failure(let error):
                    print("Unable to setup apple pay: \(error)")
                }
            }
            
        }
    }

3. Handling Multiple Merchant IDs (MIDs)

  • Multiple MIDs: Manage various merchant IDs in your app by following Apple's guidelines.

  • Implementation Tips: Ensure your app can switch between MIDs based on the transaction context.

Last updated