# ComponentCallback ```swift /// - Parameters: /// - onReady: A closure that is triggered when the payment method is ready. Defaults to `nil`. /// - handleTap: A closure that is used to validate conditions before processing the payment. Useful for handling pre-payment checks like T&C validation. Defaults to `nil`. /// - onChange: A closure that is triggered when the payment method is changed and any new updates. /// - onCardBinChanged: A closure that is triggered when the card bin is changed and card metadata is successfully fetched. /// - onSubmit: A closure that is triggered when the payment method is submitted. Defaults to `nil`. /// - onTokenized: A closure that is triggered when an item can be tokenized, providing the token details. /// - handleSubmit: A closure that is used to submit a customized payment session /// - onSuccess: A closure that is triggered when the payment is successful, passing the payment method and a unique `PaymentId`. /// - onError: A closure that is triggered when an error occurs during the payment process. public init(onReady: (@Sendable (Describable) -> Void)? = nil, handleTap: (@Sendable (Describable) async -> Bool)? = nil, onChange: (@Sendable (any Describable & Tokenizable & Submittable) -> Void)? = nil, onCardBinChanged: (@Sendable (CardMetadata) -> CallbackResult)? = nil, onSubmit: (@Sendable (Describable) -> Void)? = nil, onTokenized: (@Sendable (TokenizationResult) -> CallbackResult)? = nil, handleSubmit: (@Sendable (SessionData) async -> APICallResult)? = nil, onSuccess: (@Sendable (Describable, PaymentID) -> Void)? = nil, onError: (@Sendable (CheckoutComponents.Error) -> Void)? = nil) ``` ## Methods ### onReady(Describable) Triggered when a component is initialized and is ready for the customer to interact with. `Describable` is the payment method that triggered the event. ```swift let callbacks = CheckoutComponents.Callbacks(onReady: { paymentMethod in // Hide loading overlay hideLoadingOverlay(); } let configuration = CheckoutComponents.Configuration(callbacks: callbacks) ``` ### onSubmit(Describable) Triggered when you or the customer trigger a component submission. `Describable` is the payment method that triggered the event. ```swift let callbacks = CheckoutComponents.Callbacks(onSubmit: { paymentMethod in // Show loading overlay to prevent further user interaction showLoadingOverlay(); } let configuration = CheckoutComponents.Configuration(callbacks: callbacks) ``` ### onSuccess(Describable, PaymentID) Triggered when the payment has been synchronously or asynchronously completed. For example, after a successful 3DS authentication. The callback contains the following payment information: - `Describable` – The payment method component that triggered the event - `PaymentID` – The payment's unique identifier ```swift let callbacks = CheckoutComponents.Callbacks(onSuccess: { paymentMethod, paymentID in // Payment with ID: paymentID has gone through successfully } let configuration = CheckoutComponents.Configuration(callbacks: callbacks) ``` ### onError(CheckoutComponents.Error) Triggered when an error occurs. See the [CheckoutError reference](https://www.checkout.com/docs/payments/accept-payments/accept-a-payment-on-your-mobile-app/flow-for-mobile-library-reference/ios/checkouterror.md) for more information. `Describable` is the payment method component that triggered the event. ```swift let callbacks = CheckoutComponents.Callbacks(onError: { error in switch error.errorCode { case .paymentRequestDeclined: showErrorMessage("Payment could not be processed. Please try again.") default: showErrorMessage("An error occurred") // Or refine more specific error strings for different error codes } } ) let configuration = CheckoutComponents.Configuration(callbacks: callbacks) ``` ### handleTap(Describable) Triggered when the customer selects a payment button. You can use this to perform checks before beginning the payment process. ```swift handleTap: { paymentMethod async -> Bool in return isTermsAndConditionsAccepted(for: paymentMethod) } ``` ### onTokenized(TokenizationResult) Triggered when a supported `PaymentMethodComponent` item is tokenized and provides the `TokenizationResult` object. * type – The name of the payment method that triggered the tokenization. Always set this to `card`. * data – [The card tokenization response](https://api-reference.checkout.com/tag/Tokens/#operation/requestAToken!c=201&path=0/type&t=response). * cardMetadata – An optional [Card metadata lookup response](https://api-reference.checkout.com/tag/Card-metadata/#operation/requestCardMetadata!c=200&path=bin&t=response) object included when you receive a card metadata API response during customer input. * preferredScheme – The customer's preferred payment scheme when multiple schemes are supported for the card. For example, Visa and Cartes Bancaires. This can be `nil` if no preference is selected, or if the scheme choice was not offered. * storeForFutureUse – The customer's save-card consent choice, exposed only while the save-card consent checkbox is shown. `true` when the customer checked the checkbox, `false` when they left it unchecked, and `nil` when no consent was collected. > **Important** > > When `storeForFutureUse` is present, forward it as `source.store_for_future_use` on your payment request. Sending nothing means the card is not stored, regardless of what the customer chose. Whether the consent checkbox displays, and what `storeForFutureUse` reports, depends on the session value of `store_payment_details` on the card payment method: | Session value of store_payment_details | Consent checkbox shown? | storeForFutureUse | | --- | --- | --- | | `collect_consent`, Remember Me not available on the session | Yes | `true` or `false`, matching the checkbox | | `collect_consent`, Remember Me available | No. Remember Me collects consent through its own flow. | `nil` | | `enabled` | No. The backend forces storage on. | `nil` | | `disabled`, absent, or unrecognized | No. The backend forces storage off. | `nil` | > **Note** > > If your payment session request omits `customer.email`, the backend silently downgrades `store_payment_details: collect_consent` to `disabled`. If you are not seeing the consent checkbox, check your session request before troubleshooting your integration. Flow for mobile accepts the card if you do not provide the callback. Additionally, depending on your preferred action, you can provide the corresponding object: - Accept the card – `return .accepted` - Reject the card – `return .reject(message: "Error message")` If you reject the card, you can display a custom error message using the optional `errorMessage` object. > **Note** > > If you attempt to tokenize an unsupported `Tokenizable` item, the `onError()` callback triggers instead. ```swift onTokenized: { tokenizationResult in if tokenizationResult.data.cardType == "CREDIT" { return .rejected(message: "Credit cards are not accepted.") } return .accepted } ) let configuration = CheckoutComponents.Configuration(..., callbacks: callbacks) ``` ### onChange(Describable) Triggered when a component's inputs change after a customer interaction. > **Note** > > If you attempt to submit an unsupported `Submittable` component, you'll trigger the `onError()` callback. > **Note** > > The component handed to this callback is a snapshot of the component's state, not the live component. To tokenize, call `tokenize()` on the component instance itself, not on the value received here. ```swift let callbacks = CheckoutComponents.Callbacks(onTokenized: { tokenizationResult in handleToken(tokenizationResult.data) // Or use other token details for your own fraud checks }) let configuration = CheckoutComponents.Configuration(..., callbacks: callbacks) ``` ### onCardBinChanged(CardMetadata) : CallbackResult Raised when the customer inputs or changes the first eight digits of a card. You can use this event to perform checks on a card based on its metadata or to observe changes to the bank identification number (BIN). The `CardMetadata` object contains the [Card Metadata lookup response](https://api-reference.checkout.com/tag/Card-metadata/#operation/requestCardMetadata!c=200&path=bin&t=response). Flow for mobile accepts the card if you do not provide the callback. Additionally, depending on your preferred action, you can provide the corresponding object: - Accept the card – `return .accepted` - Reject the card – `return .rejected(message: "Error message")` If you reject the card, you can display a custom error message using the optional `errorMessage` object. ```swift let callbacks = CheckoutComponents.Callbacks( onCardBinChanged: { cardMetadata in // Reject credit cards if cardMetadata.cardType == "credit" { return .rejected(message: "Credit cards are not accepted.") } // Otherwise, allow the payment to proceed return .accepted } ) let configuration = CheckoutComponents.Configuration(..., callbacks: callbacks) ``` ### handleSubmit(SessionData) : APICallResult You can use this callback to submit a customized payment, using the [Submit a Payment Session](https://api-reference.checkout.com/tag/Flow/#operation/SubmitPaymentSession) endpoint. If no callback is provided, the payment is processed as normal, and Flow for mobile sends the request. The `SubmitData` object contains `session_data`, which is a unique token representing the additional customer data that Flow for mobile captured. You must provide this token when you submit the customized payment session request. You must provide the unmodified response body returned by the endpoint. ```swift let callbacks = CheckoutComponents.Callbacks( handleSubmit: { sessionData in submitPaymentSession(sessionData) } ) let configuration = CheckoutComponents.Configuration(..., callbacks: callbacks) ```