{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-guides/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["sub-heading","br","details","required","coming-soon"]},"type":"markdown"},"seo":{"title":"Implementation","description":"Transform your commerce with PXP's unified platform—seamless payments, real-time insights, and global growth in one powerful integration.","lang":"en-UK","siteUrl":"https://developer.pxp.io","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"implementation","__idx":0},"children":["Implementation"]},{"$$mdtype":"Tag","name":"SubHeading","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Learn how to use the Apple Pay component for iOS in your iOS application."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"overview","__idx":1},"children":["Overview"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Every component follows the same four-step lifecycle:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Initialise the PXP Checkout SDK with your configuration."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Create the Apple Pay component with your specific configuration."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Mount the component to display the Apple Pay button in your view."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Handle payment results and lifecycle events."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"before-you-start","__idx":2},"children":["Before you start"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To use the Apple Pay component, you first need to:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/install"},"children":["Install Components for iOS"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Complete the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/apple-pay/onboarding"},"children":["Apple Pay onboarding"]}," process in the Unity Portal."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Configure your iOS app with Apple Pay entitlements."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Ensure your merchant certificate is properly configured."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"device-and-os-compatibility","__idx":3},"children":["Device and OS compatibility"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Apple Pay for iOS has specific requirements for optimal functionality."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"supported-ios-versions","__idx":4},"children":["Supported iOS versions"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["iOS 10.0+ for basic Apple Pay support."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["iOS 11.0+ for enhanced contact field support."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["iOS 15.0+ for coupon code support."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"device-requirements","__idx":5},"children":["Device requirements"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["iPhone: iPhone 6 or later with Touch ID or Face ID."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["iPad: iPad Pro, iPad Air 2, iPad (5th generation) or later, iPad mini 3 or later."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Apple Watch: When paired with compatible iPhone."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"configuration-requirements","__idx":6},"children":["Configuration requirements"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The customer must have a supported payment method in their Wallet app."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The device must have Touch ID, Face ID, or passcode enabled."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["App must have proper Apple Pay entitlements configured."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-1-configure-app-entitlements","__idx":7},"children":["Step 1: Configure app entitlements"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["First, ensure your iOS app has the proper Apple Pay entitlements configured."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"entitlementsplist","__idx":8},"children":["Entitlements.plist"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"xml","header":{"controls":{"copy":{}}},"source":"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n    <key>com.apple.developer.in-app-payments</key>\n    <array>\n        <string>merchant.com.yourcompany.yourapp</string>\n    </array>\n</dict>\n</plist>\n","lang":"xml"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"infoplist-privacy-descriptions","__idx":9},"children":["Info.plist privacy descriptions"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"xml","header":{"controls":{"copy":{}}},"source":"<key>NSFaceIDUsageDescription</key>\n<string>Use Face ID to authenticate Apple Pay transactions</string>\n<key>NSContactsUsageDescription</key>\n<string>Access contacts for shipping and billing information</string>\n","lang":"xml"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-2-initialise-the-ios-sdk","__idx":10},"children":["Step 2: Initialise the iOS SDK"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Import the PXP Checkout SDK and initialise it with Apple Pay support."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"import UIKit\nimport PXPCheckoutSDK\n\nclass CheckoutViewController: UIViewController {\n    \n    private var checkout: PxpCheckout?\n    private var applePayComponent: ApplePayButtonComponent?\n    \n    override func viewDidLoad() {\n        super.viewDidLoad()\n        initializeSDK()\n    }\n    \n    private func initializeSDK() {\n        let checkoutConfig = CheckoutConfig(\n            environment: .test, // or .live for production\n            session: SessionConfig(\n                sessionId: \"your-session-id\",\n                allowedFundingTypes: AllowedFundingTypes(\n                    wallets: WalletFundingTypes(\n                        applePay: ApplePayFundingType(\n                            merchantId: \"merchant.com.yourcompany.yourapp\"\n                        )\n                    )\n                )\n            ),\n            ownerId: \"your-owner-id\",\n            ownerType: .merchant,\n            merchantShopperId: \"shopper-\\(Int(Date().timeIntervalSince1970))\",\n            kountDisabled: false, // OPTIONAL: Set to true to disable Kount fraud detection\n            transactionData: TransactionData(\n                amount: 25.00,\n                currency: \"USD\",\n                entryType: .mobileApp,\n                intent: .capture,\n                merchantTransactionId: \"txn-\\(Int(Date().timeIntervalSince1970))\",\n                merchantTransactionDate: Date(),\n                shopper: ShopperData(\n                    email: \"customer@example.com\"\n                )\n            )\n        )\n        \n        do {\n            checkout = try PxpCheckout.initialize(config: checkoutConfig)\n            print(\"PXP Checkout SDK initialised successfully\")\n        } catch {\n            print(\"Failed to initialise PXP Checkout SDK: \\(error)\")\n        }\n    }\n}\n","lang":"swift"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"configuration-parameters","__idx":11},"children":["Configuration parameters"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Property"},"children":["Property"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["environment"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["Environment"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The environment type.",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},"Possible values:",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".test"]},": For sandbox"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".live"]},": For production"]}]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["session"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["SessionConfig"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Details about the checkout session."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["session.sessionId"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["String"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The unique session identifier."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["session.allowedFundingTypes.wallets.applePay.merchantId"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["String"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Your Apple Pay merchant identifier."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ownerId"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["String"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The identifier of the owner related to the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ownerType"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ownerType"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["OwnerType"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The type of owner.",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},"Possible values:",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".merchantGroup"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".merchant"]}," ",{"$$mdtype":"Tag","name":"ComingSoon","attributes":{"noSpace":false},"children":[]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".site"]}," ",{"$$mdtype":"Tag","name":"ComingSoon","attributes":{"noSpace":false},"children":[]}]}]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchantShopperId"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["String"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A unique identifier for this shopper."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionData"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["TransactionData"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Details about the transaction."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionData.currency"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["String"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The currency code, in ISO 4217 format."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionData.amount"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["Double"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The transaction amount."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionData.entryType"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["EntryType"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The entry type.",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},"Possible values:",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".mobileApp"]},": Mobile app transactions"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".ecom"]},": E-commerce transactions"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".moto"]},": Mail order/telephone order"]}]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionData.intent"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["Intent"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The transaction intent.",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},"Possible values:",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".create"]},": Create payment method"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".confirm"]},": Confirm payment"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".capture"]},": Capture authorised payment"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".void"]},": Void authorised payment"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".refund"]},": Refund captured payment"]}]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionData.merchantTransactionId"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["String"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A unique identifier for this transaction."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionData.merchantTransactionDate"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["Date"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The date and time of the transaction."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["transactionData.shopper.email"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["String"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The shopper's email address."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["kountDisabled"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["Bool"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Whether to disable the Kount fraud detection service. Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]}," (fraud detection enabled)."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-3-create-the-component-configuration","__idx":12},"children":["Step 3: Create the component configuration"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Next, create the Apple Pay component configuration with your specific requirements."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"private func createApplePayConfiguration() -> ApplePayButtonComponentConfig {\n    let config = ApplePayButtonComponentConfig()\n    \n    // Basic configuration\n    config.merchantDisplayName = \"Your Store\"\n    config.paymentDescription = \"Purchase from Your Store\"\n    config.currencyCode = \"USD\"\n    config.countryCode = \"US\"\n    config.supportedNetworks = [.visa, .masterCard, .amex]\n    config.merchantCapabilities = [.threeDSecure, .emv]\n    \n    // Button styling\n    config.buttonType = .buy\n    config.buttonStyle = .black\n    config.buttonRadius = 8.0\n    \n    // Payment items\n    config.totalPaymentItem = ApplePayPaymentSummaryItem(\n        amount: 25.00,\n        label: \"Total\",\n        type: .final\n    )\n    \n    config.paymentItems = [\n        ApplePayPaymentSummaryItem(amount: 20.00, label: \"Product\", type: .final),\n        ApplePayPaymentSummaryItem(amount: 3.00, label: \"Tax\", type: .final),\n        ApplePayPaymentSummaryItem(amount: 2.00, label: \"Shipping\", type: .final)\n    ]\n    \n    // Contact fields\n    config.requiredBillingContactFields = [.postalAddress, .name, .emailAddress]\n    config.requiredShippingContactFields = [.postalAddress, .name, .phoneNumber]\n    \n    // Shipping methods\n    config.shippingMethods = [\n        ApplePayShippingMethod(\n            amount: 2.00,\n            detail: \"5-7 business days\",\n            identifier: \"standard\",\n            label: \"Standard Shipping\"\n        ),\n        ApplePayShippingMethod(\n            amount: 5.00,\n            detail: \"2-3 business days\",\n            identifier: \"express\",\n            label: \"Express Shipping\"\n        )\n    ]\n    \n    // Event handlers\n    config.onPreAuthorisation = { [weak self] in\n        return await self?.handlePreAuthorisation()\n    }\n    \n    config.onPostAuthorisation = { [weak self] result in\n        self?.handlePostAuthorisation(result)\n    }\n    \n    config.onError = { [weak self] error in\n        self?.handleError(error)\n    }\n    \n    config.onCancel = { [weak self] error in\n        self?.handleCancellation(error)\n    }\n    \n    return config\n}\n","lang":"swift"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"configuration-parameters-1","__idx":13},"children":["Configuration parameters"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Parameter"},"children":["Parameter"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchantDisplayName"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["String (≤ 64 characters)"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The name of your store as it appears to customers during payment."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentDescription"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["String (≤ 128 characters)"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A description of the payment that appears to customers."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["currencyCode"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["String"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The currency code in ISO 4217 format (e.g., \"USD\")."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["countryCode"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["String"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The merchant's country code in ISO 3166-1 alpha-2 format (e.g., \"US\")."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["supportedNetworks"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["[PaymentNetwork]"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Supported card networks.",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},"Possible values:",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".visa"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".masterCard"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".amex"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".discover"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".jcb"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".unionPay"]}]}]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchantCapabilities"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["[MerchantCapability]"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Payment processing capabilities.",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},"Possible values:",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".threeDSecure"]},": 3D Secure support"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".emv"]},": EMV support"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".credit"]},": Credit card support"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".debit"]},": Debit card support"]}]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["buttonType"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["ApplePaymentButtonType"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The button type.",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},"Possible values:",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".plain"]},": Apple Pay logo only"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".buy"]},": Purchase button"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".pay"]},": Payment button"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".donate"]},": Donation button"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".checkout"]},": Checkout button"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".book"]},": Booking button"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".subscribe"]},": Subscription button"]}]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["buttonStyle"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["ApplePaymentButtonStyle"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The button style.",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},"Possible values:",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".black"]},": Black background with white text"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".white"]},": White background with black text"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".whiteOutline"]},": White background with black border"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".automatic"]},": Adapts to system appearance (iOS 13+)"]}]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["buttonRadius"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["CGFloat"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The button corner radius (default: 4.0)."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["totalPaymentItem"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["ApplePayPaymentSummaryItem"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The total payment amount display."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paymentItems"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["[ApplePayPaymentSummaryItem]"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Individual line items for the payment."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["requiredBillingContactFields"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["[ContactField]"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Required billing contact fields.",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},"Possible values:",{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".postalAddress"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".name"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".emailAddress"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".phoneNumber"]}]}]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["requiredShippingContactFields"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["[ContactField]"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Required shipping contact fields."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["shippingMethods"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["[ApplePayShippingMethod]"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Available shipping methods."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-4-setup-the-view-layout","__idx":14},"children":["Step 4: Setup the view layout"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create your view layout to include the Apple Pay button container."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"using-storyboard","__idx":15},"children":["Using Storyboard"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"@IBOutlet weak var paymentSummaryView: UIView!\n@IBOutlet weak var applePayContainer: UIView!\n@IBOutlet weak var errorMessageLabel: UILabel!\n@IBOutlet weak var successMessageLabel: UILabel!\n\noverride func viewDidLoad() {\n    super.viewDidLoad()\n    setupUI()\n    initializeSDK()\n}\n\nprivate func setupUI() {\n    // Configure payment summary\n    setupPaymentSummary()\n    \n    // Configure Apple Pay container\n    applePayContainer.layer.cornerRadius = 8\n    applePayContainer.backgroundColor = .systemBackground\n    \n    // Hide message labels initially\n    errorMessageLabel.isHidden = true\n    successMessageLabel.isHidden = true\n}\n\nprivate func setupPaymentSummary() {\n    // Create payment summary views\n    let stackView = UIStackView()\n    stackView.axis = .vertical\n    stackView.spacing = 8\n    stackView.translatesAutoresizingMaskIntoConstraints = false\n    \n    // Add line items\n    stackView.addArrangedSubview(createLineItem(label: \"Premium T-Shirt\", amount: \"$20.00\"))\n    stackView.addArrangedSubview(createLineItem(label: \"Sales Tax\", amount: \"$3.00\"))\n    stackView.addArrangedSubview(createLineItem(label: \"Shipping\", amount: \"$2.00\"))\n    \n    // Add separator\n    let separator = UIView()\n    separator.backgroundColor = .separator\n    separator.heightAnchor.constraint(equalToConstant: 1).isActive = true\n    stackView.addArrangedSubview(separator)\n    \n    // Add total\n    let totalView = createLineItem(label: \"Total\", amount: \"$25.00\", isTotal: true)\n    stackView.addArrangedSubview(totalView)\n    \n    paymentSummaryView.addSubview(stackView)\n    \n    NSLayoutConstraint.activate([\n        stackView.topAnchor.constraint(equalTo: paymentSummaryView.topAnchor, constant: 16),\n        stackView.leadingAnchor.constraint(equalTo: paymentSummaryView.leadingAnchor, constant: 16),\n        stackView.trailingAnchor.constraint(equalTo: paymentSummaryView.trailingAnchor, constant: -16),\n        stackView.bottomAnchor.constraint(equalTo: paymentSummaryView.bottomAnchor, constant: -16)\n    ])\n}\n\nprivate func createLineItem(label: String, amount: String, isTotal: Bool = false) -> UIView {\n    let containerView = UIView()\n    \n    let labelView = UILabel()\n    labelView.text = label\n    labelView.font = isTotal ? .systemFont(ofSize: 18, weight: .semibold) : .systemFont(ofSize: 16)\n    labelView.translatesAutoresizingMaskIntoConstraints = false\n    \n    let amountLabel = UILabel()\n    amountLabel.text = amount\n    amountLabel.font = isTotal ? .systemFont(ofSize: 18, weight: .semibold) : .systemFont(ofSize: 16)\n    amountLabel.textAlignment = .right\n    amountLabel.translatesAutoresizingMaskIntoConstraints = false\n    \n    containerView.addSubview(labelView)\n    containerView.addSubview(amountLabel)\n    \n    NSLayoutConstraint.activate([\n        labelView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),\n        labelView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor),\n        labelView.topAnchor.constraint(equalTo: containerView.topAnchor),\n        labelView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),\n        \n        amountLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),\n        amountLabel.centerYAnchor.constraint(equalTo: containerView.centerYAnchor),\n        amountLabel.leadingAnchor.constraint(greaterThanOrEqualTo: labelView.trailingAnchor, constant: 8)\n    ])\n    \n    return containerView\n}\n","lang":"swift"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"using-swiftui","__idx":16},"children":["Using SwiftUI"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"import SwiftUI\nimport PXPCheckoutSDK\n\nstruct CheckoutView: View {\n    @State private var applePayComponent: ApplePayButtonComponent?\n    @State private var checkout: PxpCheckout?\n    @State private var errorMessage: String = \"\"\n    @State private var successMessage: String = \"\"\n    @State private var showingError = false\n    @State private var showingSuccess = false\n    \n    var body: some View {\n        VStack(spacing: 20) {\n            Text(\"Complete your purchase\")\n                .font(.largeTitle)\n                .fontWeight(.bold)\n            \n            // Payment summary\n            VStack(spacing: 12) {\n                HStack {\n                    Text(\"Premium T-Shirt\")\n                    Spacer()\n                    Text(\"$20.00\")\n                }\n                \n                HStack {\n                    Text(\"Sales Tax\")\n                    Spacer()\n                    Text(\"$3.00\")\n                }\n                \n                HStack {\n                    Text(\"Shipping\")\n                    Spacer()\n                    Text(\"$2.00\")\n                }\n                \n                Divider()\n                \n                HStack {\n                    Text(\"Total\")\n                        .fontWeight(.semibold)\n                    Spacer()\n                    Text(\"$25.00\")\n                        .fontWeight(.semibold)\n                }\n                .font(.title3)\n            }\n            .padding()\n            .background(Color(.systemGray6))\n            .cornerRadius(12)\n            \n            // Error/Success Messages\n            if showingError {\n                Text(errorMessage)\n                    .foregroundColor(.red)\n                    .padding()\n                    .background(Color.red.opacity(0.1))\n                    .cornerRadius(8)\n            }\n            \n            if showingSuccess {\n                Text(successMessage)\n                    .foregroundColor(.green)\n                    .padding()\n                    .background(Color.green.opacity(0.1))\n                    .cornerRadius(8)\n            }\n            \n            // Apple Pay button container\n            ApplePayButtonView(\n                onComponentCreated: { component in\n                    self.applePayComponent = component\n                }\n            )\n            .frame(height: 50)\n            .cornerRadius(8)\n            \n            Text(\"Or pay with credit card\")\n                .foregroundColor(.secondary)\n                .font(.caption)\n            \n            Spacer()\n        }\n        .padding()\n        .onAppear {\n            initializeSDK()\n        }\n    }\n    \n    private func initializeSDK() {\n        // Initialise SDK (same as UIKit example)\n    }\n}\n","lang":"swift"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-5-create-and-mount-the-component","__idx":17},"children":["Step 5: Create and mount the component"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create the Apple Pay component and add it to your view."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"private func createAndMountApplePayComponent() {\n    guard let checkout = checkout else {\n        print(\"Checkout SDK not initialized\")\n        return\n    }\n    \n    do {\n        let config = createApplePayConfiguration()\n        applePayComponent = try checkout.create(.applePayButton, componentConfig: config)\n        \n        if let componentView = applePayComponent?.render() {\n            mountComponent(componentView)\n        }\n        \n        print(\"Apple Pay component created and mounted successfully\")\n        \n    } catch {\n        print(\"Failed to create Apple Pay component: \\(error)\")\n        showError(\"Apple Pay is not available on this device\")\n    }\n}\n\nprivate func mountComponent(_ componentView: UIView) {\n    // Clear any existing subviews\n    applePayContainer.subviews.forEach { $0.removeFromSuperview() }\n    \n    // Add the component view\n    applePayContainer.addSubview(componentView)\n    componentView.translatesAutoresizingMaskIntoConstraints = false\n    \n    NSLayoutConstraint.activate([\n        componentView.topAnchor.constraint(equalTo: applePayContainer.topAnchor),\n        componentView.leadingAnchor.constraint(equalTo: applePayContainer.leadingAnchor),\n        componentView.trailingAnchor.constraint(equalTo: applePayContainer.trailingAnchor),\n        componentView.bottomAnchor.constraint(equalTo: applePayContainer.bottomAnchor)\n    ])\n}\n","lang":"swift"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"swiftui-component-wrapper","__idx":18},"children":["SwiftUI component wrapper"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"struct ApplePayButtonView: UIViewRepresentable {\n    let onComponentCreated: (ApplePayButtonComponent) -> Void\n    \n    func makeUIView(context: Context) -> UIView {\n        let containerView = UIView()\n        \n        // Create checkout and component\n        let checkoutConfig = CheckoutConfig(\n            environment: .test,\n            session: SessionConfig(sessionId: \"your-session-id\"),\n            // ... other configuration\n        )\n        \n        do {\n            let checkout = try PxpCheckout.initialize(config: checkoutConfig)\n            let config = createApplePayConfiguration()\n            let component = try checkout.create(.applePayButton, componentConfig: config)\n            \n            if let componentView = component.render() {\n                containerView.addSubview(componentView)\n                componentView.translatesAutoresizingMaskIntoConstraints = false\n                \n                NSLayoutConstraint.activate([\n                    componentView.topAnchor.constraint(equalTo: containerView.topAnchor),\n                    componentView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),\n                    componentView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),\n                    componentView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor)\n                ])\n            }\n            \n            onComponentCreated(component)\n        } catch {\n            print(\"Failed to create Apple Pay component: \\(error)\")\n        }\n        \n        return containerView\n    }\n    \n    func updateUIView(_ uiView: UIView, context: Context) {\n        // Updates handled by the component\n    }\n    \n    private func createApplePayConfiguration() -> ApplePayButtonComponentConfig {\n        // Same configuration as previous examples\n    }\n}\n","lang":"swift"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-6-handle-payment-results","__idx":19},"children":["Step 6: Handle payment results"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Implement the event handlers to process payment results and user interactions."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"// MARK: - Event Handlers\n\nprivate func handlePreAuthorisation() async -> ApplePayTransactionInitData? {\n    print(\"Pre-authorisation started\")\n    \n    DispatchQueue.main.async {\n        self.showMessage(\"Processing payment...\", type: .info)\n    }\n    \n    return ApplePayTransactionInitData(\n        riskScreeningData: RiskScreeningData(\n            performRiskScreening: true,\n            deviceSessionId: generateDeviceSessionId(),\n            userIp: \"192.168.1.100\",\n            account: RiskScreeningAccount(\n                id: \"user_12345678\",\n                creationDateTime: \"2024-01-15T10:30:00.000Z\"\n            ),\n            items: [\n                RiskScreeningItem(  // NOT Item\n                    price: 99.99,\n                    quantity: 1,\n                    category: \"Electronics\",\n                    sku: \"PROD-001\"\n                )\n            ],\n            fulfillments: [\n                RiskScreeningFulfillment(  // NOT Fulfillment\n                    type: .shipped,  // enum case, not string\n                    shipping: RiskScreeningShipping(\n                        shippingMethod: .express  // or .standard, .nextDay, etc.\n                    ),\n                    recipientPerson: RiskScreeningRecipientPerson(\n                        phoneNumber: \"+1234567890\"\n                    )\n                )\n            ],\n            transaction: RiskScreeningTransaction(\n                subtotal: 99.99\n            )\n        )\n    )\n}\n\nprivate func handlePostAuthorisation(_ result: BaseSubmitResult) {\n    DispatchQueue.main.async {\n        if let authorizedResult = result as? AuthorisedSubmitResult {\n            self.showMessage(\"Payment successful! Redirecting...\", type: .success)\n            print(\"Transaction ID: \\(authorizedResult.provider.code)\")\n            \n            // Navigate to success screen after delay\n            DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {\n                self.navigateToSuccessScreen(transactionId: authorizedResult.provider.code)\n            }\n            \n        } else if let declinedResult = result as? DeclinedSubmitResult {\n            self.showMessage(\"Payment was declined: \\(declinedResult.errorReason)\", type: .error)\n            \n        } else if let failedResult = result as? FailedSubmitResult {\n            self.showMessage(\"Payment failed: \\(failedResult.errorReason)\", type: .error)\n        }\n    }\n}\n\nprivate func handleError(_ error: Error) {\n    print(\"Apple Pay error: \\(error)\")\n    \n    DispatchQueue.main.async {\n        if let pkError = error as? PKPaymentError {\n            self.handlePKPaymentError(pkError)\n        } else if let validationError = error as? ApplePayValidationException {\n            self.showMessage(\"Validation error: \\(validationError.localizedDescription)\", type: .error)\n        } else {\n            self.showMessage(\"Payment error: \\(error.localizedDescription)\", type: .error)\n        }\n    }\n}\n\nprivate func handlePKPaymentError(_ error: PKPaymentError) {\n    switch error.code {\n    case .paymentNotAllowed:\n        showMessage(\"Payment not allowed. Please check your settings.\", type: .error)\n    case .paymentNetworkNotSupported:\n        showMessage(\"Card network not supported. Please use a different card.\", type: .error)\n    case .deviceCannotMakePayments:\n        showMessage(\"Apple Pay is not available on this device.\", type: .error)\n    default:\n        showMessage(\"Payment error occurred. Please try again.\", type: .error)\n    }\n}\n\nprivate func handleCancellation(_ error: Error?) {\n    print(\"Payment cancelled by user\")\n    DispatchQueue.main.async {\n        self.showMessage(\"Payment was cancelled\", type: .info)\n    }\n}\n\n// MARK: - Helper methods\n\nprivate func getDeviceSessionId() async -> String {\n    return UIDevice.current.identifierForVendor?.uuidString ?? \"unknown-device\"\n}\n\nprivate func showMessage(_ message: String, type: MessageType) {\n    errorMessageLabel.isHidden = true\n    successMessageLabel.isHidden = true\n    \n    switch type {\n    case .error:\n        errorMessageLabel.text = message\n        errorMessageLabel.isHidden = false\n    case .success:\n        successMessageLabel.text = message\n        successMessageLabel.isHidden = false\n    case .info:\n        successMessageLabel.text = message\n        successMessageLabel.textColor = .systemBlue\n        successMessageLabel.isHidden = false\n    }\n}\n\nprivate func navigateToSuccessScreen(transactionId: String) {\n    let storyboard = UIStoryboard(name: \"Main\", bundle: nil)\n    if let successVC = storyboard.instantiateViewController(withIdentifier: \"SuccessViewController\") as? SuccessViewController {\n        successVC.transactionId = transactionId\n        navigationController?.pushViewController(successVC, animated: true)\n    }\n}\n\nenum MessageType {\n    case error, success, info\n}\n","lang":"swift"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-7-add-advanced-event-handling","__idx":20},"children":["Step 7: Add advanced event handling"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Implement shipping and payment method selection handlers."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"private func setupAdvancedEventHandlers() {\n    guard let config = applePayComponent?.config else { return }\n    \n    // Shipping contact selection\n    config.onShippingContactSelected = { [weak self] contact in\n        guard let self = self else { return PKPaymentRequestShippingContactUpdate(errors: []) }\n        \n        print(\"Shipping contact selected: \\(contact)\")\n        \n        // Calculate shipping and tax based on address\n        let shippingCost = self.calculateShippingCost(for: contact.postalAddress)\n        let tax = self.calculateTax(for: contact.postalAddress)\n        let newTotal = 20.00 + shippingCost + tax\n        \n        return PKPaymentRequestShippingContactUpdate(\n            errors: [],\n            shippingMethods: [\n                PKShippingMethod(\n                    label: \"Standard Shipping\",\n                    amount: NSDecimalNumber(value: shippingCost),\n                    type: .final,\n                    identifier: \"standard\",\n                    detail: \"5-7 business days\"\n                )\n            ],\n            paymentSummaryItems: [\n                PKPaymentSummaryItem(label: \"Premium T-Shirt\", amount: NSDecimalNumber(value: 20.00)),\n                PKPaymentSummaryItem(label: \"Sales Tax\", amount: NSDecimalNumber(value: tax)),\n                PKPaymentSummaryItem(label: \"Shipping\", amount: NSDecimalNumber(value: shippingCost)),\n                PKPaymentSummaryItem(label: \"Your Store Name\", amount: NSDecimalNumber(value: newTotal))\n            ]\n        )\n    }\n    \n    // Shipping method selection\n    config.onShippingMethodSelected = { [weak self] method in\n        guard let self = self else { return PKPaymentRequestShippingMethodUpdate(paymentSummaryItems: []) }\n        \n        print(\"Shipping method selected: \\(method)\")\n        \n        let baseAmount = 20.00\n        let tax = 3.00\n        let shippingCost = method.amount.doubleValue\n        let newTotal = baseAmount + tax + shippingCost\n        \n        return PKPaymentRequestShippingMethodUpdate(\n            paymentSummaryItems: [\n                PKPaymentSummaryItem(label: \"Premium T-Shirt\", amount: NSDecimalNumber(value: baseAmount)),\n                PKPaymentSummaryItem(label: \"Sales Tax\", amount: NSDecimalNumber(value: tax)),\n                PKPaymentSummaryItem(label: \"Shipping\", amount: method.amount),\n                PKPaymentSummaryItem(label: \"Your Store Name\", amount: NSDecimalNumber(value: newTotal))\n            ]\n        )\n    }\n    \n    // Payment method selection (iOS 15.0+)\n    if #available(iOS 15.0, *) {\n        config.onPaymentMethodSelected = { paymentMethod in\n            print(\"Payment method selected: \\(paymentMethod)\")\n            \n            return PKPaymentRequestPaymentMethodUpdate(\n                paymentSummaryItems: [\n                    PKPaymentSummaryItem(label: \"Premium T-Shirt\", amount: NSDecimalNumber(value: 20.00)),\n                    PKPaymentSummaryItem(label: \"Sales Tax\", amount: NSDecimalNumber(value: 3.00)),\n                    PKPaymentSummaryItem(label: \"Shipping\", amount: NSDecimalNumber(value: 2.00)),\n                    PKPaymentSummaryItem(label: \"Your Store Name\", amount: NSDecimalNumber(value: 25.00))\n                ]\n            )\n        }\n        \n        // Coupon code handling\n        config.onCouponCodeChanged = { [weak self] couponCode in\n            guard let self = self else { return PKPaymentRequestCouponCodeUpdate(paymentSummaryItems: []) }\n            \n            print(\"Coupon code changed: \\(couponCode)\")\n            \n            let discount = self.calculateDiscount(for: couponCode)\n            let newTotal = 25.00 - discount\n            \n            return PKPaymentRequestCouponCodeUpdate(\n                errors: discount > 0 ? [] : [PKPaymentError(.couponCodeInvalid)],\n                paymentSummaryItems: [\n                    PKPaymentSummaryItem(label: \"Premium T-Shirt\", amount: NSDecimalNumber(value: 20.00)),\n                    PKPaymentSummaryItem(label: \"Sales Tax\", amount: NSDecimalNumber(value: 3.00)),\n                    PKPaymentSummaryItem(label: \"Shipping\", amount: NSDecimalNumber(value: 2.00)),\n                    PKPaymentSummaryItem(label: \"Discount\", amount: NSDecimalNumber(value: -discount)),\n                    PKPaymentSummaryItem(label: \"Your Store Name\", amount: NSDecimalNumber(value: newTotal))\n                ]\n            )\n        }\n    }\n}\n\n// MARK: - Calculation methods\n\nprivate func calculateShippingCost(for address: CNPostalAddress?) -> Double {\n    guard let address = address else { return 5.00 }\n    \n    // Simple shipping calculation based on state/country\n    if address.isoCountryCode == \"US\" {\n        return address.state == \"CA\" ? 7.99 : 4.99\n    }\n    return 15.99 // International shipping\n}\n\nprivate func calculateTax(for address: CNPostalAddress?) -> Double {\n    guard let address = address, address.isoCountryCode == \"US\" else { return 0.00 }\n    \n    let taxRates: [String: Double] = [\n        \"CA\": 0.0875, // California\n        \"NY\": 0.08,   // New York\n        \"TX\": 0.0625  // Texas\n    ]\n    \n    let rate = taxRates[address.state] ?? 0.06\n    return 20.00 * rate\n}\n\nprivate func calculateDiscount(for couponCode: String) -> Double {\n    let validCoupons: [String: Double] = [\n        \"SAVE10\": 2.50,\n        \"SAVE20\": 5.00,\n        \"WELCOME\": 3.00\n    ]\n    \n    return validCoupons[couponCode.uppercased()] ?? 0.00\n}\n","lang":"swift"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"step-8-component-lifecycle-management","__idx":21},"children":["Step 8: Component lifecycle management"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Properly manage the component lifecycle to prevent memory leaks and ensure clean transitions."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"class CheckoutViewController: UIViewController {\n    \n    // MARK: - Lifecycle\n    \n    override func viewWillDisappear(_ animated: Bool) {\n        super.viewWillDisappear(animated)\n        \n        // Clean up component if navigating away\n        if isMovingFromParent || isBeingDismissed {\n            cleanupComponent()\n        }\n    }\n    \n    deinit {\n        cleanupComponent()\n    }\n    \n    private func cleanupComponent() {\n        applePayComponent?.unmount()\n        applePayComponent = nil\n        checkout = nil\n        print(\"Apple Pay component cleaned up\")\n    }\n    \n    // MARK: - Error recovery\n    \n    private func retryComponentCreation() {\n        cleanupComponent()\n        \n        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {\n            self.initializeSDK()\n            self.createAndMountApplePayComponent()\n        }\n    }\n}\n","lang":"swift"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"whats-next","__idx":22},"children":["What's next?"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"customise-the-look-and-feel","__idx":23},"children":["Customise the look and feel"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can configure the appearance and behaviour of the Apple Pay component to fit your brand. We've documented all configurable parameters in the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/apple-pay/customisation"},"children":["Customisation"]}," page."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"// Custom button styling\nconfig.buttonType = .buy\nconfig.buttonStyle = .black\nconfig.buttonRadius = 12.0\n\n// Custom SwiftUI content\nconfig.customContent = {\n    return AnyView(\n        HStack {\n            Image(systemName: \"applelogo\")\n                .foregroundColor(.white)\n            Text(\"Buy with Apple Pay\")\n                .foregroundColor(.white)\n                .fontWeight(.semibold)\n        }\n        .frame(maxWidth: .infinity, minHeight: 50)\n        .background(\n            LinearGradient(\n                gradient: Gradient(colors: [Color.black, Color.gray]),\n                startPoint: .leading,\n                endPoint: .trailing\n            )\n        )\n        .cornerRadius(12)\n    )\n}\n","lang":"swift"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"add-more-event-handling","__idx":24},"children":["Add more event handling"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The Apple Pay component emits events based on user interaction, shipping changes, and payment method updates. For more information about all the available events, see the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/apple-pay/events"},"children":["Events"]}," page."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"add-error-handling-and-validation","__idx":25},"children":["Add error handling and validation"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Error handling is crucial for payment components because they deal with sensitive financial data and complex validation rules. For more details about error handling, see the ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/apple-pay/data-validation"},"children":["Data validation"]}," page."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"// Comprehensive error handling\nconfig.onError = { error in\n    DispatchQueue.main.async {\n        if let validationError = error as? ApplePayValidationException {\n            self.handleValidationError(validationError)\n        } else if let networkError = error as? URLError {\n            self.handleNetworkError(networkError)\n        } else {\n            self.handleGenericError(error)\n        }\n    }\n}\n\nprivate func handleValidationError(_ error: ApplePayValidationException) {\n    showMessage(\"Please check your payment information: \\(error.localizedDescription)\", type: .error)\n}\n\nprivate func handleNetworkError(_ error: URLError) {\n    showMessage(\"Connection error. Please check your internet and try again.\", type: .error)\n}\n\nprivate func handleGenericError(_ error: Error) {\n    showMessage(\"An unexpected error occurred. Please try again.\", type: .error)\n}\n","lang":"swift"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"complete-uikit-example","__idx":26},"children":["Complete UIKit example"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"import UIKit\nimport PXPCheckoutSDK\nimport PassKit\n\nclass CompleteCheckoutViewController: UIViewController {\n    \n    // MARK: - Outlets\n    @IBOutlet weak var titleLabel: UILabel!\n    @IBOutlet weak var paymentSummaryView: UIView!\n    @IBOutlet weak var applePayContainer: UIView!\n    @IBOutlet weak var errorMessageLabel: UILabel!\n    @IBOutlet weak var successMessageLabel: UILabel!\n    @IBOutlet weak var loadingIndicator: UIActivityIndicatorView!\n    \n    // MARK: - Properties\n    private var checkout: PxpCheckout?\n    private var applePayComponent: ApplePayButtonComponent?\n    \n    // MARK: - Lifecycle\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        setupUI()\n        initializeSDK()\n    }\n    \n    override func viewWillDisappear(_ animated: Bool) {\n        super.viewWillDisappear(animated)\n        if isMovingFromParent || isBeingDismissed {\n            cleanupComponent()\n        }\n    }\n    \n    deinit {\n        cleanupComponent()\n    }\n    \n    // MARK: - Setup\n    private func setupUI() {\n        titleLabel.text = \"Complete your purchase\"\n        titleLabel.font = UIFont.systemFont(ofSize: 28, weight: .bold)\n        \n        setupPaymentSummary()\n        \n        applePayContainer.layer.cornerRadius = 8\n        applePayContainer.backgroundColor = .systemBackground\n        \n        errorMessageLabel.isHidden = true\n        successMessageLabel.isHidden = true\n        loadingIndicator.isHidden = true\n        \n        view.backgroundColor = .systemBackground\n    }\n    \n    private func setupPaymentSummary() {\n        paymentSummaryView.backgroundColor = UIColor.systemGray6\n        paymentSummaryView.layer.cornerRadius = 12\n        \n        let stackView = UIStackView()\n        stackView.axis = .vertical\n        stackView.spacing = 12\n        stackView.translatesAutoresizingMaskIntoConstraints = false\n        \n        // Add line items\n        stackView.addArrangedSubview(createLineItem(label: \"Premium T-Shirt\", amount: \"$20.00\"))\n        stackView.addArrangedSubview(createLineItem(label: \"Sales Tax\", amount: \"$3.00\"))\n        stackView.addArrangedSubview(createLineItem(label: \"Shipping\", amount: \"$2.00\"))\n        \n        // Add separator\n        let separator = UIView()\n        separator.backgroundColor = .separator\n        separator.heightAnchor.constraint(equalToConstant: 1).isActive = true\n        stackView.addArrangedSubview(separator)\n        \n        // Add total\n        stackView.addArrangedSubview(createLineItem(label: \"Total\", amount: \"$25.00\", isTotal: true))\n        \n        paymentSummaryView.addSubview(stackView)\n        \n        NSLayoutConstraint.activate([\n            stackView.topAnchor.constraint(equalTo: paymentSummaryView.topAnchor, constant: 16),\n            stackView.leadingAnchor.constraint(equalTo: paymentSummaryView.leadingAnchor, constant: 16),\n            stackView.trailingAnchor.constraint(equalTo: paymentSummaryView.trailingAnchor, constant: -16),\n            stackView.bottomAnchor.constraint(equalTo: paymentSummaryView.bottomAnchor, constant: -16)\n        ])\n    }\n    \n    private func createLineItem(label: String, amount: String, isTotal: Bool = false) -> UIView {\n        let containerView = UIView()\n        \n        let labelView = UILabel()\n        labelView.text = label\n        labelView.font = isTotal ? .systemFont(ofSize: 18, weight: .semibold) : .systemFont(ofSize: 16)\n        labelView.translatesAutoresizingMaskIntoConstraints = false\n        \n        let amountLabel = UILabel()\n        amountLabel.text = amount\n        amountLabel.font = isTotal ? .systemFont(ofSize: 18, weight: .semibold) : .systemFont(ofSize: 16)\n        amountLabel.textAlignment = .right\n        amountLabel.translatesAutoresizingMaskIntoConstraints = false\n        \n        containerView.addSubview(labelView)\n        containerView.addSubview(amountLabel)\n        \n        NSLayoutConstraint.activate([\n            labelView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),\n            labelView.centerYAnchor.constraint(equalTo: containerView.centerYAnchor),\n            labelView.topAnchor.constraint(equalTo: containerView.topAnchor),\n            labelView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor),\n            \n            amountLabel.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),\n            amountLabel.centerYAnchor.constraint(equalTo: containerView.centerYAnchor),\n            amountLabel.leadingAnchor.constraint(greaterThanOrEqualTo: labelView.trailingAnchor, constant: 8)\n        ])\n        \n        return containerView\n    }\n    \n    // MARK: - SDK Initialisation\n    private func initializeSDK() {\n        let checkoutConfig = CheckoutConfig(\n            environment: .test,\n            session: SessionConfig(\n                sessionId: \"your-session-id\",\n                allowedFundingTypes: AllowedFundingTypes(\n                    wallets: WalletFundingTypes(\n                        applePay: ApplePayFundingType(\n                            merchantId: \"merchant.com.yourcompany.yourapp\"\n                        )\n                    )\n                )\n            ),\n            ownerId: \"your-owner-id\",\n            ownerType: .merchant,\n            merchantShopperId: \"shopper-\\(Int(Date().timeIntervalSince1970))\",\n            kountDisabled: false, // OPTIONAL: Set to true to disable Kount fraud detection\n            transactionData: TransactionData(\n                amount: 25.00,\n                currency: \"USD\",\n                entryType: .mobileApp,\n                intent: .capture,\n                merchantTransactionId: \"txn-\\(Int(Date().timeIntervalSince1970))\",\n                merchantTransactionDate: Date(),\n                shopper: ShopperData(\n                    email: \"customer@example.com\"\n                )\n            )\n        )\n        \n        do {\n            checkout = try PxpCheckout.initialize(config: checkoutConfig)\n            createAndMountApplePayComponent()\n        } catch {\n            print(\"Failed to initialise SDK: \\(error)\")\n            showMessage(\"Failed to initialise payment system\", type: .error)\n        }\n    }\n    \n    private func createAndMountApplePayComponent() {\n        guard let checkout = checkout else { return }\n        \n        // Check if Apple Pay is available\n        guard PKPaymentAuthorizationController.canMakePayments() else {\n            showMessage(\"Apple Pay is not available on this device\", type: .error)\n            return\n        }\n        \n        do {\n            let config = createApplePayConfiguration()\n            applePayComponent = try checkout.create(.applePayButton, componentConfig: config)\n            \n            if let componentView = applePayComponent?.render() {\n                mountComponent(componentView)\n            }\n            \n        } catch {\n            print(\"Failed to create Apple Pay component: \\(error)\")\n            showMessage(\"Apple Pay is not available\", type: .error)\n        }\n    }\n    \n    private func createApplePayConfiguration() -> ApplePayButtonComponentConfig {\n        let config = ApplePayButtonComponentConfig()\n        \n        // Basic configuration\n        config.merchantDisplayName = \"Your Store Name\"\n        config.paymentDescription = \"Premium T-Shirt Purchase\"\n        config.currencyCode = \"USD\"\n        config.countryCode = \"US\"\n        config.supportedNetworks = [.visa, .masterCard, .amex, .discover]\n        config.merchantCapabilities = [.threeDSecure, .emv, .credit, .debit]\n        \n        // Button styling\n        config.buttonType = .buy\n        config.buttonStyle = .black\n        config.buttonRadius = 8.0\n        \n        // Payment items\n        config.totalPaymentItem = ApplePayPaymentSummaryItem(\n            amount: 25.00,\n            label: \"Your Store Name\",\n            type: .final\n        )\n        \n        config.paymentItems = [\n            ApplePayPaymentSummaryItem(amount: 20.00, label: \"Premium T-Shirt\", type: .final),\n            ApplePayPaymentSummaryItem(amount: 3.00, label: \"Sales Tax\", type: .final),\n            ApplePayPaymentSummaryItem(amount: 2.00, label: \"Shipping\", type: .final)\n        ]\n        \n        // Contact fields\n        config.requiredBillingContactFields = [.postalAddress, .name, .emailAddress]\n        config.requiredShippingContactFields = [.postalAddress, .name, .phoneNumber]\n        \n        // Shipping methods\n        config.shippingMethods = [\n            ApplePayShippingMethod(\n                amount: 2.00,\n                detail: \"5-7 business days\",\n                identifier: \"standard\",\n                label: \"Standard Shipping\"\n            ),\n            ApplePayShippingMethod(\n                amount: 5.00,\n                detail: \"2-3 business days\", \n                identifier: \"express\",\n                label: \"Express Shipping\"\n            )\n        ]\n        \n        // Event handlers\n        config.onPreAuthorisation = { [weak self] in\n            return await self?.handlePreAuthorisation()\n        }\n        \n        config.onPostAuthorisation = { [weak self] result in\n            self?.handlePostAuthorisation(result)\n        }\n        \n        config.onShippingContactSelected = { [weak self] contact in\n            return self?.handleShippingContactSelected(contact) ?? PKPaymentRequestShippingContactUpdate(errors: [])\n        }\n        \n        config.onShippingMethodSelected = { [weak self] method in\n            return self?.handleShippingMethodSelected(method) ?? PKPaymentRequestShippingMethodUpdate(paymentSummaryItems: [])\n        }\n        \n        config.onError = { [weak self] error in\n            self?.handleError(error)\n        }\n        \n        config.onCancel = { [weak self] error in\n            self?.handleCancellation(error)\n        }\n        \n        return config\n    }\n    \n    private func mountComponent(_ componentView: UIView) {\n        applePayContainer.subviews.forEach { $0.removeFromSuperview() }\n        applePayContainer.addSubview(componentView)\n        componentView.translatesAutoresizingMaskIntoConstraints = false\n        \n        NSLayoutConstraint.activate([\n            componentView.topAnchor.constraint(equalTo: applePayContainer.topAnchor),\n            componentView.leadingAnchor.constraint(equalTo: applePayContainer.leadingAnchor),\n            componentView.trailingAnchor.constraint(equalTo: applePayContainer.trailingAnchor),\n            componentView.bottomAnchor.constraint(equalTo: applePayContainer.bottomAnchor),\n            componentView.heightAnchor.constraint(equalToConstant: 50)\n        ])\n    }\n    \n    // MARK: - Event Handlers\n    private func handlePreAuthorisation() async -> ApplePayTransactionInitData? {\n        DispatchQueue.main.async {\n            self.showMessage(\"Processing payment...\", type: .info)\n            self.loadingIndicator.startAnimating()\n            self.loadingIndicator.isHidden = false\n        }\n        \n        return ApplePayTransactionInitData(\n            riskScreeningData: RiskScreeningData(\n                performRiskScreening: true,\n                deviceSessionId: generateDeviceSessionId(),\n                userIp: \"192.168.1.100\",\n                account: RiskScreeningAccount(\n                    id: \"user_12345678\",\n                    creationDateTime: \"2024-01-15T10:30:00.000Z\"\n                ),\n                fulfillments: [\n                    RiskScreeningFulfillment(\n                        type: .shipped,\n                        recipientPerson: RiskScreeningRecipientPerson(\n                            phoneNumber: \"+1234567890\"\n                        )\n                    )\n                ]\n            )\n        )\n    }\n    \n    private func handlePostAuthorisation(_ result: BaseSubmitResult) {\n        DispatchQueue.main.async {\n            self.loadingIndicator.stopAnimating()\n            self.loadingIndicator.isHidden = true\n            \n            if let authorizedResult = result as? AuthorisedSubmitResult {\n                self.showMessage(\"Payment successful! Redirecting...\", type: .success)\n                print(\"Transaction ID: \\(authorizedResult.provider.code)\")\n                \n                DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {\n                    self.navigateToSuccessScreen(transactionId: authorizedResult.provider.code)\n                }\n                \n            } else if let declinedResult = result as? DeclinedSubmitResult {\n                self.showMessage(\"Payment declined: \\(declinedResult.errorReason)\", type: .error)\n                \n            } else if let failedResult = result as? FailedSubmitResult {\n                self.showMessage(\"Payment failed: \\(failedResult.errorReason)\", type: .error)\n            }\n        }\n    }\n    \n    private func handleShippingContactSelected(_ contact: PKContact) -> PKPaymentRequestShippingContactUpdate {\n        let shippingCost = calculateShippingCost(for: contact.postalAddress)\n        let tax = calculateTax(for: contact.postalAddress)\n        let newTotal = 20.00 + shippingCost + tax\n        \n        return PKPaymentRequestShippingContactUpdate(\n            errors: [],\n            shippingMethods: [\n                PKShippingMethod(\n                    label: \"Standard Shipping\",\n                    amount: NSDecimalNumber(value: shippingCost),\n                    type: .final,\n                    identifier: \"standard\",\n                    detail: \"5-7 business days\"\n                )\n            ],\n            paymentSummaryItems: [\n                PKPaymentSummaryItem(label: \"Premium T-Shirt\", amount: NSDecimalNumber(value: 20.00)),\n                PKPaymentSummaryItem(label: \"Sales Tax\", amount: NSDecimalNumber(value: tax)),\n                PKPaymentSummaryItem(label: \"Shipping\", amount: NSDecimalNumber(value: shippingCost)),\n                PKPaymentSummaryItem(label: \"Your Store Name\", amount: NSDecimalNumber(value: newTotal))\n            ]\n        )\n    }\n    \n    private func handleShippingMethodSelected(_ method: PKShippingMethod) -> PKPaymentRequestShippingMethodUpdate {\n        let baseAmount = 20.00\n        let tax = 3.00\n        let shippingCost = method.amount.doubleValue\n        let newTotal = baseAmount + tax + shippingCost\n        \n        return PKPaymentRequestShippingMethodUpdate(\n            paymentSummaryItems: [\n                PKPaymentSummaryItem(label: \"Premium T-Shirt\", amount: NSDecimalNumber(value: baseAmount)),\n                PKPaymentSummaryItem(label: \"Sales Tax\", amount: NSDecimalNumber(value: tax)),\n                PKPaymentSummaryItem(label: \"Shipping\", amount: method.amount),\n                PKPaymentSummaryItem(label: \"Your Store Name\", amount: NSDecimalNumber(value: newTotal))\n            ]\n        )\n    }\n    \n    private func handleError(_ error: Error) {\n        DispatchQueue.main.async {\n            self.loadingIndicator.stopAnimating()\n            self.loadingIndicator.isHidden = true\n            \n            if let pkError = error as? PKPaymentError {\n                self.handlePKPaymentError(pkError)\n            } else if let validationError = error as? ApplePayValidationException {\n                self.showMessage(\"Validation error: \\(validationError.localizedDescription)\", type: .error)\n            } else {\n                self.showMessage(\"Payment error: \\(error.localizedDescription)\", type: .error)\n            }\n        }\n    }\n    \n    private func handlePKPaymentError(_ error: PKPaymentError) {\n        switch error.code {\n        case .paymentNotAllowed:\n            showMessage(\"Payment not allowed. Please check your settings.\", type: .error)\n        case .paymentNetworkNotSupported:\n            showMessage(\"Card not supported. Please use a different card.\", type: .error)\n        case .deviceCannotMakePayments:\n            showMessage(\"Apple Pay is not available on this device.\", type: .error)\n        default:\n            showMessage(\"Payment error occurred. Please try again.\", type: .error)\n        }\n    }\n    \n    private func handleCancellation(_ error: Error?) {\n        DispatchQueue.main.async {\n            self.loadingIndicator.stopAnimating()\n            self.loadingIndicator.isHidden = true\n            self.showMessage(\"Payment was cancelled\", type: .info)\n        }\n    }\n    \n    // MARK: - Helper Methods\n    private func showMessage(_ message: String, type: MessageType) {\n        errorMessageLabel.isHidden = true\n        successMessageLabel.isHidden = true\n        \n        switch type {\n        case .error:\n            errorMessageLabel.text = message\n            errorMessageLabel.isHidden = false\n        case .success:\n            successMessageLabel.text = message\n            successMessageLabel.textColor = .systemGreen\n            successMessageLabel.isHidden = false\n        case .info:\n            successMessageLabel.text = message\n            successMessageLabel.textColor = .systemBlue\n            successMessageLabel.isHidden = false\n        }\n    }\n    \n    private func calculateShippingCost(for address: CNPostalAddress?) -> Double {\n        guard let address = address else { return 5.00 }\n        return address.isoCountryCode == \"US\" ? (address.state == \"CA\" ? 7.99 : 4.99) : 15.99\n    }\n    \n    private func calculateTax(for address: CNPostalAddress?) -> Double {\n        guard let address = address, address.isoCountryCode == \"US\" else { return 0.00 }\n        \n        let taxRates: [String: Double] = [\"CA\": 0.0875, \"NY\": 0.08, \"TX\": 0.0625]\n        let rate = taxRates[address.state] ?? 0.06\n        return 20.00 * rate\n    }\n    \n    private func navigateToSuccessScreen(transactionId: String) {\n        let alert = UIAlertController(\n            title: \"Payment Successful\",\n            message: \"Transaction ID: \\(transactionId)\",\n            preferredStyle: .alert\n        )\n        alert.addAction(UIAlertAction(title: \"OK\", style: .default) { _ in\n            self.navigationController?.popViewController(animated: true)\n        })\n        present(alert, animated: true)\n    }\n    \n    private func cleanupComponent() {\n        applePayComponent?.unmount()\n        applePayComponent = nil\n        checkout = nil\n    }\n    \n    enum MessageType {\n        case error, success, info\n    }\n}\n","lang":"swift"},"children":[]}]},"headings":[{"value":"Implementation","id":"implementation","depth":1},{"value":"Overview","id":"overview","depth":2},{"value":"Before you start","id":"before-you-start","depth":2},{"value":"Device and OS compatibility","id":"device-and-os-compatibility","depth":3},{"value":"Supported iOS versions","id":"supported-ios-versions","depth":4},{"value":"Device requirements","id":"device-requirements","depth":4},{"value":"Configuration requirements","id":"configuration-requirements","depth":4},{"value":"Step 1: Configure app entitlements","id":"step-1-configure-app-entitlements","depth":2},{"value":"Entitlements.plist","id":"entitlementsplist","depth":3},{"value":"Info.plist privacy descriptions","id":"infoplist-privacy-descriptions","depth":3},{"value":"Step 2: Initialise the iOS SDK","id":"step-2-initialise-the-ios-sdk","depth":2},{"value":"Configuration parameters","id":"configuration-parameters","depth":3},{"value":"Step 3: Create the component configuration","id":"step-3-create-the-component-configuration","depth":2},{"value":"Configuration parameters","id":"configuration-parameters-1","depth":3},{"value":"Step 4: Setup the view layout","id":"step-4-setup-the-view-layout","depth":2},{"value":"Using Storyboard","id":"using-storyboard","depth":3},{"value":"Using SwiftUI","id":"using-swiftui","depth":3},{"value":"Step 5: Create and mount the component","id":"step-5-create-and-mount-the-component","depth":2},{"value":"SwiftUI component wrapper","id":"swiftui-component-wrapper","depth":3},{"value":"Step 6: Handle payment results","id":"step-6-handle-payment-results","depth":2},{"value":"Step 7: Add advanced event handling","id":"step-7-add-advanced-event-handling","depth":2},{"value":"Step 8: Component lifecycle management","id":"step-8-component-lifecycle-management","depth":2},{"value":"What's next?","id":"whats-next","depth":2},{"value":"Customise the look and feel","id":"customise-the-look-and-feel","depth":3},{"value":"Add more event handling","id":"add-more-event-handling","depth":3},{"value":"Add error handling and validation","id":"add-error-handling-and-validation","depth":3},{"value":"Complete UIKit example","id":"complete-uikit-example","depth":2}],"frontmatter":{"seo":{"title":"Implementation"}},"lastModified":"2026-05-19T10:18:47.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/guides/checkout/components/ios/apple-pay/implementation","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}