Skip to content

js_primitives.dart:28 Unexpected null value. (Web) #2160

Open
@ChurikiTenna

Description

@ChurikiTenna

Describe the bug
It throws error on:

var intent = await Stripe.instance.confirmPayment(
          paymentIntentClientSecret: clientSecret,
          data: PaymentMethodParams.card(
            paymentMethodData: PaymentMethodData(
              billingDetails: BillingDetails(
                email: CachedForEnduser.enduser.email,
                name: CachedForEnduser.enduser.fullName,
              ),
            ),
          ),
        );

clientSecret, email, name field exist, and not empty.

Then I tried fulling every fields, which I confirmed not null. Still throws the same error.

var intent = await Stripe.instance.confirmPayment(
          paymentIntentClientSecret: clientSecret,
          data: PaymentMethodParams.card(
            paymentMethodData: PaymentMethodData(
              billingDetails: BillingDetails(
                email: CachedForEnduser.enduser.email,
                name: CachedForEnduser.enduser.fullName,
                phone: CachedForEnduser.enduser.phoneNumber,
                address: addr,
              ),
              shippingDetails: ShippingDetails(address: addr),
              metadata: {},
         
            ),
          ),
        );

The clientSecret comes from:

const paymentIntent = await stripe.paymentIntents.create({
        customer: stripeCustomerId,
        amount,
        currency,
        payment_method: defaultPaymentMethodId,
        confirm: false,
        on_behalf_of: gymStripeExpressData.stripeAccountId,
        application_fee_amount: getTransactionFee(currency, gymType) + (amount * s_percentage) | 0,
        transfer_data: {
          destination: gymStripeExpressData.stripeAccountId,
        },
        statement_descriptor_suffix: sanitizeDescriptor(gym.businessName),
        receipt_email: email
      });

      // Firestoreに保存
      admin.firestore().collection('purchaseds').add({
        createdAt: Timestamp.now(),
        paymentIntentId: paymentIntent.id,
        ...product,
      })

      console.log('paymentIntent', paymentIntent)

      return {
        success: true,
        paymentStatus: paymentIntent.status,
        clientSecret: paymentIntent.client_secret <- here
      };

paymentIntent as below:

next_action is null, but I see "status": "requires_payment_method" on stripe dashboard.

id: 'pi_3RUmerCxca5HrpDY0QdTpVun',
object: 'payment_intent',
amount: 100,
amount_capturable: 0,
amount_details: { tip: {} },
amount_received: 0,
application: null,
application_fee_amount: 93,
automatic_payment_methods: { allow_redirects: 'always', enabled: true },
canceled_at: null,
cancellation_reason: null,
capture_method: 'automatic_async',
client_secret: 'pi_',
confirmation_method: 'automatic',
created: 1748687337,
currency: 'jpy',
customer: 'cus_
',
description: null,
last_payment_error: null,
latest_charge: null,
livemode: true,
metadata: {},
next_action: null,
on_behalf_of: 'acct_',
payment_method: 'pm_
',
payment_method_configuration_details: {
id: 'pmc_',
parent: 'pmc_
'
},
payment_method_options: {
card: {
installments: [Object],
mandate_options: null,
network: null,
request_three_d_secure: 'automatic'
}
},

Resent status of the intent is shown as 'requires_confirmation' in stripe dashboard.

I tried both confirm: true and confirm: false.

CardField is as below:

const CardField(
                enablePostalCode: false,
                decoration: InputDecoration(
                  enabledBorder: OutlineInputBorder(
                    borderSide: BorderSide(color: Colors.transparent),
                  ),
                  focusedBorder: OutlineInputBorder(
                    borderSide: BorderSide(color: Colors.transparent),
                  ),
                ),
              ),

When I try in iOS app, it throws:

StripeException(error: LocalizedErrorMessage(code: FailureCode.Failed, localizedMessage: Card details not complete, message: Card details not complete, stripeErrorCode: null, declineCode: null, type: null))

After dozens of trial, it showed country is empty error, so I filled the country field.

Now, it is throwing
StripeException(error: LocalizedErrorMessage(code: FailureCode.Failed, localizedMessage: We are unable to authenticate your payment method. Please choose a different payment method and try again., message: We are unable to authenticate your payment method. Please choose a different payment method and try again., stripeErrorCode: null, declineCode: null, type: null))

after a few minute, the error message changes to:
Card detail is not complete.

On the web version
It still shows
In Safari: Null check operator used on a null value
In Chrome: 'Unexpected null value'

After a few more changes,
I have implemented the paymentIntents.confirm to the server side, and call the Stripe.instance.handleNextAction(clientSecret); on the flutter side if not complete.
Then, handleNextAction shows:

  • Web:
    The PaymentIntent supplied does not require manual server-side confirmation. Please use confirmCardPayment instead to complete the payment.
    But there is not such a method: confirmCardPayment in Stripe.
    If I try to do Stripe.instance.confirmPayment,
    Unexpected null value. <- never know where.

  • iOS:
    It shows visa multi-step verification-like page, but end up failing with We are unable to authenticate your payment method..

To Reproduce
Run the code above

Expected behavior
Confirm the payment

Smartphone / tablet

  • Device: Chrome
  • OS: Mac OS
  • Package version: 11.5.0
  • Flutter version 3.7.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions