React 中的智能 PayPal 按钮,禁用按钮

问题描述 投票:0回答:2

我在 React 中实现了 PayPal 智能按钮

function PayPalButtonComponent(props: PayPalButtonProps) {
  const [show, set_show] = useState(false);
  const [error, set_error] = useState<string>();

  const create_order = (_: any, actions: any) => {
    return actions.order.create({
      purchase_units: [
        {
          amount: {
            currency: props.currency || "EUR",
            value: props.total
          }
        }
      ]
    });
  };
  const handle_approve = (_: any, actions: any) => {
    return actions.order.capture().then((details: any) => {
      if (props.onSuccess) props.onSuccess(details);
    });
  };
  const handle_cancel = () => {
    if (props.onCancel) props.onCancel();
  };
  const handle_error = () => {
    if (props.onError) props.onError();
  };
  const render_button = () => {
    const Button = paypal.Buttons.driver("react", { React, ReactDOM });
    return (
      <Button
        style={{
          layout: "horizontal",
          size: "responsive",
          shape: "rect",
          color: "gold",
          tagline: false
        }}
        funding={{
          allowed: [paypal.FUNDING.CARD, paypal.FUNDING.PAYPAL],
          disallowed: [paypal.FUNDING.CREDIT]
        }}
        createOrder={create_order}
        onApprove={handle_approve}
        onError={handle_error}
        onCancel={handle_cancel}
      />
    );
  };

  useEffect(() => {
    if (props.isScriptLoaded) {
      if (props.isScriptLoadSucceed) set_show(true);
      else set_error("Unable to load the paypalscript");
    }
  }, [props.isScriptLoaded, props.isScriptLoadSucceed]);

  if (error) return <p>{error}</p>;
  if (!show) return <FakeButton />;

  return render_button();
}

我一直在努力实现这些按钮,因为没有文档,我从here找到并复制了一些代码,并试图猜测其他东西。但我不明白如何禁用按钮。

本指南中,他们声明可以在操作对象上调用 disable() 方法,但无法弄清楚如何使用我的配置来实现这一点。

你试过类似的东西吗?您知道可以遵循的任何文档吗?

编辑

我想要完成的是在支付期间将按钮设置为禁用状态。我知道有 paypal 覆盖,但是当交易完成时,我更改了应用程序路由,因为它发生在调用 onSuccess 时,由于 actions.order.capture() 的明显异步性质,这不可能立即发生,所以有时可以再次单击贝宝按钮。如果我可以禁用按钮,我就解决了问题。

onInit 实现允许您在单击按钮之前禁用/启用该按钮,这对于结帐前的某种验证很有用(例如已检查的条款),但不适用于我的情况。我也试过在

create_order
中调用 actions.disable() 但这会破坏按钮。

reactjs typescript paypal paypal-buttons
2个回答
0
投票

这里有同样的情况,文档中的 onInit 示例并不像某些人认为的那么简单......您需要创建隐藏输入并在付款时为其分配某种变量,以便在付款后禁用按钮。可惜没有人解决这个问题。


0
投票

对于 React,我会使用官方的 PayPal NPM (@paypal/react-paypal-js) 包。他们有一些关于如何使用它的很好的文档......在你的情况下,只需使用该组件,你可以设置它是否被禁用作为一个属性。

查看他们的代码示例:

import { useEffect } from "react";
import {
    PayPalScriptProvider,
    PayPalButtons,
    usePayPalScriptReducer
} from "@paypal/react-paypal-js";

// This values are the props in the UI
const amount = "2";
const currency = "USD";
const style = {"layout":"vertical"};

// Custom component to wrap the PayPalButtons and handle currency changes
const ButtonWrapper = ({ currency, showSpinner }) => {
    // usePayPalScriptReducer can be use only inside children of PayPalScriptProviders
    // This is the main reason to wrap the PayPalButtons in a new component
    const [{ options, isPending }, dispatch] = usePayPalScriptReducer();

    useEffect(() => {
        dispatch({
            type: "resetOptions",
            value: {
                ...options,
                currency: currency,
            },
        });
    }, [currency, showSpinner]);


    return (<>
            { (showSpinner && isPending) && <div className="spinner" /> }
            <PayPalButtons
                style={style}
                disabled={false}
                forceReRender={[amount, currency, style]}
                fundingSource={undefined}
                createOrder={(data, actions) => {
                    return actions.order
                        .create({
                            purchase_units: [
                                {
                                    amount: {
                                        currency_code: currency,
                                        value: amount,
                                    },
                                },
                            ],
                        })
                        .then((orderId) => {
                            // Your code here after create the order
                            return orderId;
                        });
                }}
                onApprove={function (data, actions) {
                    return actions.order.capture().then(function () {
                        // Your code here after capture the order
                    });
                }}
            />
        </>
    );
}

export default function App() {
    return (
        <div style={{ maxWidth: "750px", minHeight: "200px" }}>
            <PayPalScriptProvider
                options={{
                    "client-id": "test",
                    components: "buttons",
                    currency: "USD"
                }}
            >
                <ButtonWrapper
                    currency={currency}
                    showSpinner={false}
                />
            </PayPalScriptProvider>
        </div>
    );
}
© www.soinside.com 2019 - 2024. All rights reserved.