#skoonovasupport

1 messages · Page 1 of 1 (latest)

cold terraceBOT
queen flame
#

Hello! Are you seeing a particular error? What is failing?

cinder shore
#

Hello! Thank you for the fast notice! I'm not very familiar with stripe very sorry to bother!

Here is my current integration:

  const handleSubmit = async (event: any) => {
    event.preventDefault();

    if (!stripe || !currentUser || !coach) return;

    setLoading(true);

    const coachUsername = coach.name.replace(' ', '-');
    const coachId = coach._id;
    const sessionId = session._id;

    const receipt_email = currentUser.email;
    const return_url = `${server}/coach/${coachUsername}/book-now/request?coachId=${coachId}&sessionId=${sessionId}&name=${coach.name}`;

    try {
      let stripeResponse;
      if (selectedCard) {
        console.log('Scenario 1: Using selected card for payment.');
        stripeResponse = await stripe.confirmCardPayment(clientSecret, {
          payment_method: selectedCard,
          receipt_email,
        });
      } else {
        console.log('Scenario 2/3: Confirming new payment.');
        if (!elements) return;
        stripeResponse = await stripe.confirmPayment({
          elements,
          confirmParams: { return_url, receipt_email },
          redirect: 'if_required',
        });
        if (saveCard) {
          console.log('Scenario 3: Creating and saving new payment method.');
          const paymentElement = elements.getElement(PaymentElement);
          if (!paymentElement) {
            console.log('Payment element not found!');
            return;
          }
          try {
            await stripe.createPaymentMethod({
              type: 'card',
              card: paymentElement, // Use paymentElement here instead of cardElement
              billing_details: { email: receipt_email },
            });
          } catch (error) {
            console.log('Error creating payment method:', error);
            return; // or handle error as needed
          }
        }
        console.log('Stripe response after payment method creation:', stripeResponse);
      }

      if (stripeResponse.error) {
        console.log('Payment error:', stripeResponse.error.message!);
        setMessage(stripeResponse.error.message!);
        throw stripeResponse.error;
      }
      if (stripeResponse.paymentIntent?.status === 'requires_capture') {
        console.log('Redirecting...');
        const paymentIntentId = stripeResponse.paymentIntent.id;
        const clientSecret = stripeResponse.paymentIntent.client_secret;
        const redirectUrl = `${return_url}&payment_intent=${paymentIntentId}&payment_intent_client_secret=${clientSecret}`;
        window.location.href = redirectUrl;
      }
    } catch (err) {
      console.log('Caught error:', getMessage(err));
      setMessage(getMessage(err));
      setLoading(false);
    }
  };
