stripe-archive / react-stripe-elements

Moved to stripe/react-stripe-js.
https://github.com/stripe/react-stripe-js
MIT License
3.03k stars 319 forks source link

Integration Error: For the paymentRequestButton Element, you must first check availability using paymentRequest.canMakePayment() before mounting the Element. #456

Closed prabir-vora closed 4 years ago

prabir-vora commented 4 years ago

Summary

Getting "Integration Error: For the paymentRequestButton Element, you must first check availability using paymentRequest.canMakePayment() before mounting the Element." This is despite checking for canMakePayment() in render method and returning null in conditional if false. By console.log() I could detect the error arises as soon as canMakePayment return true in the form {applePay: true}

The reason I'm passing the paymentRequest as a prop is because my orderTotal is subject to change, which I can't account for if my paymentRequest is created in the constructor of the child element.

Here is my code summary and snippets:

I'm passing the paymentRequest object as a prop to the PaymentRequestButton component:

Code in Parent Component:

renderPaymentRequestButton = () => {
    const paymentRequest = this.props.stripe.paymentRequest({
      country: 'US',
      currency: 'usd',
      total: {
        label: 'Order Total',
        amount: (this.onCalculateTotalAmount()),
      },
    }); 
    paymentRequest.on('paymentmethod', async event => {
      await this.onCreateChargeWithPaymentRequest(businessFieldID, event,   this.onCalculateTotalAmount());  
    })
    return (
      <Elements>
        <PaymentRequestButtonStripe 
          paymentRequest={paymentRequest}
          totalAmount={this.onCalculateTotalAmount( )}
          onCreateChargeWithPaymentRequest={this.onCreateChargeWithPaymentRequest}

        />
      </Elements>
    );
  }

Code in Child (PaymentRequestButtonStripe):

class PaymentRequestButtonStripe extends React.Component {

  constructor(props) {
    super(props);
    this.state = { canMakePayment: {applePay: false}, loading: true }

    props.paymentRequest.canMakePayment().then(result => {
      this.setState({ canMakePayment: result, loading: false })
    })
  }

  render() {

    const { canMakePayment, loading } = this.state;
    const { applePay = false } = canMakePayment;
    const showButton = (applePay ) && !loading ; 

    if (!showButton) return null;
    return (
      <PaymentRequestButtonElement
        paymentRequest={this.props.paymentRequest}
        className="PaymentRequestButton"
        style={{
          // For more details on how to style the Payment Request Button, see:
          // https://stripe.com/docs/elements/payment-request-button#styling-the-element
          paymentRequestButton: {
            theme: 'light',
            height: '64px',
          },
        }}
      />
    );
  } 

}

export default injectStripe(PaymentRequestButtonStripe);

Other information

Screen Shot 2019-11-07 at 12 50 00 PM

Safari

tylerwray commented 4 years ago

Can you provide any info as to why this issue was closed? I'm getting the same error reported in production and I can't reproduce it.