簡體   English   中英

React-paypal 高級集成錯誤

[英]React-paypal advanced integration errors

我已經嘗試實施 React-Paypal 高級集成將近一周了,但我一直收到錯誤消息。 我沒有使用 paypal 沙箱中的 api,而是調用我們自己的 api 構建的 dotnet。

當我繼續付款時,創建了訂單 ID,但付款被拒絕。

我想要實現的工作流程是;

onClick Prepare for payment將生成我需要在后端處理的所有數據。 然后,在渲染或 onClick Pay上,它將創建一個包含 orderId 的訂單並捕獲付款。

誰能發現我在下面的代碼中出錯的地方?

錯誤:

在此處輸入圖像描述

Checkout.jsx

import { useState } from "react"
import {
    PayPalScriptProvider
} from "@paypal/react-paypal-js";
import CheckoutButton from "./CheckoutButton";
import "../styles/Checkout.css";
import NewCheckoutBtn from "./Checkout2";

const PrepareForPayment = () => {

    const [clientId, setClientId] = useState(null)
    const [clientToken, setClientToken] = useState(null)
    const [merchantRef, setMerchantRef] = useState(null)
    const [sessionHash, setSessionHash] = useState(null)
    const [showData, setShowData] = useState(false);

    const baseUrl = "http://local.payment.web"

    const onClick = async () => {
        console.log("onClick ran");
        return await fetch(`${baseUrl}/api/Ppal/ReactApi/PrepareForPayment`, {
                mode: "cors",
                method: "post",
                headers: {
                    'content-type': 'application/json',
                    'Access-Control-Allow-Origin': '*'
    
                },
                body: JSON.stringify({
                    "curCode": "USD",
                    "orderAmount": 500
                })
            }).then(res => {
                console.log("fetch Data : ", res);
                return res.json()
            }).then(data => {
                console.log("fetch Data : ", data);
                setShowData(true)
                setClientId(data.ClientId)
                setClientToken(data.ClientToken)
    
                if (data.prepareForPayment) {
                    setMerchantRef(data.merchantRef)
                    setSessionHash(data.sessionHash)
                }
            }).catch(err => console.log(err))
    }
    
    return (
        <>
            <button onClick={onClick} disabled={showData ? true : false}>Prepare for payment</button>
            {
                clientToken && (
                    <PayPalScriptProvider
                        options={{
                            "client-id": clientId,
                            components: "buttons,hosted-fields",
                            "data-client-token": clientToken,
                            intent: "capture",
                            vault: false,
                        }}
                    >
                        <CheckoutButton merchantRef={merchantRef} sessionHash={sessionHash} />
                    </PayPalScriptProvider>
                )
            }
        </>
    )
}

export default PrepareForPayment

CheckoutButton.jsx

import { useState, useRef, useEffect } from "react";
import { usePayPalHostedFields, usePayPalScriptReducer } from "@paypal/react-paypal-js";

import "../styles/CheckoutBtn.css";
import { useCallback } from "react";

const CheckoutButton = ({ merchantRef, sessionHash }) => {
    const [paid, hasPaid] = useState(false)
    const [orderId, setOrderId] = useState(null)
    const [supportsHostedFields, setSupportsHostedFields] = useState(null)
    const [renderInstance, setRenderInstance] = useState()

    const cardHolderName = useRef(null);
    const hostedField = usePayPalHostedFields();
    const [{ isResolved, options }] = usePayPalScriptReducer()

    const paypal = window.paypal
    const baseUrl = "http://local.payment.web"

    const initPaypal = useCallback(async () => {
        if (typeof supportsHostedFields === "boolean" && !!supportsHostedFields) {
            const instance = await paypal.HostedFields.render({
                createOrder: function() {
                    return fetch(`${baseUrl}/api/Ppal/ReactApi/CreateOrder2`, {
                        method: 'post',
                        headers: {
                            'content-type': 'application/json'
                        },
                        body: JSON.stringify({
                            merchantRef: merchantRef,
                            sessionHash: sessionHash,
                            orderId: orderId,
                            intent: "capture",
                        })
                    }).then(res => {
                        console.log("res from createOrder", res);
                        return res.json()
                    }).then(data => {
                        console.log("orderId from initialize : ", data?.orderId);
                        if (data?.createOrder) return setOrderId(data?.orderId)
                    }).catch(err => console.log(err))
                },
                styles: {
                    input: {
                      "font-size": "16pt",
                      color: "#3A3A3A"
                    },
                    ".number": {
                      "font-family": "monospace"
                    },
                    ".valid": {
                      color: "green"
                    }
                  },
                  fields: {
                    number: {
                      selector: "#card-number",
                      placeholder: "Credit Card Number"
                    },
                    cvv: {
                      selector: "#cvv",
                      placeholder: "CVV"
                    },
                    expirationDate: {
                      selector: "#expiration-date",
                      placeholder: "MM/YYYY"
                    }
                  }
            })
            setRenderInstance(instance)
        }
    }, [merchantRef, sessionHash, orderId, paypal, supportsHostedFields])

    useEffect(() => {
        if (isResolved) {
          setSupportsHostedFields(paypal.HostedFields.isEligible());
        }
    }, [setSupportsHostedFields, options, isResolved, paypal]);

    useEffect(() => {
        initPaypal()
    }, [initPaypal])

    
    const handleClick = (e) => {
        e.preventDefault()
        
        console.log("Order id onclick : ", orderId);
        renderInstance.submit().then((data) => {
            console.log("Reach here?");
            const captureOrder = async () => {
                return await fetch(`${baseUrl}/api/Ppal/ReactApi/CaptureOrder`, {
                    mode: "cors",
                    method: "post",
                    headers: {
                        'content-type': 'application/json'
                    },
                    body: JSON.stringify({
                        merchantRef: merchantRef,
                        sessionHash: sessionHash
                    })
                }).then((res) => {
                    console.log("res from pay button : ", res);
                    return res.json()
                }).then((data) => {
                    console.log("data from pay button : ", data);
                    if(data.isApproved) {
                        alert("Payment successful")
                        hasPaid(true)
                    }
                    if(!data.isApproved) alert("Payment declined")
                    if(data.isExpired) alert("Payment expired")
                })
            }
            captureOrder().catch((err) => {
                console.log(err)
            })
            return data
        })
        
        console.log("Card holder : ", cardHolderName.current.value);
        console.log("merchant ref : ", merchantRef);
        console.log("Order id onclick after : ", orderId);
    };

    return (
        <form onSubmit={handleClick}>
            <label htmlFor="card-number">Card Number</label>
            <div id="card-number"></div>
            <label htmlFor="expiration-date">Expiration Date</label>
            <div id="expiration-date"></div>
            <label htmlFor="cvv">CVV</label>
            <div id="cvv"></div>
            <button value="submit" id="submit" className="btn">
                Pay with Card
            </button>
        </form>
    )
};

export default CheckoutButton;

正如其他人指出的那樣,您的屏幕截圖中的錯誤來自handleClick內部的這一行

        console.log("Card holder : ", cardHolderName.current.value);

您已經使用cardHolderName初始化了 cardHolderName。

    const cardHolderName = useRef(null);

但是你的代碼似乎對那個 ref 沒有任何作用。 因此 ref 的當前值將始終為 null。

要修復錯誤,請刪除對cardHolderName.current.value的尊重,或將 ref 的值設置為具有value屬性的 object。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM