{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-guides/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["sub-heading","br","details","admonition"]},"type":"markdown"},"seo":{"title":"Card submit","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":"card-submit","__idx":0},"children":["Card submit"]},{"$$mdtype":"Tag","name":"SubHeading","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Learn about how to configure the card submit component."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"basic-usage","__idx":1},"children":["Basic usage"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"minimal-configuration","__idx":2},"children":["Minimal configuration"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The card submit component orchestrates validation, tokenisation, 3DS authentication, and authorisation. At minimum, you need to link your card input components and implement the required callbacks:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"import SwiftUI\nimport PXPCheckoutSDK\n\nlet pxpCheckout = try PxpCheckout.initialize(config: CheckoutConfig(\n    environment: .test,\n    session: SessionData(\n        sessionId: \"your-session-id\",\n        hmacKey: \"your-hmac-key\",\n        encryptionKey: \"your-encryption-key\"\n    ),\n    transactionData: TransactionData(\n        amount: Decimal(10),\n        currency: \"USD\",\n        entryType: .ecom,\n        intent: TransactionIntentData(card: .authorisation),\n        merchantTransactionId: \"unique-transaction-id\",\n        merchantTransactionDate: { Date() }\n    ),\n    merchantShopperId: \"shopper-id\",\n    ownerType: \"MerchantGroup\",\n    ownerId: \"your-owner-id\"\n))\n\nlet cardNumber = try pxpCheckout.create(\n    .cardNumber,\n    componentConfig: CardNumberComponentConfig(label: \"Card number\")\n) as! CardNumberComponent\n\nlet cardExpiry = try pxpCheckout.create(\n    .cardExpiryDate,\n    componentConfig: CardExpiryDateComponentConfig(label: \"Expiry date\")\n) as! CardExpiryDateComponent\n\nlet cardCvc = try pxpCheckout.create(\n    .cardCvc,\n    componentConfig: CardCvcComponentConfig(label: \"CVC\")\n) as! CardCvcComponent\n\nvar submitConfig = CardSubmitComponentConfig()\nsubmitConfig.cardNumberComponent = cardNumber\nsubmitConfig.cardExpiryDateComponent = cardExpiry\nsubmitConfig.cardCvcComponent = cardCvc\n\nsubmitConfig.onPreAuthorisation = { preAuth in\n    TransactionInitiationData()\n}\n\nsubmitConfig.onPostAuthorisation = { result in\n    // Handle result (AuthorisedSubmitResult, RefusedSubmitResult, FailedSubmitResult)\n}\n\nlet cardSubmit = try pxpCheckout.create(.cardSubmit, componentConfig: submitConfig) as! CardSubmitComponent\n","lang":"swift"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Render the components in your SwiftUI view:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"VStack {\n    cardNumber.buildContent()\n    HStack {\n        cardExpiry.buildContent()\n        cardCvc.buildContent()\n    }\n    cardSubmit.buildContent()\n}\n","lang":"swift"},"children":[]},{"$$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":{"align":"left","data-label":"Property"},"children":["Property"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cardNumberComponent"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["CardNumberComponent?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The card number input component. Required when using standalone card fields (not using ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["newCardComponent"]},"). See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/card/card-number"},"children":["Card number"]},". Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nil"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cardExpiryDateComponent"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["CardExpiryDateComponent?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The expiry date component. Required when using standalone card fields (not using ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["newCardComponent"]},"). See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/card/card-expiry-date"},"children":["Card expiry date"]},". Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nil"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cardCvcComponent"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["CardCvcComponent?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The CVC component. Required when using standalone card fields (not using ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["newCardComponent"]},"). See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/card/card-cvc"},"children":["Card CVC"]},". Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nil"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["newCardComponent"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["NewCardComponent?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The pre-built new card component. Use this instead of standalone card fields for a simplified implementation. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/card/new-card"},"children":["New card"]},". Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nil"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPreAuthorisation"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["(PreAuthorizationData?) async -> TransactionInitiationData?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Required callback to provide transaction data before authorisation. Called after validation and tokenisation but before the authorisation request. Return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nil"]}," to abort the transaction."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPostAuthorisation"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["(BaseSubmitResult) -> Void"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Callback for handling the final transaction result. Receives one of: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["AuthorisedSubmitResult"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["RefusedSubmitResult"]},", or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FailedSubmitResult"]},"."]}]}]}]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use either ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["newCardComponent"]}," or the standalone card fields, not both."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"advanced-configuration","__idx":3},"children":["Advanced configuration"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can customise the submit button, enable AVS, configure 3DS, and add optional components:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"let cardHolderName = try pxpCheckout.create(\n    .cardHolderName,\n    componentConfig: CardHolderNameComponentConfig(label: \"Cardholder name\")\n) as! CardHolderNameComponent\n\nlet cardConsent = try pxpCheckout.create(\n    .cardConsent,\n    componentConfig: CardConsentComponentConfig(label: \"Save this card for future purchases\")\n) as! CardConsentComponent\n\nlet billingAddress = try pxpCheckout.create(\n    .billingAddress,\n    componentConfig: BillingAddressComponentConfig()\n) as! BillingAddressComponent\n\nvar submitConfig = CardSubmitComponentConfig()\nsubmitConfig.cardNumberComponent = cardNumber\nsubmitConfig.cardExpiryDateComponent = cardExpiry\nsubmitConfig.cardCvcComponent = cardCvc\nsubmitConfig.cardHolderNameComponent = cardHolderName\nsubmitConfig.cardConsentComponent = cardConsent\n\nsubmitConfig.submitText = \"Complete payment\"\nsubmitConfig.disableUntilValidated = true\nsubmitConfig.hideSubmitButton = false\n\nsubmitConfig.useCardOnFile = false\nsubmitConfig.avsRequest = true\nsubmitConfig.billingAddressComponents = BillingAddressComponents(\n    billingAddressComponent: billingAddress\n)\n\nsubmitConfig.useUnityAuthenticationStrategy = true\n\nsubmitConfig.onPreAuthorisation = { preAuth in\n    // Can use await here for async operations\n    return TransactionInitiationData()\n}\nsubmitConfig.onPostAuthorisation = { result in }\n\nlet cardSubmit = try pxpCheckout.create(.cardSubmit, componentConfig: submitConfig) as! CardSubmitComponent\n","lang":"swift"},"children":[]},{"$$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":{"align":"left","data-label":"Property"},"children":["Property"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["submitText"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["String?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The button text. Supports ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{amount}"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{currency}"]}," placeholders which are automatically replaced with the transaction values. Defaults to SDK localisation."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["disableUntilValidated"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["Bool?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Whether to disable the button until all fields are valid. When ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]},", the button remains disabled until all required card fields pass validation. Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["hideSubmitButton"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["Bool?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Whether to hide the button so you can call ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["submitAsync()"]}," from your own control. When ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]},", you must manually trigger submission. Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["styles"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["ButtonStateStyles?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The button styling for base, disabled, and loading states. Each state can have different appearance. Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nil"]},". States: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["base"]}," (normal clickable), ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["disabled"]}," (validation failed or processing), ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["loading"]}," (payment in progress)."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cardHolderNameComponent"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["CardHolderNameComponent?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The optional cardholder name field. When provided, the cardholder's name is included in the tokenisation request. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/card/cardholder-name"},"children":["Cardholder name"]},". Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nil"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cardConsentComponent"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["CardConsentComponent?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The optional consent checkbox for saving cards. When checked and transaction succeeds, the card is tokenised for future use. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/card/card-consent"},"children":["Card consent"]},". Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nil"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cardOnFileComponent"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["CardOnFileComponent?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The saved cards component. Required when ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["useCardOnFile"]}," is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]},". Displays previously saved card tokens. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/card/card-on-file"},"children":["Card-on-file"]},". Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nil"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["clickOnceStandaloneComponent"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["ClickOnceStandaloneComponent?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The Click Once component for one-click payments. Displays the most recently used card with a submit button. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/card/click-once"},"children":["Click-once"]},". Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nil"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["useCardOnFile"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["Bool?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Whether to use a tokenised card instead of new card entry. When ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cardOnFileComponent"]}," must be provided. Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["avsRequest"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["Bool?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Whether to send billing address for address verification (AVS). When ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["billingAddressComponents"]}," must be provided. Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["billingAddressComponents"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["BillingAddressComponents?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The billing address components for AVS. Required when ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["avsRequest"]}," is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]},". Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nil"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["useUnityAuthenticationStrategy"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["Bool?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Whether to use Unity's integrated 3DS strategy. When ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]},", the SDK handles 3DS authentication automatically using Unity's service. Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["authenticationConfig"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["AuthenticationConfig?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The optional authentication configuration object. Provides additional control over 3DS authentication behaviour. Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nil"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["billingAddressComponents.billingAddressComponent"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["BillingAddressComponent?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The pre-built billing address form including country, postcode, and street address. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/card/billing-address"},"children":["Billing address"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["billingAddressComponents.countrySelectionComponent"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["CountrySelectionComponent?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The standalone country field. Alternative to using the pre-built billing address form. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/card/country-selection"},"children":["Country selection"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["billingAddressComponents.postcodeComponent"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["PostcodeComponent?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The standalone postcode field. Alternative to using the pre-built billing address form. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/card/postcode"},"children":["Postcode"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["billingAddressComponents.addressComponent"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["AddressComponent?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The standalone address field. Alternative to using the pre-built billing address form. See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/card/address"},"children":["Address"]},"."]}]}]}]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you provide both a pre-built billing address component and standalone billing fields, the pre-built component takes precedence."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"styling","__idx":4},"children":["Styling"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"default-styling","__idx":5},"children":["Default styling"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The card submit button uses built-in styling with colors, padding, and loading states."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"custom-styling","__idx":6},"children":["Custom styling"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["You can customise the button appearance for different states:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"submitConfig.styles = ButtonStateStyles(\n    base: FieldStyle(\n        color: .white,\n        font: .headline,\n        backgroundColor: .blue,\n        cornerRadius: 10,\n        padding: EdgeInsets(top: 14, leading: 20, bottom: 14, trailing: 20)\n    ),\n    disabled: FieldStyle(\n        color: .white,\n        backgroundColor: .gray.opacity(0.5),\n        cornerRadius: 10,\n        padding: EdgeInsets(top: 14, leading: 20, bottom: 14, trailing: 20)\n    ),\n    loading: FieldStyle(\n        color: .white,\n        backgroundColor: .blue.opacity(0.7),\n        cornerRadius: 10,\n        padding: EdgeInsets(top: 14, leading: 20, bottom: 14, trailing: 20)\n    )\n)\n","lang":"swift"},"children":[]},{"$$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":{"align":"left","data-label":"Property"},"children":["Property"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["styles.base"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["FieldStyle?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The button appearance in normal state when clickable and ready. Properties: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["color"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["font"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["fontWeight"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["fontSize"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["backgroundColor"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["borderColor"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["borderWidth"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cornerRadius"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["padding"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["margin"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["textAlignment"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["opacity"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["shadow"]}," (ShadowStyle), ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["icon"]}," (IconStyle)."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["styles.disabled"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["FieldStyle?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The button appearance when disabled due to validation failure or processing. Uses the same properties as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["base"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["styles.loading"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["FieldStyle?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The button appearance during payment processing. Typically shows a loading indicator. Uses the same properties as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["base"]},"."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"event-handling","__idx":7},"children":["Event handling"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The card submit component provides event handlers for the complete payment lifecycle:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"submitConfig.onClick = {\n    // Button tapped, before validation\n}\n\nsubmitConfig.onStartSubmit = {\n    // Validation passed, submission started\n}\n\nsubmitConfig.onChange = { state in\n    // Component state changed (idle, loading, success, error)\n}\n\nsubmitConfig.onValidation = { results in\n    // Field validation results\n}\n\nsubmitConfig.onCustomValidation = {\n    // Can use await here for async validation\n    return true\n}\n\nsubmitConfig.onPreTokenisation = {\n    // Before tokenisation (new card)\n    return true\n}\n\nsubmitConfig.onPostTokenisation = { result in\n    // Tokenisation completed\n}\n\nsubmitConfig.onPreInitiateAuthentication = {\n    // Can use await here\n    return PreInitiateIntegratedAuthenticationData(providerId: \"pxpfinancial\", timeout: 120)\n}\n\nsubmitConfig.onPostInitiateAuthentication = { result in\n    // 3DS pre-initiate completed\n}\n\nsubmitConfig.onPreAuthentication = {\n    // Can use await here\n    return InitiateIntegratedAuthenticationData(\n        merchantCountryNumericCode: \"826\",\n        merchantLegalName: \"Example Ltd\",\n        challengeWindowSize: .size1,\n        requestorChallengeIndicator: .challengeRequestedMandate,\n        timeout: 180\n    )\n}\n\nsubmitConfig.onPostAuthentication = { result in\n    // 3DS authentication completed\n}\n\nsubmitConfig.onPreAuthorisation = { preAuth in\n    // Can use await here for async operations\n    return TransactionInitiationData()\n}\n\nsubmitConfig.onPostAuthorisation = { submitResult in\n    // Final transaction result\n}\n\nsubmitConfig.onPreRetrySoftDecline = { result in\n    .simple(true)\n}\n\nsubmitConfig.onGetFingerprintResult = {\n    // Can use await here to fetch fingerprint\n    return \"\"\n}\n\nsubmitConfig.onCollectStart = { _ in }\nsubmitConfig.onCollectEnd = { _ in }\n\nsubmitConfig.onSubmitError = { error in\n    // Handle errors\n}\n","lang":"swift"},"children":[]},{"$$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":{"align":"left","data-label":"Callback"},"children":["Callback"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onClick: (() -> Void)?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Called when the button is tapped, before validation runs."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onStartSubmit: (() -> Void)?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Called after validation passes and before submission begins."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onChange: ((ComponentState) -> Void)?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Called when the component state changes. Receives the new state: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["idle"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["loading"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["success"]},", or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onValidation: (([ValidationResult]) -> Void)?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Called with aggregated validation results from all linked components."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onCustomValidation: (() async -> Bool)?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Custom validation logic hook. Return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]}," to abort submission."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPreTokenisation: (() -> Bool)?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Called before tokenisation. Return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]}," to skip tokenisation."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPostTokenisation: ((CardTokenizationResult) -> Void)?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Called after tokenisation completes. Receives the tokenisation result."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPreInitiateAuthentication: (() async -> PreInitiateIntegratedAuthenticationData?)?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Called to provide 3DS pre-initiate configuration. Return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nil"]}," to skip this step."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPostInitiateAuthentication: ((AuthenticationResult) -> Void)?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Called after 3DS pre-initiate completes. Receives the authentication result."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPreAuthentication: (() async -> InitiateIntegratedAuthenticationData?)?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Called to provide 3DS authentication configuration. Return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nil"]}," to skip 3DS challenge."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPostAuthentication: ((AuthenticationResult) -> Void)?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Called after 3DS challenge completes. Receives the authentication result."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPreAuthorisation: ((PreAuthorizationData?) async -> TransactionInitiationData?)?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Required callback to provide transaction data before authorisation. Return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["nil"]}," to abort authorisation."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPostAuthorisation: ((BaseSubmitResult) -> Void)?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Called with the final transaction result. Receives one of: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["AuthorisedSubmitResult"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["RefusedSubmitResult"]},", or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FailedSubmitResult"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPreRetrySoftDecline: ((BaseSubmitResult) -> SoftDeclineRetryResult)?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Called when a soft decline occurs. Return retry decision (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".simple(true)"]}," to retry, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".simple(false)"]}," to stop)."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onGetFingerprintResult: (() async -> String)?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Called to provide device fingerprint for risk screening. Return the fingerprint string."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onCollectStart: ((Any) -> Void)?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Called when data collection starts. Receives collection metadata."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onCollectEnd: ((Any) -> Void)?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Called when data collection ends. Receives collection metadata."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onSubmitError: ((BaseSdkException) -> Void)?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Called when SDK or network errors occur. Receives the exception details."]}]}]}]}]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For more information about event data structures and usage patterns, see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/card/events"},"children":["Events"]},", ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/card/3ds"},"children":["3DS transactions"]},", and ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/card/data-validation"},"children":["Data validation"]},"."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"methods","__idx":8},"children":["Methods"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"submitasync","__idx":9},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["submitAsync()"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Programmatically triggers the payment flow. Use when ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["hideSubmitButton"]}," is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["true"]}," or from your own custom button:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"await cardSubmit.submitAsync()\n","lang":"swift"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The method runs the complete payment pipeline:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Validates linked components and AVS data"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Tokenises the card (for new card flows)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Runs 3DS authentication when required"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Calls ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPreAuthorisation"]}," and processes authorisation"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Invokes configured callbacks in sequence"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"buildcontent","__idx":10},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["buildContent()"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Returns SwiftUI content for the submit button:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"cardSubmit.buildContent()\n","lang":"swift"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"examples","__idx":11},"children":["Examples"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"basic-payment-form","__idx":12},"children":["Basic payment form"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A complete payment form with card fields and submit button:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"struct BasicCardPaymentView: View {\n    @State private var checkout: PxpCheckout?\n    @State private var cardNumber: CardNumberComponent?\n    @State private var cardExpiry: CardExpiryDateComponent?\n    @State private var cardCvc: CardCvcComponent?\n    @State private var cardSubmit: CardSubmitComponent?\n\n    var body: some View {\n        Group {\n            if let cardNumber, let cardExpiry, let cardCvc, let cardSubmit {\n                VStack(spacing: 16) {\n                    cardNumber.buildContent()\n                    HStack {\n                        cardExpiry.buildContent()\n                        cardCvc.buildContent()\n                    }\n                    cardSubmit.buildContent()\n                }\n                .padding()\n            } else {\n                ProgressView()\n            }\n        }\n        .task { await setup() }\n    }\n\n    private func setup() async {\n        do {\n            let session = SessionData(\n                sessionId: \"your-session-id\",\n                hmacKey: \"your-hmac-key\",\n                encryptionKey: \"your-encryption-key\"\n            )\n            let tx = TransactionData(\n                amount: Decimal(10),\n                currency: \"USD\",\n                entryType: .ecom,\n                intent: TransactionIntentData(card: .authorisation),\n                merchantTransactionId: UUID().uuidString,\n                merchantTransactionDate: { Date() }\n            )\n            let config = CheckoutConfig(\n                environment: .test,\n                session: session,\n                transactionData: tx,\n                merchantShopperId: \"shopper-1\",\n                ownerType: \"MerchantGroup\",\n                ownerId: \"your-owner-id\"\n            )\n            let pxp = try PxpCheckout.initialize(config: config)\n\n            let cn = try pxp.create(.cardNumber, componentConfig: CardNumberComponentConfig(label: \"Card number\")) as! CardNumberComponent\n            let ex = try pxp.create(.cardExpiryDate, componentConfig: CardExpiryDateComponentConfig(label: \"Expiry\")) as! CardExpiryDateComponent\n            let cv = try pxp.create(.cardCvc, componentConfig: CardCvcComponentConfig(label: \"CVC\")) as! CardCvcComponent\n\n            var sc = CardSubmitComponentConfig()\n            sc.cardNumberComponent = cn\n            sc.cardExpiryDateComponent = ex\n            sc.cardCvcComponent = cv\n            sc.submitText = \"Pay now\"\n            sc.disableUntilValidated = true\n            sc.onPreAuthorisation = { _ in\n                // Can use await here for async operations\n                return TransactionInitiationData()\n            }\n            sc.onPostAuthorisation = { result in\n                if result is AuthorisedSubmitResult {\n                    // Navigate to success\n                }\n            }\n            sc.onSubmitError = { _ in }\n            let submit = try pxp.create(.cardSubmit, componentConfig: sc) as! CardSubmitComponent\n\n            await MainActor.run {\n                checkout = pxp\n                cardNumber = cn\n                cardExpiry = ex\n                cardCvc = cv\n                cardSubmit = submit\n            }\n        } catch {\n            // Handle setup error\n        }\n    }\n}\n","lang":"swift"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"custom-validation","__idx":13},"children":["Custom validation"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Add your own validation logic before submission:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"submitConfig.onCustomValidation = {\n    // Can use await here for async validation\n    return myCustomValidationCheck()\n}\n","lang":"swift"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"programmatic-submission","__idx":14},"children":["Programmatic submission"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Hide the SDK button and use your own:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"submitConfig.hideSubmitButton = true\nlet cardSubmit = try pxpCheckout.create(.cardSubmit, componentConfig: submitConfig) as! CardSubmitComponent\n\n// In your SwiftUI view:\nButton(\"Pay with custom button\") {\n    Task {\n        await cardSubmit.submitAsync()\n    }\n}\n","lang":"swift"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"soft-decline-retry","__idx":15},"children":["Soft decline retry"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Handle soft declines with retry logic:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"submitConfig.onPreRetrySoftDecline = { result in\n    .withConfig(\n        SoftDeclineRetryConfig(\n            retry: true,\n            updatedConfigs: UpdatedAuthConfigs(\n                onPreAuthentication: {\n                    // Can use await here\n                    return InitiateIntegratedAuthenticationData(\n                        merchantCountryNumericCode: \"826\",\n                        merchantLegalName: \"Example Ltd\",\n                        challengeWindowSize: .size1,\n                        requestorChallengeIndicator: .challengeRequestedMandate,\n                        timeout: 180\n                    )\n                }\n            )\n        )\n    )\n}\n","lang":"swift"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"with-3ds-authentication","__idx":16},"children":["With 3DS authentication"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Enable Unity's 3DS strategy and implement authentication callbacks:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"swift","header":{"controls":{"copy":{}}},"source":"submitConfig.useUnityAuthenticationStrategy = true\nsubmitConfig.onPreInitiateAuthentication = {\n    // Can use await here\n    return PreInitiateIntegratedAuthenticationData(providerId: \"pxpfinancial\", timeout: 120)\n}\nsubmitConfig.onPostInitiateAuthentication = { result in\n    // Handle pre-initiate result\n}\nsubmitConfig.onPreAuthentication = {\n    // Can use await here\n    return InitiateIntegratedAuthenticationData(\n        merchantCountryNumericCode: \"826\",\n        merchantLegalName: \"Example Ltd\",\n        challengeWindowSize: .size1,\n        requestorChallengeIndicator: .challengeRequestedMandate,\n        timeout: 180\n    )\n}\nsubmitConfig.onPostAuthentication = { result in\n    // Handle authentication result\n}\n","lang":"swift"},"children":[]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For integration context, see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/card/implementation"},"children":["Implementation"]},". For 3DS details, see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/card/3ds"},"children":["3DS transactions"]},". For validation behaviour, see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/ios/card/data-validation"},"children":["Data validation"]},"."]}]}]},"headings":[{"value":"Card submit","id":"card-submit","depth":1},{"value":"Basic usage","id":"basic-usage","depth":2},{"value":"Minimal configuration","id":"minimal-configuration","depth":3},{"value":"Advanced configuration","id":"advanced-configuration","depth":3},{"value":"Styling","id":"styling","depth":2},{"value":"Default styling","id":"default-styling","depth":3},{"value":"Custom styling","id":"custom-styling","depth":3},{"value":"Event handling","id":"event-handling","depth":2},{"value":"Methods","id":"methods","depth":2},{"value":"submitAsync()","id":"submitasync","depth":3},{"value":"buildContent()","id":"buildcontent","depth":3},{"value":"Examples","id":"examples","depth":2},{"value":"Basic payment form","id":"basic-payment-form","depth":3},{"value":"Custom validation","id":"custom-validation","depth":3},{"value":"Programmatic submission","id":"programmatic-submission","depth":3},{"value":"Soft decline retry","id":"soft-decline-retry","depth":3},{"value":"With 3DS authentication","id":"with-3ds-authentication","depth":3}],"frontmatter":{"seo":{"title":"Card submit"}},"lastModified":"2026-05-18T11:23:43.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/guides/checkout/components/ios/card/card-submit","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}