Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Please pass either 'apiKey' or 'stripe' to StripeProvider

I've previously had this working just fine, but I am now stumped as to what is going on. I'm using Next.js for SSR and my Pay element looks like so:

class Pay extends React.Component {
  constructor() {
    super();
    this.state = { stripe: null };
  }

  componentDidMount() {
    console.log(window.Stripe)
    this.setState({
      stripe: window.Stripe('pk_test_123'),
    });
  }

  render() {
    console.log(this.state)
    return (
      <StripeProvider apiKey={this.state.stripe}>
        <Elements>
          <InjectedCheckoutForm />
        </Elements>
      </StripeProvider>
    );
  }
}

The above throws the error:

Please pass either 'apiKey' or 'stripe' to StripeProvider. If you're using 'stripe' but don't have a Stripe instance yet, pass 'null' explicitly.

What I'm confused about here though is, as it is, window, nor the state are logged as the page throws a 500 error. If I remove the StripeProvider component, window.Stripe logs out fine, and this.state contains my Stripe state so I can't understand why its throwing the error.

like image 842
K20GH Avatar asked Apr 11 '18 21:04

K20GH


1 Answers

Why you're getting the error

<StripeProvider /> wants the apiKey or stripe prop on the initial render as shown by the error.

On your initial render, state.stripe is null, and so subsequently <StripeProvider apiKey=null>. This raises the 500 error because only StripeProvider's this.props.stripe is null-checked so that it can understand there are some asynchronous things going on on the consumer's side.

https://github.com/stripe/react-stripe-elements/blob/master/src/components/Provider.js#L105

this.props.apiKey being null leads you to your error because apiKey is not treated the same way. https://github.com/stripe/react-stripe-elements/blob/master/src/components/Provider.js#L110

Solution

I think the problem though is that you're just using the wrong property. Switch from StripeProvider.apiKey to StripeProvider.stripe. apiKey takes in a string type while stripe takes in a StripeObject (which is also what your window.Stripe() returns).

  <StripeProvider stripe={this.state.stripe}>
    <Elements>
      <InjectedCheckoutForm />
    </Elements>
  </StripeProvider>

Observe the code examples at https://github.com/stripe/react-stripe-elements#loading-stripejs-asynchronously and https://github.com/stripe/react-stripe-elements#server-side-rendering-ssr for more information.

Sandbox: https://codesandbox.io/s/x2r1pxwjqz

Try changing stripe -> apiKey to see the error pop up.

like image 140
Chau Avatar answered Oct 28 '22 21:10

Chau