```
#

I'm having an issue with the third scenario "if (saveCard)"

#

This is what chat gpt tells me from the long error I get:
The error message is indicating that the argument you're providing to stripe.createPaymentMethod does not match any of the expected overloads. This could be happening because the paymentElement is not of the expected types (StripeCardElement, StripeCardNumberElement, or { token: string; }), or because the argument structure is incorrect.

pastel wind
#

Can you share the error message?

cinder shore
#

Yes, here it is:

No overload matches this call.
  Overload 1 of 3, '(paymentMethodData: CreatePaymentMethodData): Promise<PaymentMethodResult>', gave the following error.
    Argument of type '{ type: "card"; card: StripeElement; billing_details: { email: string; }; }' is not assignable to parameter of type 'CreatePaymentMethodData'.
      Types of property 'card' are incompatible.
        Type 'StripeElement' is not assignable to type 'StripeCardElement | StripeCardNumberElement | { token: string; } | undefined'.
          Type 'StripeAddressElement' is not assignable to type 'StripeCardElement | StripeCardNumberElement | { token: string; } | undefined'.
            Type 'StripeAddressElement' is not assignable to type 'StripeCardNumberElement'.
              Type 'StripeAddressElement' is not assignable to type '{ on(eventType: "change", handler: (event: StripeCardNumberElementChangeEvent) => any): StripeCardNumberElement; on(eventType: "ready", handler: (event: { ...; }) => any): StripeCardNumberElement; on(eventType: "focus", handler: (event: { ...; }) => any): StripeCardNumberElement; on(eventType: "blur", handler: (even...'.
                Types of property 'on' are incompatible.
                  Type '{ (eventType: "change", handler: (event: StripeAddressElementChangeEvent) => any): StripeAddressElement; (eventType: "ready", handler: (event: { ...; }) => any): StripeAddressElement; (eventType: "focus", handler: (event: { ...; }) => any): StripeAddressElement; (eventType: "blur", handler: (event: { ...; }) => any)...' is not assignable to type '{ (eventType: "change", handler: (event: StripeCardNumberElementChangeEvent) => any): StripeCardNumberElement; (eventType: "ready", handler: (event: { ...; }) => any): StripeCardNumberElement; (eventType: "focus", handler: (event: { ...; }) => any): StripeCardNumberElement; (eventType: "blur", handler: (event: { ......'.
                    Types of parameters 'handler' and 'handler' are incompatible.
                      Types of parameters 'event' and 'event' are incompatible.
                        Type 'StripeAddressElementChangeEvent' is missing the following properties from type 'StripeCardNumberElementChangeEvent': brand, error
  Overload 2 of 3, '(options: CreatePaymentMethodFromElements): Promise<PaymentMethodResult>', gave the following error.
    Argument of type '{ type: string; card: StripeElement; billing_details: { email: string; }; }' is not assignable to parameter of type 'CreatePaymentMethodFromElements'.
      Object literal may only specify known properties, and 'type' does not exist in type 'CreatePaymentMethodFromElements'.
  Overload 3 of 3, '(options: CreatePaymentMethodFromElement): Promise<PaymentMethodResult>', gave the following error.
    Argument of type '{ type: string; card: StripeElement; billing_details: { email: string; }; }' is not assignable to parameter of type 'CreatePaymentMethodFromElement'.
      Object literal may only specify known properties, and 'type' does not exist in type 'CreatePaymentMethodFromElement'.
#

Here is my current funnel:

  1. Payment intent is created (before the payment modal opens)
  2. User opens the payment modal > Tries to fetch payment methods from customerID
  3. If no payment methods are found, show the payment element, otherwise show the saved credit cards with a button to add a new card (show payment element)
  4. User enters card details and can now decide to save or not his card
  5. User clicks proceed > triggers handle submit
pastel wind
#

It looks like there is type mismatch here. How are you creating the elements?

cinder shore
#

Like so I believe: const elements = useElements();

#

and then
{showPaymentElement ? (
<div className="mt-4 mb-4">
<PaymentElement id="payment-element" />
</div>
) : (
<div>
<h2 className="font-medium text-base">Select saved cards</h2>
</div>
)}

#

and like this sorry:
<Elements stripe={stripePromise} options={options as any}>
<CheckoutForm {...{ coach, clientSecret, session }} />
</Elements>

#

My application is quite complex and I'm not very experienced, very sorry

pastel wind
#

Okie taking a step back. I see you are using both method
stripe.confirmCardPayment
and
stripe.confirmPayment

This doesn't work because they belongs to 2 different type of Elements. The former is the legacy Card Elements, while the latter is the newer PaymentElements

#

Any Doc you have been following?

cinder shore
#

I see, I'm not sure of what to tell you, the scenario one does seem to work when a customer has a card like so:

#

clicking proceed does pass all the checks, same for the scenario 2 where a customer can use a new card but not save it, the issue seems to be happening on the third scenario, when the user wants to use a new card and also save it for future payments

#

For the third scenario, here is the console log: "Error creating payment method: IntegrationError: Invalid value for createPaymentMethod: card was payment Element, which cannot be used to create card PaymentMethods."

pastel wind
#

Let's focus on the code. The error you received is from this block

            await stripe.createPaymentMethod({
              type: 'card',
              card: paymentElement, // Use paymentElement here instead of cardElement
              billing_details: { email: receipt_email },
            });

As the error stated, you can't pass paymentElement here, because card expects either a card or a cardNumber Element

#

I would recommend taking a step back and write down each scenario, and making sure you don't mix up multiple type of Elements