React js Stripe checkout is not working

后端 未结 2 683
花落未央
花落未央 2021-02-13 19:59

I am trying to render a stripe checkout default form in React js application.

相关标签:
2条回答
  • 2021-02-13 20:29

    Chris's answer was excellent, however I had to make a few minor changes in order for the code to function. I've also removed the TypeScript function types (for those of us not using TypeScript). Comments are added where changes to the answer have been made. FYI this is my first post, please let me know if this should be a Comment instead of an Answer.

    export default class Cards extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                loading: true,
                stripeLoading: true,
            };
            // onStripeUpdate must be bound or else clicking on button will produce error.
            this.onStripeUpdate = this.onStripeUpdate.bind(this);
            // binding loadStripe as a best practice, not doing so does not seem to cause error.
            this.loadStripe = this.loadStripe.bind(this);
        }
    
        loadStripe(onload) {
            if(! window.StripeCheckout) {
                const script = document.createElement('script');
                script.onload = function () {
                    console.info("Stripe script loaded");
                    onload();
                };
                script.src = 'https://checkout.stripe.com/checkout.js';
                document.head.appendChild(script);
            } else {
                onload();
            }
        }
    
        componentDidMount() {
    
            this.loadStripe(() => {
                this.stripeHandler = window.StripeCheckout.configure({
                    key: 'pk_test_xxxxxxxxxxxxxxxxxxxxxxxx',
                    image: 'https://stripe.com/img/documentation/checkout/marketplace.png',
                    locale: 'auto',
                    token: (token) => {
                        this.setState({ loading: true });
                        // use fetch or some other AJAX library here if you dont want to use axios
                        axios.post('/your-server-side-code', {
                            stripeToken: token.id,
                        });
                    }
                });
    
                this.setState({
                    stripeLoading: false,
                    // loading needs to be explicitly set false so component will render in 'loaded' state.
                    loading: false,
                });
            });
        }
    
        componentWillUnmount() {
            if(this.stripeHandler) {
                this.stripeHandler.close();
            }
        }
    
        onStripeUpdate(e) {
            this.stripeHandler.open({
                name: 'test',
                description: 'widget',
                panelLabel: 'Update Credit Card',
                allowRememberMe: false,
            });
            e.preventDefault();
        }
    
        render() {
            const { stripeLoading, loading } = this.state;
            return (
                <div>
                    {(loading || stripeLoading)
                        ? <p>loading..</p>
                        : <button onClick={this.onStripeUpdate}>Add CC</button>
                    }
                </div>
            );
        }
    }
    
    0 讨论(0)
  • 2021-02-13 20:45

    The main issue you are probably having is loading a script within React.

    One approach is to load the checkout script only when needed (assuming some form of spa), then just directly call it. This is akin to the "custom" version on the documentation page: https://stripe.com/docs/checkout#integration-custom

    If you are already loading checkout.js (for example before your "app.js"), then the below can be simplified a bit by not manually loading in the script.

    import React from 'react';
    
    export default class Cards extends React.Component {
    
        constructor(props:Object) {
            super(props);
            this.state = {
                loading: true,
                stripeLoading: true,
            };
        }
    
        loadStripe(onload:Function) {
            if(! window.StripeCheckout) {
                const script = document.createElement('script');
                script.onload = function () {
                    console.info("Stripe script loaded");
                    onload();
                };
                script.src = 'https://checkout.stripe.com/checkout.js';
                document.head.appendChild(script);
            } else {
                onload();
            }
        }
    
        componentDidMount() {
    
            this.loadStripe(() => {
                this.stripehandler = window.StripeCheckout.configure({
                    key: 'pk_test_xxxxxxxxxxxxxxxxxxxxxxxx',
                    image: 'https://stripe.com/img/documentation/checkout/marketplace.png',
                    locale: 'auto',
                    token: (token) => {
                        this.setState({ loading: true });
                        axios.post('/your-server-side-code', {
                            stripeToken: token.id,
                        });
                    }
                });
    
                this.setState({
                    stripeLoading: false
                });
            });
        }
    
        componentWillUnmount() {
            if(this.stripehandler) {
                this.stripehandler.close();
            }
        }
    
        onStripeUpdate(e:Object) {
            this.stripehandler.open({
                name: 'test',
                description: 'widget',
                panelLabel: 'Update Credit Card',
                allowRememberMe: false,
            });
            e.preventDefault();
        }
    
        render() {
            const { stripeLoading, loading } = this.state;
            return (
                <div>
                    {(loading || stripeLoading)
                        ? <p>loading..</p>
                        : <button onClick={this.onStripeUpdate}>Add CC</button>
                    }
                </div>
            );
        }
    }
    
    0 讨论(0)
提交回复
热议问题