# FlowComponent ## Methods ### submit() Submits a `FlowComponent`, if you require your own pay button. > **Information** > > This option is not available for digital wallets, including Apple Pay and Google Pay. ```javascript function submit() { return FlowComponent; } ``` ### tokenize(): Promise(TokenizeResult) This method must be used with your own pay button. It submits a `FlowComponent` element with card or card verification value (CVV) tokenization. This method only works with card payments. **Card component** Returns a [JavaScript Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves with the `TokenizeResult` object, which includes the following fields: - `type` – The name of the payment method that initiated the tokenization – Only `card` is supported. - `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 a Card Metadata API response is received during customer input ```javascript const cardComponent = checkout.create('card'); if (await cardComponent.isAvailable()) { cardComponent.mount('#card-container'); } const cardPayButton = document.getElementbyId('card-pay-button'); cardPayButton.addEventListener('click', async () => { const { data } = await cardComponent.tokenize(); await utilizeToken(data.token); });+ ``` **CVV component** Returns a [JavaScript Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves with the `CardCvvTokenizeResult` object, which includes the following fields: - `type` – The name of the payment method that initiated the tokenization – Only `card_cvv` is supported. - `data` – The [Card CVV Tokenization response](https://api-reference.checkout.com/tag/Tokens/#operation/requestAToken!c=201&path=3/type&t=response) ```javascript const storedCardPayButton = document.getElementbyId('stored-card-pay-button'); storedCardPayButton.addEventListener('click', async () => { const { data } = await cardCvvComponent.tokenize(); await utilizeToken(data.token); }); ``` --- ### isValid() Checks if the `FlowComponent` has captured all details from the customer and can be submitted. ```javascript function isValid() { return boolean; } ``` --- ### isAvailable() Checks if the `FlowComponent` can be rendered. Call this before mounting the `FlowComponent`. ```javascript function isAvailable() { return Promise; } ``` --- ### unselect() Cancels the selection of the currently selected payment method in the `FlowComponent` instance. The `unselect()` method only works with the `flow` component. Calling `unselect()` when no payment method is selected has no effect. Additionally, after calling `unselect()`, subsequent calls to `submit()` or `tokenize()` also have no effect, because no payment method is active. ```javascript const flowComponent = checkout.create('flow'); flowComponent.mount('#flow-container'); flowComponent.unselect(); ``` --- ### mount('#element') Mounts a `FlowComponent` to a page. You can provide one of the following: - A [DOM Element Object](https://developer.mozilla.org/en-US/docs/Web/API/Document_object_model/Locating_DOM_elements_using_selectors) - An [Element Selector](https://developer.mozilla.org/en-US/docs/Web/API/Element) | Parameter | Type | Description | | --- | --- | --- | | `#elem` | `object` | The Element Selector or DOM Element object you want to mount to. | ```javascript function mount('#element') { return FlowComponent; } ``` --- ### unmount() Unmounts a `FlowComponent` from the page. This stops rendering the component, and removes all life-cycles from the browser. ```javascript function unmount() { return FlowComponent; } ``` --- ## Events ### onReady(FlowComponent) Raised when a `FlowComponent` is initialized and ready for the customer to interact. ```javascript const flowComponent = checkout.create('flow', { onReady: (_self) => { // Hide loading overlay hideLoadingOverlay(); }, }); flowComponent.mount('#flow-container'); ``` --- ### onChange(FlowComponent) Raised when a `FlowComponent` changes after a customer interaction. ```javascript const flowComponent = checkout.create('flow', { onChange: (_self) => { // Enable/disable custom pay button based on input validity if (self.isValid()) { submitButton.removeAttribute('disabled'); } else { submitButton.setAttribute('disabled', true); } }, }); flowComponent.mount('#flow-container'); ``` --- ### onSubmit(FlowComponent) Raised when you or the customer initiates a `FlowComponent` submission. ```javascript const flowComponent = checkout.create('flow', { onSubmit: (_self) => { // Show loading overlay to prevent further user interaction showLoadingOverlay(); }, }); flowComponent.mount('#flow-container'); ``` --- ### onPaymentCompleted(FlowComponent, PaymentResponse) Raised when the payment is completed synchronously. This event is not raised if the payment requires asynchronous action. For example, 3DS authentication. The `PaymentResponse` object contains information on the successful payment: - `id` – A unique identifier for the payment - `status` – The payment status – This always returns `Approved`. - `type` – The name of the payment method used for the payment ```javascript const flowComponent = checkout.create('flow', { onPaymentCompleted: async (_self, paymentResponse) => { // Complete order in server side await completeOrder(paymentResponse.id); }, }); flowComponent.mount('#flow-container'); ``` --- ### onMandateCreated(FlowComponent, MandateContext) Raised for Bacs Direct Debit payments, after Flow successfully creates the Direct Debit mandate. Bacs Direct Debit sets up a mandate rather than taking an immediate payment, so Flow does not raise `onPaymentCompleted` for this payment method. Use `onMandateCreated` to know that the Bacs setup completed successfully, and confirm the payment setup from your server after the five-day mandate activation period. For more information, see [Bacs Direct Debit for web](https://www.checkout.com/docs/payments/add-payment-methods/bacs/web.md). The `MandateContext` object contains the payment setup response: - `type` – The name of the payment method used for the setup – This always returns `bacs`. - `context_data.setup_id` – The unique identifier of the payment setup ```javascript const flowComponent = checkout.create('flow', { onMandateCreated: (_self, mandateContext) => { const setupId = mandateContext.context_data.setup_id; // Store the setup ID against your order, then redirect the customer window.location.href = `/confirmation?setup=${setupId}`; }, }); flowComponent.mount('#flow-container'); ``` > **Note** > > After Flow creates the mandate, it moves the pay button into its success state and locks the form so the customer cannot resubmit. Perform your redirect from inside `onMandateCreated`. --- ### onError(FlowComponent, CheckoutError) Raised when an error occurs. For more information, see the [CheckoutError](https://www.checkout.com/docs/payments/accept-payments/accept-a-payment-on-your-website/flow-library-reference/checkouterror.md) reference. ```javascript const flowComponent = checkout.create('flow', { onError: async (_self, error) => { // Display payment request failure message if (error.code === 'payment_request_failed') { showErrorMessage('Payment could not be processed. Please try again.'); } }, }); flowComponent.mount('#flow-container'); ``` ### onCardBinChanged(FlowComponent, CardMetadataResponse) Raised when the customer inputs or changes the first 11 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 BIN. The `CardMetadataResponse` object contains the [Card Metadata lookup response](https://api-reference.checkout.com/tag/Card-metadata/#operation/requestCardMetadata!c=200&path=bin&t=response). Flow accepts the card if the callback you provide does not return a response. 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. ```javascript const flowComponent = checkout.create('flow', { onCardBinChanged: (_self, cardMetadata) => { if (cardMetadata.card_type === 'credit') { return { continue: false, errorMessage: 'Credit cards are not accepted.', }; } return { continue: true }; } }); flowComponent.mount('#flow-container'); ``` --- ### onTokenized(FlowComponent, TokenizeResult) Raised when the cardholder details provided by the customer are tokenized. You can use this event to perform checks on a card based on its tokenization result and metadata. The `TokenizeResult` object contains the following information: - `type` – The name of the payment method that triggered the tokenization – Only `card` is supported. - `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 a Card Metadata API response is received during customer input Flow accepts the card if the callback you provide does not return a response. Additionally, depending on your preferred action, you can provide the corresponding object: - Accept the card: `{ continue: true }` - Reject the card: `{ continue: false, errorMessage: "Message" }` If you choose to reject the card, you can display a custom error message using the optional `errorMessage` object. ```javascript const flowComponent = checkout.create('flow', { onTokenized: (_self, tokenizeResult) => { if (tokenizeResult.data.card_type === 'CREDIT') { return { continue: false, errorMessage: 'Credit cards are not accepted.', }; } return { continue: true }; } }); flowComponent.mount('#flow-container'); ``` --- ### onAuthorized(FlowComponent, AuthorizeResult) When the customer initiates an Apple Pay or Google Pay payment submission, the `onAuthorized(FlowComponent)` event is raised. You can use the returned object to inspect the payment details they provided and decide whether to continue with the payment. For example, if you do not want to accept American Express or credit card payments. Depending on the payment method, `AuthorizeResult` contains different payloads: - For Apple Pay payments – It contains the payload from the `onpaymentauthorized` [event](https://developer.apple.com/documentation/applepayontheweb/applepaypaymentauthorizedevent) provided by the Apple Pay Javascript SDK. - For Google Pay payments – It contains the payload from the `loadPaymentData` [response](https://developers.google.com/pay/api/web/reference/response-objects#PaymentData) provided by the Google Pay API. > **Information** > > `onAuthorize` events raised by Google Pay payments do not return an `AuthorizeResult` object. Flow accepts the card if the callback you provide does not return a response. Additionally, depending on your preferred action, you can provide the corresponding object: - Accept the card – `{ continue: true }` - Reject the card – `{ continue: false, errorMessage: "Message" }` If you choose to reject the card, you can display a custom error message using the optional `errorMessage` object. ```javascript const applepayComponent = checkout.create('applepay', { onAuthorized: (_self, authorizeResult) => { if (authorizeResult?.payment?.token?.paymentMethod?.type === 'credit') { return { continue: false, errorMessage: 'Credit cards are not accepted.', }; } return { continue: true }; }, }); if (await applepayComponent.isAvailable()) { applepayComponent.mount('#applepay-container'); } ``` --- ## Callbacks ### handleClick(FlowComponent) Raised when a wallet payment button is clicked. For example, Apple Pay, Google Pay, or PayPal. You can use this to perform checks before beginning the payment process. `FlowComponent` is the instance that initiated the callback. ```javascript const flowComponent = checkout.create('flow', { handleClick: (_self) => { if (acceptedTermsAndConditions) { return { continue: true }; } return { continue: false }; }, }); flowComponent.mount('#flow-container'); ``` ### handleSubmit(FlowComponent, SubmitData) Raised when you or the customer submit a `FlowComponent` element. You can use this callback to submit a customized payment, by calling the [Submit a Payment Session Payment](https://api-reference.checkout.com/tag/Flow/#operation/SubmitPaymentSession) endpoint. The `SubmitData` object contains `session_data`. This is a unique token representing the additional customer data that Flow 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. ### handlePaymentAdditionalContentMount(FlowComponent, containerElement) Raised when a payment method is rendered in the Flow component. This callback is raised for each payment method rendered. You can use this callback to render additional content in the provided `containerElement` reference. For example, your Terms & Conditions message. The additional content appears after the _Pay_ or wallet payment button. You can provide a unique identifier string for each payment method, which is included as `mountIdentifier` in the `handlePaymentAdditionalContentUnmount` [callback](#handlePaymentAdditionalContentUnmount(FlowComponent,_containerElement,_mountIdentifier)) when the Flow component is unmounted. ```javascript let isCheckboxAccepted = false; const handlePaymentAdditionalContentMount = (_self, containerElement) => { const identifier = `${component.type}-tnc`; const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.name = identifier checkbox.addEventListener('click', () => { isCheckboxAccepted = checkbox.checked; }); const label = document.createElement('label'); label.innerHTML = 'By clicking the pay button, you authorize us to use your payment details to process the payment'; element.appendChild(checkbox); element.appendChild(label); return identifier; }; const handleClick = (_selef) => { if (isCheckboxAccepted) { return { continue: true }; } return { continue: false }; }; const checkout = await new CheckoutWebComponents({ paymentSession, publicKey, componentOptions: { flow: { handleClick, handlePaymentAdditionalContentMount, }, }, }); const flowComponent = checkout.create('flow'); flowComponent.mount('#flow-container'); ``` ### handlePaymentAdditionalContentUnmount(FlowComponent, containerElement, mountIdentifier) Raised when a payment method is unmounted from the Flow component. You can use this callback to clean up the rendered content, as well as any logic applied to your page. If you provide a unique identifier to the `handlePaymentAdditionalContentMount` [callback](#handlePaymentAdditionalContentMount(FlowComponent,_containerElement)) during rendering, it is returned as `mountIdentifier` for your reference. ```javascript const handlePaymentAdditionalContentMount = (component, containerElement) => { // Render the Terms and Conditions content to `containerElement` reference. }; const handlePaymentAdditionalContentUnmount = (component, containerElement, mountIdentifier) => { containerElement.innerHTML = ''; // Clean up the Terms and Conditions content. }; const checkout = await new CheckoutWebComponents({ paymentSession, publicKey, componentOptions: { flow: { handlePaymentAdditionalContentMount, handlePaymentAdditionalContentUnmount, }, }, }); const flowComponent = checkout.create('flow'); flowComponent.mount('#flow-container'); ```