Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

react-stripe-elements Error: You must provide a Stripe Element or a valid token type to create a Token

I am using react-stripe-elements to create a token for payments. However, according to the documentation when the card form is wrapped in the Elements component it should automatically pickup which stripe elements to tokenize.

However, in this case we are presented with the error

You must provide a Stripe Element or a valid token type to create a Token.

Here is the code:

import React from 'react';
import {CardCVCElement, CardExpiryElement, CardNumberElement, PostalCodeElement, StripeProvider, Elements} from 'react-stripe-elements';

class CheckoutForm extends React.Component {
  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleSubmit(ev) {
    ev.preventDefault();

    this.props.stripe.createToken({email: '[email protected]'}).then(({token }) => {console.log('Received Stripe token:', token)});
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Card details
          <CardNumberElement />
          <CardExpiryElement />
          <CardCVCElement />
          <PostalCodeElement />
        </label>
        <button>Confirm order</button>
      </form>
    );
  }
}


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

  componentDidMount() {
    this.setState({ stripe: window.Stripe('test_key') });
  }

  render() {
    return (
      <StripeProvider stripe={this.state.stripe}>
        <Elements>
          <CheckoutForm stripe={this.state.stripe} />
        </Elements>
      </StripeProvider>
    );
  }
}

export default App;

According to the documentation the following should be true:

'Within the context of Elements, this call to createToken knows which Element to tokenize, since there's only one in this group.'

However, this doesn't seem to be the case. I have also tried using the single 'Card Element' and have not found any success in doing so.

like image 228
Sachin Karia Avatar asked Jan 30 '18 10:01

Sachin Karia


People also ask

What is a Stripe element?

Stripe Elements is a set of prebuilt UI components for building your web checkout flow. It's available as a feature of Stripe. js, our foundational JavaScript library for building payment flows. Stripe. js tokenizes sensitive payment details within an Element without ever having them touch your server.

What is Stripe createToken?

Use stripe. createToken to convert information collected by card elements into a single-use Token that you safely pass to your server to use in an API call.

How do you add a Stripe in react?

The Elements provider allows you to use Element components and access the Stripe object in any nested component. Render an Elements provider at the root of your React app so that it is available everywhere you need it. To use the Elements provider, call loadStripe from @stripe/stripe-js with your publishable key.


1 Answers

It turns out I never managed to solve the issue using react-stripe-elements. I ended using the standard JS version (from the stripe documentation). Here is my current working solution:

import React from 'react';

class CheckoutForm extends React.Component {
  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);

    this.state = {
      elements: null,
      card: null
    };
  }

  componentWillReceiveProps() {
    this.setState({ elements: this.props.stripe.elements() }, () => {
      this.setState({ card: this.state.elements.create('card') }, () => {
        this.state.card.mount('#card-element');
      });
    });
  }

  handleSubmit(ev) {
    ev.preventDefault();
    this.props.stripe.createToken(this.state.card).then((token) => {
      console.log('Received Stripe token:', token);
    });
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <div className="row">
          <label >
            Credit or debit card
          </label>
          <div id="card-element"/>
          <div id="card-errors" role="alert"/>
        </div>
        <button>Submit Payment</button>
      </form>
    );
  }
}

class App extends React.Component {
  constructor() {
    super();
    this.state = {stripe: window.Stripe('test_key')};
  }

  render() {
    return (
      <CheckoutForm stripe={this.state.stripe}/>
    );
  }
}

export default App;
like image 65
Sachin Karia Avatar answered Nov 05 '22 18:11

Sachin Karia