stripe / react-stripe-js

React components for Stripe.js and Stripe Elements
https://stripe.com/docs/stripe-js/react
MIT License
1.75k stars 267 forks source link

[BUG]: Stripe.confirmSetup promise when set with `billingDetails: "never"` does not resolve #469

Closed pavlos163 closed 7 months ago

pavlos163 commented 8 months ago

What happened?

I am using Payment Elements to allow users to set up new payment methods without paying.

My react component is the following:

// ...imports...

export type PropsType = {
  stripe: Stripe;
  elements: StripeElements;
  ...
};

class StripeAddNewCardForm extends React.Component<PropsType> {
  private _handleSubmit = async () => {
    const { stripe, elements, ... } = this.props;

    if (elements == null || !stripe) {
      return;
    }

    const { error: submitError } = await elements.submit();
    if (submitError) {
      return;
    }

    // This is my API call that creates a setup intent and gives me back the client secret
    const res = await axios.post("/investor/payment-methods/initiate-stripe");

    const { error } = await stripe.confirmSetup({
      elements,
      clientSecret: res.data.clientSecret,
      confirmParams: {
        return_url: "https://some-url-in-my-website'
      }
    });

    if (error) {
      ...
    }
  };

  render() {
    const { stripe, elements } = this.props;

    return (
      <>
        <PaymentElement options={{ terms: { card: "never" } }} />
        <CustomButton
          disabled={!stripe || !elements}
          customonclick={async () => this._handleSubmit()}
        >
          Add card
        </CustomButton>
      </>
    );
  }
}

export default StripeAddNewCardForm;

The above works correctly! i.e. when I click on the button, the _handleSubmit runs, calls my API which returns the client secret, calls Stripe to confirm the setup, and finishes without error.

However, this stop working when I update <PaymentElement options={{ terms: { card: "never" } }} /> to <PaymentElement options={{ terms: { card: "never" }, fields: { billingDetails: "never" } }} />, or <PaymentElement options={{ terms: { card: "never" }, fields: { billingDetails: { address: "never" } } }} />.

What happens if I do that, is that my code correctly reaches the stripe.confirmSetup line, but that promise never resolves. i.e. if I console.log something directly above and below the stripe.confirmSetup, only the log above shows up. In addition to that, I can see in the Stripe dashboard that the Stripe intent never actually gets confirmed. This ONLY happens with the added props in PaymentElement.

Environment

No response

Reproduction

No response

stale[bot] commented 7 months ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.