React js Stripe checkout无效

时间:2017-01-06 06:24:32

标签: javascript node.js reactjs stripe-payments

我正在尝试在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 个答案:

答案 0 :(得分:10)

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

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

如果您已经加载checkout.js(例如在您的&#34; app.js&#34;之前),则可以通过不在脚本中手动加载来简化以下内容。

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

答案 1 :(得分:8)

克里斯的回答非常好,但我必须做一些小改动才能使代码正常运行。我还删除了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>
        );
    }
}