## Confirm a Customer Balance payment Use `stripe.confirmCustomerBalancePayment` in the [Customer Balance](/payments/customer-balance.md) payment flow when the customer submits your payment form. When called, it will confirm the [PaymentIntent](/api/payment_intents.md) with `data` you provide. Refer to our [integration guide](/payments/bank-transfers/accept-a-payment.md) for more details. Since the [Customer Balance](/payments/customer-balance.md) payment method draws from a balance, the attempt will succeed or fail depending on the current balance amount. To collect more funds from the customer when the cash balance is insufficient, use the customer balance with [bank transfer funding](/payments/bank-transfers/accept-a-payment.md) parameters. The confirmation attempt will finish in one of the following result states: 1. If the customer balance is greater than or equal to the amount, the PaymentIntent response will have a `status` of `succeeded`. The `funding_type` will be ignored. 2. If the customer balance is less than the amount, and you do not set the `funding_type`, the PaymentIntent response will have a `status` of `requires_payment_method`. 3. If the customer balance is less than the amount, and you set the `funding_type`, the PaymentIntent response will have a `status` of `requires_action`. The `paymentIntent.next_action.display_bank_transfer_instructions` hash will contain bank transfer details for funding the [Customer Balance](/payments/customer-balance.md). > Note that `stripe.confirmCustomerBalancePayment` may take several seconds to complete. > During that time, you should disable your form from being resubmitted and show a waiting indicator like a spinner. > If you receive an error result, you should be sure to show that error to the customer, re-enable the form, and hide the waiting indicator. `stripe.confirmCustomerBalancePayment` will return a `Promise` which resolves with a result object. This object has either: * `result.paymentIntent`: when the [Customer Balance](/payments/customer-balance) is sufficient to pay the amount, a [PaymentIntent](/api/payment_intents) with `status` of `succeeded`. * `result.paymentIntent`: when the [Customer Balance](/payments/customer-balance) is insufficient to pay the amount, and `funding_type` data was provided, a [PaymentIntent](/api/payment_intents) with `status` of `requires_action`. * `result.paymentIntent`: when the [Customer Balance](/payments/customer-balance) is insufficient to pay the amount, and no `funding_type` data was provided, a [PaymentIntent](/api/payment_intents) with `status` of `requires_payment_method`. * `result.error`: an error. Refer to the API reference for all possible errors. **Syntax:** `stripe.confirmCustomerBalancePayment(...)` - `clientSecret` (string) **required** The [client secret](/api/payment_intents/object.md#payment_intent_object-client_secret) of the `PaymentIntent`. - `data` (object) Data to be sent with the request. Refer to the [Payment Intents API](/api/payment_intents/confirm.md) for a full list of parameters. - `payment_method` (object) **required** An object specifying the `customer_balance` type. - `customer_balance` (object) **required** Set to `{}`. - `payment_method_options` (object) Additional payment specific configuration options. See the [with collected data](#stripe_confirm_customer_balance_payment-collected) use case below. - `options` (object) An options object to control the behavior of this method. - `handleActions` (boolean) **required** Set to `false`. The [Customer Balance](/payments/customer-balance.md) does not handle the next actions for you automatically (e.g. displaying bank transfer details). To make future upgrades easier, this option is required to always be sent. Please refer to our [Stripe Customer Balance integration guide](/payments/bank-transfers.md) for more info. ### Use case: with collected data You can pass in the customer’s [bank transfer funding](/payments/bank-transfers/accept-a-payment.md) details to create a new `PaymentMethod` and confirm the `PaymentIntent`. If the [Customer Balance](/payments/customer-balance.md) was not enough to pay the amount, the `status` is `requires_action`. The `paymentIntent.next_action.display_bank_transfer_instructions` hash contains bank transfer details for funding the [Customer Balance](/payments/customer-balance.md). ### Data argument properties - `payment_method` (object) **required** Pass an object to confirm using data collected. - `customer_balance` (object) **required** Set to `{}`. - `payment_method_options` (object) Additional payment-specific configuration options. - `funding_type` (string) The funding method type to be used when there are not enough funds in the [Customer Balance](/payments/customer-balance.md). Permitted values include: `bank_transfer`. - `bank_transfer` (object) The customer's chosen bank transfer method. - `type` (string) **required** The list of bank transfer types allowed to use for funding. Permitted values include: `us_bank_account`, `eu_bank_account`, `id_bank_account`, `gb_bank_account`, `jp_bank_account`, or `mx_bank_account`. - `eu_bank_account` (object) Details for the customer's EU bank account transfer. Required if the type is `eu_bank_account`. - `country` (string) **required** The desired country code of the bank account information. Permitted values include: `DE`, `ES`, `FR`, `IE`, `NL`. - `id_bank_account` (object) Details for the customer's Indonesian bank account transfer. Required if the type is `id_bank_account`. - `bank` (string) **required** Bank where the account is held. One of `bca`, `bni`. - `requested_address_types` (array) List of address types that should be returned in the financial_addresses response. If not specified, all valid types will be returned. Permitted values include: `aba`, `swift`, `sort_code`, `zengin`, `iban`, `spei`, `id_bban`, or `sepa`. ### Confirm with collected data ```js stripe.confirmCustomerBalancePayment( '{PAYMENT_INTENT_CLIENT_SECRET}', { payment_method: { customer_balance: { }, }, payment_method_options: { customer_balance: { funding_type: 'bank_transfer', bank_transfer: { type: 'us_bank_account', }, }, }, }, { handleActions: false, } ).then(function({error, paymentIntent}) { if (error) { // Inform the customer that there was an error. } else if (paymentIntent.status === 'requires_payment_method') { // If `payment_method_options.funding_type` wasn't set this // is where you would need to handle the insufficient customer // balance state. } else if (paymentIntent.status === 'requires_action') { // If the current customer balance is insufficient to cover // the amount, and you've passed // `payment_method_options.funding_type` for funding the // customer balance, you can display the bank transfer // instructions to your user. if (paymentIntent.next_action.type === 'display_bank_transfer_instructions') { // Bank transfer details can be found under: // paymentIntent.next_action.display_bank_transfer_instructions } } }); ``` ```es_next const {paymentIntent, error} = await stripe.confirmCustomerBalancePayment( '{PAYMENT_INTENT_CLIENT_SECRET}', { payment_method: { customer_balance: { }, }, payment_method_options: { customer_balance: { funding_type: 'bank_transfer', bank_transfer: { type: 'us_bank_account', }, }, }, }, { handleActions: false, } ); if (error) { // Inform the customer that there was an error. } else if (paymentIntent.status === 'requires_payment_method') { // If `payment_method_options.funding_type` wasn't set this // is where you would need to handle the insufficient customer // balance state. } else if (paymentIntent.status === 'requires_action') { // If the current customer balance is insufficient to cover // the amount, and you've passed // `payment_method_options.funding_type` for funding the // customer balance, you can display the bank transfer // instructions to your user. if (paymentIntent.next_action.type === 'display_bank_transfer_instructions') { // Bank transfer details can be found under: // paymentIntent.next_action.display_bank_transfer_instructions } } ``` ### Confirm a Customer Balance payment ```js stripe.confirmCustomerBalancePayment( '{PAYMENT_INTENT_CLIENT_SECRET}', { payment_method: { customer_balance: {}, } }, { handleActions: false, } ).then(function({error, paymentIntent}) { if (error) { // Inform the customer that there was an error. } else if (paymentIntent.status === 'requires_payment_method') { // If `payment_method_options.funding_type` wasn't set this // is where you would need to handle the insufficient customer // balance state. } else if (paymentIntent.status === 'requires_action') { // If the current customer balance is insufficient to cover // the amount, and you've passed // `payment_method_options.funding_type` for funding the // customer balance, you can display the bank transfer // instructions to your user. if (paymentIntent.next_action.type === 'display_bank_transfer_instructions') { // Bank transfer details can be found under: // paymentIntent.next_action.display_bank_transfer_instructions } } }); ``` ```es_next const {paymentIntent, error} = await stripe.confirmCustomerBalancePayment( '{PAYMENT_INTENT_CLIENT_SECRET}', { payment_method: { customer_balance: {}, } }, { handleActions: false, } ); if (error) { // Inform the customer that there was an error. } else if (paymentIntent.status === 'requires_payment_method') { // If `payment_method_options.funding_type` wasn't set this // is where you would need to handle the insufficient customer // balance state. } else if (paymentIntent.status === 'requires_action') { // If the current customer balance is insufficient to cover // the amount, and you've passed // `payment_method_options.funding_type` for funding the // customer balance, you can display the bank transfer // instructions to your user. if (paymentIntent.next_action.type === 'display_bank_transfer_instructions') { // Bank transfer details can be found under: // paymentIntent.next_action.display_bank_transfer_instructions } } ```