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 ponent 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 };
}
ponentDidMount() {
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.
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 ponent 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 };
}
ponentDidMount() {
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.
Share Improve this question edited Jan 30, 2018 at 11:02 Sachin Karia asked Jan 30, 2018 at 10:50 Sachin KariaSachin Karia 5652 gold badges10 silver badges23 bronze badges 5-
There's a missing
'
at the end of :this.props.stripe.createToken({email: '[email protected]
– Dyo Commented Jan 30, 2018 at 11:01 - thanks - updated (same error) – Sachin Karia Commented Jan 30, 2018 at 11:02
-
2
Don't know much about react-stripe but it seems you need to use the HOC
injectStripe(CheckoutForm)
instead of passing stripe directly inChekoutForm props
– Dyo Commented Jan 30, 2018 at 11:14 - In this case I've passed the stripe object through the props manually, i think the result is the same (stripe has been loaded and the functions are present when printed in the console. – Sachin Karia Commented Jan 30, 2018 at 11:16
-
It works fine for me when I use the
injectStripe
method. I attempted to do something similar to you because I am using Redux, but I could not get it to work. I went back to using stripe only in the ponent below anyconnect()
calls, but using the primary method in the readme github./stripe/react-stripe-elements#getting-started. – Sia Commented Mar 10, 2018 at 19:32
4 Answers
Reset to default 4It 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
};
}
ponentWillReceiveProps() {
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;
In the ments they rightly say you need to use the HOC injectStripe
.
The docs for stripe.createToken
mention that you need to pass the element you wish to tokenize data from.
Also from the github repo README:
⚠️ NOTE injectStripe cannot be used on the same element that renders the Elements ponent; it must be used on the child ponent of Elements. injectStripe returns a wrapped ponent that needs to sit under but above any code where you'd like to access this.props.stripe.
In my specif case I was using a Mobx store and I needed to handle createToken
and my form submission in the same place.
Even though I had a reference to stripe since initialisation it didn't work.
The createToken
call needs to e from a ponent child of Elements and with stripe injected.
I ended up having:
@inject('signupStore')
@observer
class CardInput extends React.Component {
ponentDidMount() {
const { signupStore } = this.props;
const handleCard = async name => {
return await this.props.stripe.createToken({ name: name });
};
signupStore.assignHandleCard(handleCard);
}
render() {
return (
<label>
Card details
<CardElement style={{ base: { fontSize: '18px' } }} />
</label>
);
}
}
export default injectStripe(CardInput);
Passing the handler back to the store, and then using it from there.
Part of signupStore
:
@action
async submitForm(formValues) {
if (this.stripe && this.handleCard) {
const tokenResponse = await this.handleCard(
`${formValues.firstName} ${formValues.lastName}`
);
runInAction(() => {
console.log('Card token received ', tokenResponse);
if (tokenResponse) {
this.cardToken = tokenResponse.token.id;
formValues.cardToken = this.cardToken;
}
});
const response = await request.signup.submit(formValues);
return response;
}
return null;
}
With the new @stripe/react-stripe-js library it's a bit different. We need to use ElementsConsumer ponent. Load stripe using loadStripe method and use Elements ponent to use your form with Stripe.
Here is a basic example.
import { Elements, loadStripe } from "@stripe/react-stripe-js"
const stripePromise = loadStripe(STRIPEKEY)
<Elements stripe={stripePromise}>
<CardForm />
</Elements>
CardForm.js
import {
CardNumberElement,
CardExpiryElement,
CardCvcElement,
ElementsConsumer,
} from "@stripe/react-stripe-js"
const StripeForm = ({ stripe, elements }) => {
const handleSubmit = async () => {
if (!stripe || !elements) {
return
}
const cardNumberElement = elements.getElement(CardNumberElement)
const res = await stripe.createToken(cardNumberElement)
}
return (
<form>
<div>
<label htmlFor="cardNumber">Card Number</label>
<div>
<CardNumberElement />
</div>
</div>
<div>
<label htmlFor="cardName">Card Name</label>
<input
type="text"
name="cardName"
required
placeholder="Please Enter"
pattern="[A-Za-z]"
/>
</div>
<div>
<label htmlFor="expDate">Exp. Date</label>
<div>
<CardExpiryElement />
</div>
</div>
<div>
<label htmlFor="CVC">CVC</label>
<div>
<CardCvcElement />
</div>
</div>
</form>
)
}
const CardForm = () => {
return (
<ElementsConsumer>
{({ stripe, elements }) => (
<StripeForm stripe={stripe} elements={elements} />
)}
</ElementsConsumer>
)
}
export default CardForm
React js it's working for me Card ponent , Get error , Card Detail and Generate Token
import React, { useState, useEffect } from "react";
import {loadStripe} from '@stripe/stripe-js';
import {CardElement,Elements,useStripe,useElements} from '@stripe/react-stripe-js';
const stripePromise = loadStripe('pk_test_YOUR_STRIPE_KYE');
const CheckoutForm = () => {
const stripe = useStripe();
const elements = useElements();
const handleSubmit = async (event) => {
event.preventDefault();
const {error, paymentMethod} = await stripe.createPaymentMethod({
type: 'card',
card: elements.getElement(CardElement),
});
console.log("paymentMethod",paymentMethod);
console.log("error", error);
if (paymentMethod) {
const cardElement = elements.getElement(CardElement);
let token = await stripe.createToken(cardElement);
console.log(token);
}
};
return (
<div>
<form onSubmit={ handleSubmit }>
<div className="login-box" id="step2" >
<div className="form-row">
<label for="card-element" style={ { color:" #76bbdf" } }>
Credit or debit card
</label>
</div>
<div >
<CardElement
className="StripeElement"
options={{
style: {
base: {
fontSize: '16px',
color: '#424770',
'::placeholder': {
color: '#aab7c4',
},
},
invalid: {
color: '#9e2146',
},
},
}}
/>
</div>
<button name="submintbtn2" className="btn btn-primary" > SUBSCRIBE </button>
</div>
</form>
</div>
)};
const Registration = () => (
<div>
<Elements stripe={stripePromise}>
<CheckoutForm />
</Elements>
</div>
);
export default Registration;
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1743576018a4473572.html
评论列表(0条)