#dawid_fw

1 messages · Page 1 of 1 (latest)

fluid wigeonBOT
hoary thicket
#

We use our own form for gathering billing details.
We send these values in both elements.create as defaultValues.billingDetails and in element.confirm as confirmParams.payment_method_data.billing_details

On screenshot we have have example of checkout where we selected Poland as billing country and tried to pay with Cash App Pay (because currency was USD)

On payment confirm we received "Cash App Pay does not support 'PL' as the billing country, it only supports 'US'."

Is there a way to make Payment elements not show this method based on country instead of failing it at this point?

We also tried to use Billing Address Elements, but it didn't help.

#

On screen you can see selected Country and Payment methods it displayed.

dreamy void
#

Yeah you need to update the payment intent with the billing details

#

So don't render the checkout form until after you've collecting billing details

#

That way you can create your pi with those details

#

Or update it

hoary thicket
dreamy void
#

Ah ok

#

So where do you pass payment method configuration?

#

Can you share a code snippet?

hoary thicket
#

Parts of our FE

    const elements = instance.elements({
      // @ts-ignore this is not typed in @types/stripe-v3
      mode: 'payment',
      locale: 'en',
      currency: amount?.currency.toLowerCase(),
      paymentMethodConfiguration: options.paymentMethodConfigurationId,
      setupFutureUsage: options.setupFutureUsage,
      amount: Math.round((amount?.value || 0) * 100),
      appearance,
      loader: 'never',
      fonts: getFonts(theme),
    })

    setPaymentElements(elements)

    // @ts-ignore this is not typed in @types/stripe-v3
    const element = elements.create('payment', {
      layout: {
        type: 'accordion',
        radios: false,
        spacedAccordionItems: true,
      },
      defaultValues: {
        billingDetails: {
          name: options.nameOnCard,
        },
      },
      fields: {
        billingDetails: {
          name: 'auto',
          email: 'never',
          phone: 'never',
          address: 'never',
        },
      },
    })

.....


    const paymentIntentResponse = await instance.confirmPayment({
      elements: paymentElements,
      clientSecret: paymentData.paymentId,
      confirmParams: {
        return_url: window.location.href,
        payment_method_data: {
          billing_details: getBillingDetails(paymentData),
        },
      },
    })
#

And part of BE that it's called on form confirm but before confirmPayment on elements object:

    override fun startPaymentProcess(
        request: NewPaymentRequest
    ): Either<Throwable, StripeClientResponse> = Either.catch {
        logger.debug("Start payment process: {}", request)
        PaymentIntent.create(createCreateParameters(request), requestOptions)
    }

    private fun createCreateParameters(request: NewPaymentRequest): PaymentIntentCreateParams {
        val id = request.id.asPair()
        return PaymentIntentCreateParams.builder()
            .setAmount(request.amount.asSmallestUnit())
            .setCurrency(request.amount.currency.code())
            .setAutomaticPaymentMethods(automaticPaymentMethods())
            .setPaymentMethodConfiguration(paymentMethodConfigurationId)
            .build()
    }
dreamy void
#

So you never pass country to the element

hoary thicket
#

Ah yeah, it's our current state 0 where we found issue and couldn't resolve it.
Can you say where we can pass this country?

As I told we tried doing it like that on FE:

val elements = stripe.elements({
      // @ts-ignore this is not typed in @types/stripe-v3
      mode: 'payment',
      locale: 'en',
      currency: amount?.currency.toLowerCase(),
      paymentMethodConfiguration: options.paymentMethodConfigurationId,
      setupFutureUsage: options.setupFutureUsage,
      amount: Math.round((amount?.value || 0) * 100),
      appearance,
      loader: 'never',
      fonts: getFonts(theme),
      defaultValues: {
         address: {
           country: `PL`,
           ....
         }
      }
    })

but nothing changed

hoary thicket
#

Tried

      defaultValues: {
        billingDetails: {
          name: options.nameOnCard,
          address: {
            country: `PL`,
          }
        },
      },
#

Still CASH APP and Klarna are displayed

dreamy void
#

Hm ok. Let me ask a colleague

hoary thicket
#

I can see that this billingDetails.address.country is passed and used in elements correctly because it shows on some payment methods when we change fields.billingDetails.address.country = 'auto'

#

Also we tried to initialize intent on BE before initializing payment elements on FE but we couldn't find field for billingDetails :/

There is only shipping address but it doesn't work too (still invalid payment methods)

dreamy void
#

Ah ok so my colleague confirmed that there's not a way around this currently with the deferred intents flow you're using (creating payment intent after payment method)

#

You'd need to rely on our billing details collection input in the payment element

hoary thicket
#

We already tried other flow, but there is no space for billingDetails / country that will work too

#

We tried:

stripe payment_intents create --amount="2000" --currency="usd" -d "automatic_payment_methods[enabled]=true" -d "payment_method_data[billing_details][address][city]=Poznan" -d "payment_method_data[billing_details][address][country]=PL"

But it doesn't work because it require type

"Missing required param: payment_method_data[type]."
#

Shipping do not help too:

stripe payment_intents create --amount="2000" --currency="usd" -d "automatic_payment_methods[enabled]=true" -d "shipping[address][country]=PL" -d "shipping[address][city]=Poznan" 
fluid wigeonBOT
dreamy void
#

Try setting billing address on the customer