refactor: resolve payment issue in paypal mode
This commit is contained in:
@@ -20,6 +20,7 @@ const PaymentComponent = ({ amount, onSuccess }) => {
|
|||||||
country_code: "",
|
country_code: "",
|
||||||
postal_code: "",
|
postal_code: "",
|
||||||
});
|
});
|
||||||
|
const [shippingInfoCollected, setShippingInfoCollected] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchExchangeRate = async () => {
|
const fetchExchangeRate = async () => {
|
||||||
@@ -56,7 +57,6 @@ const PaymentComponent = ({ amount, onSuccess }) => {
|
|||||||
throw new Error("Failed to fetch exchange rate");
|
throw new Error("Failed to fetch exchange rate");
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// setError("Currency conversion failed. Please try again later.");
|
|
||||||
console.error("Exchange rate error:", err);
|
console.error("Exchange rate error:", err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -80,22 +80,14 @@ const PaymentComponent = ({ amount, onSuccess }) => {
|
|||||||
const handlePaymentSuccess = (response) => {
|
const handlePaymentSuccess = (response) => {
|
||||||
onSuccess?.({
|
onSuccess?.({
|
||||||
...response,
|
...response,
|
||||||
shippingData, // Include the shipping data in the success callback
|
address: shippingData, // Include the shipping data in the success callback
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRazorpayPayment = async () => {
|
const handleRazorpayPayment = async () => {
|
||||||
if (!shippingData.address_line_1 || !shippingData.city || !shippingData.postal_code) {
|
|
||||||
setError("Please fill in all required fields.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const order = await createOrder();
|
const order = await createOrder();
|
||||||
console.log(shippingData)
|
|
||||||
// log env varaible NEXT_RAZORPAY_CLIENT_ID in next js
|
|
||||||
|
|
||||||
console.log("Razorpay Client ID:", process.env.NEXT_PUBLIC_RAZORPAY_CLIENT_ID);
|
|
||||||
const options = {
|
const options = {
|
||||||
key: "rzp_test_Xf4wnkvQQeUnCq",
|
key: "rzp_test_Xf4wnkvQQeUnCq",
|
||||||
amount: order.amount,
|
amount: order.amount,
|
||||||
@@ -109,8 +101,8 @@ const PaymentComponent = ({ amount, onSuccess }) => {
|
|||||||
contact: shippingData.city,
|
contact: shippingData.city,
|
||||||
},
|
},
|
||||||
handler: (response) => {
|
handler: (response) => {
|
||||||
response.address = shippingData
|
response.address = shippingData;
|
||||||
handlePaymentSuccess(response); // Pass the response to the success handler
|
handlePaymentSuccess(response);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -123,13 +115,23 @@ const PaymentComponent = ({ amount, onSuccess }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handlePopupSubmit = () => {
|
const handlePopupSubmit = () => {
|
||||||
|
if (!shippingData.address_line_1 || !shippingData.city || !shippingData.postal_code) {
|
||||||
|
setError("Please fill in all required fields.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setShowPopup(false);
|
setShowPopup(false);
|
||||||
handleRazorpayPayment();
|
setShippingInfoCollected(true);
|
||||||
|
setError(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
// if (!usdAmount) {
|
const validateShippingInfo = () => {
|
||||||
// return <div className="text-center p-4">Loading exchange rates...</div>;
|
if (!shippingInfoCollected) {
|
||||||
// }
|
setShowPopup(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="max-w-md mx-auto">
|
<div className="max-w-md mx-auto">
|
||||||
@@ -143,68 +145,96 @@ const PaymentComponent = ({ amount, onSuccess }) => {
|
|||||||
Error loading Razorpay: {razorpayError}
|
Error loading Razorpay: {razorpayError}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<PayPalScriptProvider
|
|
||||||
options={{
|
|
||||||
"client-id": process.env.NEXT_PUBLIC_CLIENT_ID,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<PayPalButtons
|
|
||||||
style={{
|
|
||||||
layout: "horizontal",
|
|
||||||
label: "checkout",
|
|
||||||
tagline: false,
|
|
||||||
fundingicons: true,
|
|
||||||
}}
|
|
||||||
disabled={isProcessing}
|
|
||||||
className="w-full"
|
|
||||||
createOrder={(data, actions) => {
|
|
||||||
return actions.order.create({
|
|
||||||
purchase_units: [
|
|
||||||
{
|
|
||||||
amount: {
|
|
||||||
value: usdAmount,
|
|
||||||
currency_code: "USD",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
application_context: {
|
|
||||||
shipping_preference: "GET_FROM_FILE",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
onApprove={async (data, actions) => {
|
|
||||||
try {
|
|
||||||
setIsProcessing(true);
|
|
||||||
const order = await actions.order.capture();
|
|
||||||
onSuccess?.(order);
|
|
||||||
} catch (err) {
|
|
||||||
setError("Payment failed. Please try again.");
|
|
||||||
console.error("Payment error:", err);
|
|
||||||
} finally {
|
|
||||||
setIsProcessing(false);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onError={(err) => {
|
|
||||||
setError("Payment failed. Please try again.");
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</PayPalScriptProvider>
|
|
||||||
|
|
||||||
<button
|
{/* Show shipping info status */}
|
||||||
onClick={() => setShowPopup(true)}
|
{shippingInfoCollected && (
|
||||||
disabled={isProcessing || isLoading}
|
<div className="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded mb-4">
|
||||||
className="mt-4 w-full bg-blue-500 text-white py-2 px-4 rounded hover:bg-blue-600"
|
Shipping information collected ✓
|
||||||
>
|
<button
|
||||||
{isLoading ? "Loading Razorpay..." : "Pay with Razorpay"}
|
onClick={() => setShowPopup(true)}
|
||||||
</button>
|
className="ml-2 text-sm underline"
|
||||||
|
>
|
||||||
|
Edit
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Collect shipping info button */}
|
||||||
|
{!shippingInfoCollected && (
|
||||||
|
<button
|
||||||
|
onClick={() => setShowPopup(true)}
|
||||||
|
className="w-full bg-gray-200 text-gray-800 py-2 px-4 rounded hover:bg-gray-300 mb-4"
|
||||||
|
>
|
||||||
|
Enter Shipping Information
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Payment options - only enabled after shipping info is collected */}
|
||||||
|
<div className={!shippingInfoCollected ? "opacity-50 pointer-events-none" : ""}>
|
||||||
|
<PayPalScriptProvider
|
||||||
|
options={{
|
||||||
|
"client-id": process.env.NEXT_PUBLIC_CLIENT_ID,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<PayPalButtons
|
||||||
|
style={{
|
||||||
|
layout: "horizontal",
|
||||||
|
label: "checkout",
|
||||||
|
tagline: false,
|
||||||
|
fundingicons: true,
|
||||||
|
}}
|
||||||
|
disabled={isProcessing || !shippingInfoCollected}
|
||||||
|
className="w-full"
|
||||||
|
createOrder={(data, actions) => {
|
||||||
|
return actions.order.create({
|
||||||
|
purchase_units: [
|
||||||
|
{
|
||||||
|
amount: {
|
||||||
|
value: usdAmount,
|
||||||
|
currency_code: "USD",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
application_context: {
|
||||||
|
shipping_preference: "GET_FROM_FILE",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
onApprove={async (data, actions) => {
|
||||||
|
try {
|
||||||
|
setIsProcessing(true);
|
||||||
|
const order = await actions.order.capture();
|
||||||
|
order.address = shippingData; // Add shipping data to PayPal order
|
||||||
|
handlePaymentSuccess(order);
|
||||||
|
} catch (err) {
|
||||||
|
setError("Payment failed. Please try again.");
|
||||||
|
console.error("Payment error:", err);
|
||||||
|
} finally {
|
||||||
|
setIsProcessing(false);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onError={(err) => {
|
||||||
|
setError("Payment failed. Please try again.");
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</PayPalScriptProvider>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={handleRazorpayPayment}
|
||||||
|
disabled={isProcessing || isLoading || !shippingInfoCollected}
|
||||||
|
className="mt-4 w-full bg-blue-500 text-white py-2 px-4 rounded hover:bg-blue-600"
|
||||||
|
>
|
||||||
|
{isLoading ? "Loading Razorpay..." : "Pay with Razorpay"}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
{showPopup && (
|
{showPopup && (
|
||||||
<div className=" fixed inset-0 flex items-center justify-center bg-black bg-opacity-50" style={{ zIndex: 1000 }}>
|
<div className="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50" style={{ zIndex: 1000 }}>
|
||||||
<div className="bg-white p-6 rounded-lg shadow-lg w-96">
|
<div className="bg-white p-6 rounded-lg shadow-lg w-96">
|
||||||
<h3 className="text-lg font-medium mb-4">Enter Your Shipping Details</h3>
|
<h3 className="text-lg font-medium mb-4">Enter Your Shipping Details</h3>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Address Line 1"
|
placeholder="Address Line 1 *"
|
||||||
value={shippingData.address_line_1}
|
value={shippingData.address_line_1}
|
||||||
onChange={(e) => setShippingData({ ...shippingData, address_line_1: e.target.value })}
|
onChange={(e) => setShippingData({ ...shippingData, address_line_1: e.target.value })}
|
||||||
className="w-full p-2 mb-4 border border-gray-300 rounded"
|
className="w-full p-2 mb-4 border border-gray-300 rounded"
|
||||||
@@ -218,7 +248,7 @@ const PaymentComponent = ({ amount, onSuccess }) => {
|
|||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="City"
|
placeholder="City *"
|
||||||
value={shippingData.city}
|
value={shippingData.city}
|
||||||
onChange={(e) => setShippingData({ ...shippingData, city: e.target.value })}
|
onChange={(e) => setShippingData({ ...shippingData, city: e.target.value })}
|
||||||
className="w-full p-2 mb-4 border border-gray-300 rounded"
|
className="w-full p-2 mb-4 border border-gray-300 rounded"
|
||||||
@@ -232,24 +262,32 @@ const PaymentComponent = ({ amount, onSuccess }) => {
|
|||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Country Code"
|
placeholder="Country Code *"
|
||||||
value={shippingData.country_code}
|
value={shippingData.country_code}
|
||||||
onChange={(e) => setShippingData({ ...shippingData, country_code: e.target.value })}
|
onChange={(e) => setShippingData({ ...shippingData, country_code: e.target.value })}
|
||||||
className="w-full p-2 mb-4 border border-gray-300 rounded"
|
className="w-full p-2 mb-4 border border-gray-300 rounded"
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Postal Code"
|
placeholder="Postal Code *"
|
||||||
value={shippingData.postal_code}
|
value={shippingData.postal_code}
|
||||||
onChange={(e) => setShippingData({ ...shippingData, postal_code: e.target.value })}
|
onChange={(e) => setShippingData({ ...shippingData, postal_code: e.target.value })}
|
||||||
className="w-full p-2 mb-4 border border-gray-300 rounded"
|
className="w-full p-2 mb-4 border border-gray-300 rounded"
|
||||||
/>
|
/>
|
||||||
<button
|
<div className="flex gap-2">
|
||||||
onClick={handlePopupSubmit}
|
<button
|
||||||
className="w-full bg-blue-500 text-white py-2 px-4 rounded hover:bg-blue-600"
|
onClick={() => setShowPopup(false)}
|
||||||
>
|
className="w-1/2 bg-gray-300 text-gray-800 py-2 px-4 rounded hover:bg-gray-400"
|
||||||
Submit
|
>
|
||||||
</button>
|
Cancel
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={handlePopupSubmit}
|
||||||
|
className="w-1/2 bg-blue-500 text-white py-2 px-4 rounded hover:bg-blue-600"
|
||||||
|
>
|
||||||
|
Save Address
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ const ShoppingCart = () => {
|
|||||||
paymentId: order.id,
|
paymentId: order.id,
|
||||||
payerEmail: order.payer.email_address,
|
payerEmail: order.payer.email_address,
|
||||||
cartId: cartItems[0].id,
|
cartId: cartItems[0].id,
|
||||||
address: shippingAddress, // Include the shipping address
|
address: order.address,
|
||||||
};
|
};
|
||||||
|
|
||||||
const apiResponse = await authAxios.post("/orders/payment/", paymentData);
|
const apiResponse = await authAxios.post("/orders/payment/", paymentData);
|
||||||
|
|||||||
Reference in New Issue
Block a user