【问题标题】:Is there a way to put a paypal script tag inside a button using reactjs?有没有办法使用 reactjs 将贝宝脚本标签放在按钮内?
【发布时间】:2019-08-13 01:30:19
【问题描述】:

我正在为 PayPal 小部件实现智能按钮,我想知道如何去做。我现在的想法是制作一个按钮,看看我是否可以在其中放置一个脚本标签,以引导我付款。到目前为止,这是我的代码:

这是来自 index.js 文件

<button>Donate Here Plz</button>

这是在我加入项目之前已经编写好的 reactjs 文件。

import ReactDOM from "react-dom";
import scriptLoader from "react-async-script-loader";

class PaypalButton extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      showButton: false,
      price: 1.0,
      priceError: true
    };

    window.React = React;
    window.ReactDOM = ReactDOM;
  }

  componentDidMount() {
    const { isScriptLoaded, isScriptLoadSucceed } = this.props;

    if (isScriptLoaded && isScriptLoadSucceed) {
      this.setState({ showButton: true });
    }
  }

  handleInputChange = e => {
    const re = /^\d*\.?\d{0,2}$/;

    if (e.target.value === "" || re.test(e.target.value)) {
      this.setState({ price: e.target.value });
    }
    if (this.state.price >= 1) {
      this.state.priceError = false;
    } else {
      this.state.priceError = true;
    }
    console.log(this.state.priceError);
  };

  componentWillReceiveProps(nextProps) {
    const { isScriptLoaded, isScriptLoadSucceed } = nextProps;

    const isLoadedButWasntLoadedBefore =
      !this.state.showButton && !this.props.isScriptLoaded && isScriptLoaded;

    if (isLoadedButWasntLoadedBefore) {
      if (isScriptLoadSucceed) {
        this.setState({ showButton: true });
      }
    }
  }

  render() {
    const paypal = window.PAYPAL;
    const {
      currency,
      env,
      commit,
      client,
      onSuccess,
      onError,
      onCancel
    } = this.props;

    const { showButton, price } = this.state;

    const payment = () =>
      paypal.rest.payment.create(env, client, {
        transactions: [
          {
            amount: {
              total: price,
              currency
            }
          }
        ]
      });

    const onAuthorize = (data, actions) =>
      actions.payment.execute().then(() => {
        const payment = {
          paid: true,
          cancelled: false,
          payerID: data.payerID,
          paymentID: data.paymentID,
          paymentToken: data.paymentToken,
          returnUrl: data.returnUrl
        };

        onSuccess(payment);
      });

    const style = {
      layout: "vertical", // horizontal | vertical
      size: "medium", // medium | large | responsive
      shape: "rect", // pill | rect
      color: "gold" // gold | blue | silver | white | black
    };

    return (
      <React.Fragment>
        <form>
          <h3 style={{ justifySelf: "center" }}>Donate Amount</h3>
          <input
            name="donate"
            type="text"
            placeholder="Minimum $1.00"
            value={this.state.price}
            onChange={this.handleInputChange}
            className="donationInput"
          />
        </form>

        <br />
        {showButton && (
          <paypal.Button.react
            style={style}
            env={env}
            client={client}
            commit={commit}
            payment={payment}
            onAuthorize={onAuthorize}
            onCancel={onCancel}
            onError={onError}
          />
        )}
      </React.Fragment>
    );
  }
}

