首页 文章

React js Stripe checkout无效

提问于
浏览
10

我试图在React js应用程序中呈现条带检出默认表单 .

<form action="/your-server-side-code" method="POST">
  <script
    src="https://checkout.stripe.com/checkout.js" className="stripe-button"
    data-key="pk_test_oDALA0jNyxDzbRz5RstV4qOr"
    data-amount="999"
    data-name="test"
    data-description="Widget"
    data-image="https://stripe.com/img/documentation/checkout/marketplace.png"
    data-locale="auto">
  </script>
</form>

它没有显示任何东西,也没有出错 . 我如何获得付款按钮和表单 .

2 回答

  • 8

    您可能遇到的主要问题是在React中加载脚本 .

    一种方法是仅在需要时加载结帐脚本(假设某种形式的spa),然后直接调用它 . 这类似于文档页面上的"custom"版本:https://stripe.com/docs/checkout#integration-custom

    如果您已经加载了checkout.js(例如在“app.js”之前),则可以通过不在脚本中手动加载来简化以下内容 .

    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>
            );
        }
    }
    
  • 9

    克里斯的答案非常好,但我必须做一些小的改动才能使代码正常运行 . 我还删除了TypeScript函数类型(对于我们这些不使用TypeScript的人) . 如果对答案进行了更改,则会添加注释 . 仅供参考,这是我的第一篇文章,如果这应该是评论而不是答案,请告诉我 .

    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>
            );
        }
    }
    

相关问题