2017-01-06 43 views
8

Tôi đang cố gắng hiển thị biểu mẫu thanh toán mặc định sọc trong ứng dụng React js.React js Thanh toán sọc không hoạt động

<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> 

Nó không hiển thị bất kỳ thứ gì và cũng không nhận được lỗi. Làm thế nào để tôi nhận được nút và biểu mẫu thanh toán đó.

+1

Sử dụng các plugin hỗ trợ 'phản ứng 'như https://www.npmjs.com/package/react-stripe-checkout –

Trả lời

7

Vấn đề chính bạn có thể đang tải tập lệnh trong React.

Một cách tiếp cận là chỉ tải tập lệnh thanh toán khi cần (giả định một số dạng spa), sau đó chỉ cần gọi trực tiếp. Điều này tương tự như phiên bản "tùy chỉnh" trên trang tài liệu: https://stripe.com/docs/checkout#integration-custom

Nếu bạn đang tải checkout.js (ví dụ trước "app.js"), thì bên dưới có thể được đơn giản hóa một chút theo cách thủ công tải trong kịch bản.

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

Câu trả lời của Chris là tuyệt vời, tuy nhiên tôi phải thực hiện một vài thay đổi nhỏ để mã hoạt động. Tôi cũng đã loại bỏ các loại hàm TypeScript (đối với những người không sử dụng TypeScript). Các bình luận được thêm vào khi các thay đổi đối với câu trả lời đã được thực hiện. FYI đây là bài viết đầu tiên của tôi, xin vui lòng cho tôi biết nếu điều này nên là một bình luận thay vì một câu trả lời.

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

Đó chính xác là những gì tôi cần! cảm ơn rất nhiều. Bằng cách này, bạn nên xác nhận câu trả lời để làm cho bài đăng được giải quyết – ekqnp

+0

cảm ơn bạn đã chia sẻ bài đăng này! –

Các vấn đề liên quan