export default scriptLoader("https://www.paypalobjects.com/api/checkout.js")(
  PaypalButton
);```

No error messages show up, but the button does not lead to anything.

【问题讨论】:

    标签: reactjs api paypal


    【解决方案1】:

    在我看来,您正在尝试使用降价版本的结帐 API。有一个新版本 V2 你可以在这里查看Paypal Checkout Buttons

    如果您需要新的 V2 按钮的 npm 包,可以在此处查看 NPM react-paypal-button-v2

    也就是说,您可以执行以下操作,这些操作取自此处 react-paypal-button-v2 github 的 npm 包 github,但没有打字稿和功能组件形式:

    import React, { useState, useEffect} from 'react';
    import ReactDOM from 'react-dom';
    
    const PaypalButton = props => {
      const [sdkReady, setSdkReady] = useState(false);
    
      const addPaypalSdk = () => {
        const clientID =
          'Your-Paypal-Client-ID';
        const script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = `https://www.paypal.com/sdk/js?client-id=${clientID}`;
        script.async = true;
        script.onload = () => {
          setSdkReady(true);
        };
        script.onerror = () => {
          throw new Error('Paypal SDK could not be loaded.');
        };
    
        document.body.appendChild(script);
      };
    
      useEffect(() => {
        if (window !== undefined && window.paypal === undefined) {
          addPaypalSdk();
        } else if (
          window !== undefined &&
          window.paypal !== undefined &&
          props.onButtonReady
        ) {
          props.onButtonReady();
        }
        // eslint-disable-next-line react-hooks/exhaustive-deps
      }, []);
    
    
      //amount goes in the value field we will use props of the button for this   
      const createOrder = (data, actions) => {
        return actions.order.create({
          purchase_units: [
            {
              amount: {
                currency_code: 'USD',
                value: props.amount,
              }
            }
          ]
        });
      };
    
      const onApprove = (data, actions) => {
        return actions.order
          .capture()
          .then(details => {
            if (props.onSuccess) {
              return props.onSuccess(data);
            }
          })
          .catch(err => {
            console.log(err)
          });
      };
    
      if (!sdkReady && window.paypal === undefined) {
        return (
          <div>Loading...</div>
        );
      }
    
      const Button = window.paypal.Buttons.driver('react', {
        React,
        ReactDOM
      });
    
      //you can set your style to whatever read the documentation for different styles I have put some examples in the style tag
      return (
        <Button
          {...props}
          createOrder={
            amount && !createOrder
              ? (data, actions) => createOrder(data, actions)
              : (data, actions) => createOrder(data, actions)
          }
          onApprove={
            onSuccess
              ? (data, actions) => onApprove(data, actions)
              : (data, actions) => onApprove(data, actions)
          }
          style={{
            layout: 'vertical',
            color: 'blue',
            shape: 'rect',
            label: 'paypal'
          }}
        />
      );
    };
    
    export default PaypalButton;
    

    然后你可以像这样在你的组件中使用它:

    const onSuccess = payment => {
      console.log(payment)
    }
    
    const onCancel = data => {
      console.log(data)
    };
    
    const onError = err => {
      console.log(err);
    };
    
    <PaypalButton
      amount="1.00"
      onError={onError}
      onSuccess={onSuccess}
      onCancel={onCancel}
    />
    

    请注意,这没有经过测试,我只是从 npm 包 github 中将其拉出并删除了打字稿以便于阅读,但它应该让您了解该做什么以及如何将您的捐赠逻辑添加到按钮。我强烈建议阅读贝宝文档。经历是痛苦的,但也是必要的。如果您不想创建自己的按钮,您可以添加 npm 包,然后就可以轻松上手了。

    【讨论】:

    • 付款 ID 为空。为什么?
    • @Khushi 我不完全确定,但如果我不得不猜测是因为此时付款尚未完全处理。在此示例中,您还可以传递来自 then 块和控制台日志的详细信息。根据我的经验,如果您要根据服务器上的记录检查交易的有效性,则需要订单 ID,这就是为什么我在控制台记录数据而不是 onApprove 函数中的详细信息的原因。文档阅读起来很痛苦,但如果要保存在服务器中,请尝试通读以找到要保存的信息。
    • 是的,我这样做了,我从 then 块传递详细信息并对其进行控制台。我得到的是:付款:对象 { create_time:“2020-03-09T07:58:00Z”,update_time:“2020-03-09T07:59:05Z”,id:“1FN65392BW503230D”,意图:“CAPTURE”,状态:“已完成”,付款人:{...},购买单位:(1)[...],链接:(1)[...]}和详细信息:对象{订单ID:“1FN65392BW503230D”,付款人ID:“3LNXV55Q55GHE”,付款ID:空, billingToken: null, facilitatorAccessToken: "A21AAHXTop8puyaYcAjkKpNe9B09ODed1hRWjs-Mrehs7_WI--aqYzLr6dYmUoQuL05zvvehd4z468BEC7S2ToaG0UVKoXdcA" } 在那个支付 id 是 null 。
    • 为了验证我将订单 ID 传递给服务器,然后我得到了 RESORCE_NOT_FOUND 和无效的资源 ID。我做的另一件事是我检查了我的商业账户,那里没有发生任何交易细节。在我的沙盒个人帐户中,它反映了详细信息
    • 您应该只需要 orderID 在您的服务器上进行验证。我每次都为 paymentID 得到 null ,此时你不应该需要它。我通常使用 nodejs 和他们提供的服务器端 sdk developer.paypal.com/docs/checkout/reference/server-integration/… 。我觉得奇怪的是,您没有在您的帐户中看到交易详细信息。这是一个适用于我的代码框codesandbox.io/s/paypal-button-nuqnj。将您的 clientID 放在 buttonjs 中。试一试,看看你的沙盒是否能反映交易。
    猜你喜欢
    • 2011-12-11
    • 2020-03-17
    • 2021-06-25
    • 2019-05-19
    • 1970-01-01
    • 1970-01-01
    • 2017-09-02
    • 2018-12-07
    • 1970-01-01
    相关资源
    最近更新 更多