363 lines
10 KiB
JavaScript
363 lines
10 KiB
JavaScript
import { Order } from "./orderModel.js";
|
|
import { generate } from "generate-password";
|
|
const { PAYPAL_CLIENT_ID, PAYPAL_CLIENT_SECRET } = process.env;
|
|
const base = "https://api-m.sandbox.paypal.com";
|
|
import axios from "axios";
|
|
|
|
export const getClientId = async (req, res) => {
|
|
try {
|
|
res.status(200).json({
|
|
success: true,
|
|
clientId: PAYPAL_CLIENT_ID,
|
|
});
|
|
} catch (error) {
|
|
res.status(500).json({
|
|
success: false,
|
|
message: error.message ? error.message : "Something went Wrong",
|
|
});
|
|
}
|
|
};
|
|
|
|
export const createOrder = async (req, res) => {
|
|
try {
|
|
if (!req?.user) return res.status(400).json({ message: "please login !" });
|
|
// console.log(req?.user)
|
|
let isUnique = false;
|
|
let order_id = generate({
|
|
length: 9,
|
|
numbers: true,
|
|
lowercase: false,
|
|
uppercase: false,
|
|
});
|
|
|
|
while (!isUnique) {
|
|
const unqOrder = await Order.findOne({ order_id });
|
|
if (!unqOrder) {
|
|
isUnique = true;
|
|
} else {
|
|
order_id = generate({
|
|
length: 9,
|
|
numbers: true,
|
|
lowercase: false,
|
|
uppercase: false,
|
|
});
|
|
}
|
|
}
|
|
|
|
req.body.user = req.user._id;
|
|
req.body.order_id = order_id;
|
|
const order = await Order.create(req.body);
|
|
|
|
res.status(201).json({
|
|
success: true,
|
|
order,
|
|
message: "order Created",
|
|
});
|
|
} catch (error) {
|
|
res.status(500).json({
|
|
success: false,
|
|
message: error.message ? error.message : "Something went Wrong",
|
|
});
|
|
}
|
|
};
|
|
|
|
export const getAllOrder = async (req, res) => {
|
|
try {
|
|
if (!req?.user) return res.status(400).json({ message: "please login !" });
|
|
// console.log(req?.user)
|
|
|
|
const order = await Order.find()
|
|
.populate({
|
|
path: "user",
|
|
select: "name -_id",
|
|
})
|
|
.sort({ createdAt: -1 });
|
|
if (order) {
|
|
res.status(201).json({
|
|
success: true,
|
|
order,
|
|
message: "All Order Fetched",
|
|
});
|
|
}
|
|
} catch (error) {
|
|
res.status(500).json({
|
|
success: false,
|
|
message: error.message ? error.message : "Something went Wrong",
|
|
});
|
|
}
|
|
};
|
|
export const getSingleOrder = async (req, res) => {
|
|
try {
|
|
if (!req?.user) return res.status(400).json({ message: "please login !" });
|
|
// console.log(req?.user)
|
|
if (!req.params.id)
|
|
return res.status(400).json({ message: "please Provide Order Id" });
|
|
|
|
const order = await Order.findById(req.params.id)
|
|
.populate({
|
|
path: "user",
|
|
select: "name -_id",
|
|
})
|
|
.populate({
|
|
path: "shippingInfo",
|
|
|
|
populate: {
|
|
path: "Franchisee",
|
|
select: "banner price_Lable ",
|
|
},
|
|
})
|
|
.sort({ createdAt: -1 });
|
|
if (order) {
|
|
res.status(201).json({
|
|
success: true,
|
|
order,
|
|
message: " Order Fetched",
|
|
});
|
|
}
|
|
} catch (error) {
|
|
res.status(500).json({
|
|
success: false,
|
|
message: error.message ? error.message : "Something went Wrong",
|
|
});
|
|
}
|
|
};
|
|
|
|
export const EditOrderBeforePayment = async (req, res) => {
|
|
try {
|
|
if (!req?.user) return res.status(400).json({ message: "please login !" });
|
|
// console.log(req?.user)
|
|
if (!req.params.id)
|
|
return res.status(400).json({ message: "please Provide Order Id" });
|
|
|
|
const order = await Order.findById(req.params.id);
|
|
if (order) {
|
|
if (order.isPaid === false) {
|
|
if (order.user.toString() === req.user._id.toString()) {
|
|
req.body.user = req.user._id;
|
|
|
|
const ModifyOrder = await Order.findByIdAndUpdate(
|
|
req.params.id,
|
|
req.body,
|
|
|
|
{
|
|
new: true,
|
|
runValidators: true,
|
|
useFindAndModify: false,
|
|
}
|
|
);
|
|
res.status(200).json({
|
|
success: true,
|
|
order: ModifyOrder,
|
|
message: " Order Updated",
|
|
});
|
|
} else {
|
|
return res.status(400).json({
|
|
message: "You not created This So You Can not Edit this Order !! ",
|
|
});
|
|
}
|
|
} else {
|
|
return res
|
|
.status(400)
|
|
.json({ message: "order can not Edited Because Payment Done !! " });
|
|
}
|
|
}
|
|
} catch (error) {
|
|
res.status(500).json({
|
|
success: false,
|
|
message: error.message ? error.message : "Something went Wrong",
|
|
});
|
|
}
|
|
};
|
|
export const deleteOneOrder = async (req, res) => {
|
|
try {
|
|
if (!req?.user) return res.status(400).json({ message: "please login !" });
|
|
if (!req.params.id)
|
|
return res.status(400).json({ message: "please Provide Order Id" });
|
|
const getOrder = await Order.findById(req.params.id);
|
|
if (!getOrder) {
|
|
return res.status(404).json({
|
|
success: false,
|
|
message: "No Order Found!",
|
|
});
|
|
}
|
|
const order = await Order.findByIdAndDelete(req.params.id);
|
|
|
|
await order.remove();
|
|
res.status(200).json({
|
|
success: true,
|
|
message: "Order Deleted Successfully!!",
|
|
});
|
|
} catch (error) {
|
|
res.status(500).json({
|
|
success: false,
|
|
message: error.message ? error.message : "Something went Wrong",
|
|
});
|
|
}
|
|
};
|
|
|
|
// parse post params sent in body in json format
|
|
|
|
/**
|
|
* Generate an OAuth 2.0 access token for authenticating with PayPal REST APIs.
|
|
// https://developer.paypal.com/api/rest/authentication/
|
|
*/
|
|
const generateAccessToken = async () => {
|
|
const credentials = `${PAYPAL_CLIENT_ID}:${PAYPAL_CLIENT_SECRET}`;
|
|
const base64Credentials = Buffer.from(credentials).toString("base64");
|
|
|
|
const headers = {
|
|
"Content-Type": "application/x-www-form-urlencoded",
|
|
Authorization: `Basic ${base64Credentials}`,
|
|
};
|
|
|
|
const data = "grant_type=client_credentials";
|
|
|
|
try {
|
|
const response = await axios.post(
|
|
"https://api.sandbox.paypal.com/v1/oauth2/token",
|
|
data,
|
|
{
|
|
headers: headers,
|
|
}
|
|
);
|
|
// console.log("response.data", response.data);
|
|
const accessToken = response.data?.access_token;
|
|
return accessToken;
|
|
// console.log("Access Token:", accessToken);
|
|
} catch (error) {
|
|
console.error(
|
|
"Error getting access token:",
|
|
error.response ? error.response.data : error.message
|
|
);
|
|
}
|
|
};
|
|
// } catch (error) {
|
|
// console.error("Failed to generate Access Token:");
|
|
// }
|
|
// };
|
|
|
|
const handleResponse = async (response) => {
|
|
try {
|
|
if (response.status >= 200 && response.status < 300) {
|
|
return {
|
|
success: true,
|
|
responseData: response.data,
|
|
httpStatusCode: response.status,
|
|
};
|
|
}
|
|
} catch (err) {
|
|
const errorMessage = await response.statusText;
|
|
throw new Error(errorMessage);
|
|
}
|
|
};
|
|
|
|
// https://developer.paypal.com/docs/api/orders/v2/#orders_create
|
|
|
|
export const createOrderCheckout = async (rea, res) => {
|
|
try {
|
|
// const { cart } = req.body;
|
|
// use the cart information passed from the front-end to calculate the purchase unit details
|
|
// console.log(
|
|
// "shopping cart information passed from the frontend createOrder() callback:",
|
|
// cart
|
|
// );
|
|
const accessToken = await generateAccessToken();
|
|
const url = `https://api.sandbox.paypal.com/v2/checkout/orders`;
|
|
const createOrderRequest = {
|
|
intent: "CAPTURE",
|
|
purchase_units: [
|
|
{
|
|
amount: {
|
|
currency_code: "USD",
|
|
value: "60.00", // Replace with the actual amount
|
|
breakdown: {
|
|
item_total: {
|
|
currency_code: "USD",
|
|
value: "60.00", // Replace with the total value of all items
|
|
},
|
|
},
|
|
},
|
|
items: [
|
|
{
|
|
name: "Apple",
|
|
unit_amount: {
|
|
currency_code: "USD",
|
|
value: "60.00", // Replace with the actual item price
|
|
},
|
|
quantity: 1,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
};
|
|
const response = await axios.post(url, JSON.stringify(createOrderRequest), {
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
Authorization: `Bearer ${accessToken}`,
|
|
},
|
|
});
|
|
|
|
if (response.status >= 200 && response.status < 300) {
|
|
return res.status(201).json({
|
|
success: true,
|
|
responseData: response.data,
|
|
httpStatusCode: response.status,
|
|
});
|
|
} else {
|
|
// Handle errors or unexpected status codes
|
|
console.error("Error:", response.status, response.statusText);
|
|
|
|
// Optionally, you can parse the error response as JSON if available
|
|
try {
|
|
const errorData = response.data;
|
|
console.error("Error Data:", errorData);
|
|
} catch (error) {
|
|
console.error("Error parsing error data:", error.message);
|
|
}
|
|
}
|
|
} catch (error) {
|
|
const errorMessage = await response.statusText;
|
|
return res.status(500).json({
|
|
success: false,
|
|
message: errorMessage,
|
|
});
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Capture payment for the created order to complete the transaction.
|
|
* //see https://developer.paypal.com/docs/api/orders/v2/#orders_capture
|
|
*/
|
|
|
|
const captureOrder = async (orderID) => {
|
|
const accessToken = await generateAccessToken();
|
|
const url = `${base}/v2/checkout/orders/${orderID}/capture`;
|
|
const response = await axios.post(
|
|
url,
|
|
{},
|
|
{
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
Authorization: `Bearer ${accessToken}`,
|
|
// Uncomment one of these to force an error for negative testing (in sandbox mode only). Documentation:
|
|
// https://developer.paypal.com/tools/sandbox/negative-testing/request-headers/
|
|
// "PayPal-Mock-Response": '{"mock_application_codes": "INSTRUMENT_DECLINED"}'
|
|
// "PayPal-Mock-Response": '{"mock_application_codes": "TRANSACTION_REFUSED"}'
|
|
// "PayPal-Mock-Response": '{"mock_application_codes": "INTERNAL_SERVER_ERROR"}'
|
|
},
|
|
}
|
|
);
|
|
return handleResponse(response);
|
|
};
|
|
|
|
export const captureOrderPayment = async (req, res) => {
|
|
try {
|
|
const { orderID } = req.params;
|
|
const { responseData, httpStatusCode } = await captureOrder(orderID);
|
|
return res.status(httpStatusCode).json(responseData);
|
|
} catch (error) {
|
|
console.error("Failed to create order:", error);
|
|
res.status(500).json({ error: "Failed to capture order." });
|
|
}
|
|
};
|