[英]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.