From 04a3dba9942eacce7b6d299b70890d2c329a571f Mon Sep 17 00:00:00 2001 From: TylerP33 Date: Tue, 26 Mar 2024 15:58:54 -0500 Subject: [PATCH] Items can officially be posted to eBay --- api/controllers/inventoryController.js | 102 ++++++++++++++++++++----- api/routes/inventoryRoutes.js | 5 +- api/server.js | 30 -------- 3 files changed, 84 insertions(+), 53 deletions(-) diff --git a/api/controllers/inventoryController.js b/api/controllers/inventoryController.js index 491c382..c328b52 100644 --- a/api/controllers/inventoryController.js +++ b/api/controllers/inventoryController.js @@ -6,11 +6,13 @@ export const createAndListItem = async (req, res) => { sku, marketplaceId, format, + listingDuration, availableQuantity, categoryId, condition, listingDescription, pricingSummary, + mpn, merchantLocationKey, quantityLimitPerBuyer, product, // Extract the entire product object @@ -20,7 +22,7 @@ export const createAndListItem = async (req, res) => { const token = await fetchEbayUserToken(req, res); // Get the eBay user token - +// only need these if payloads is there? let dynamicAspects = {}; for (const [key, value] of Object.entries(product.aspects)) { dynamicAspects[key] = Array.isArray(value) ? value : [value]; @@ -31,19 +33,30 @@ export const createAndListItem = async (req, res) => { const inventoryItemPayload = { sku, condition, + quantity: availableQuantity, product: { title: product.title.substring(0, 80), // Utilizing product title brand: product.brand, // Using brand from the product object + mpn: mpn, description: product.description, // Using product description imageUrls: product.imageUrls, // Using all imageUrls from product - aspects: dynamicAspects }, - availability: { - shipToLocationAvailability: { - quantity: availableQuantity, - }, - }, - // Package weight and dimensions, adjusted to the new structure + availability: { + shipToLocationAvailability: { + quantity: availableQuantity, + availabilityDistributions: [ // Adding availability distributions + { + availabilityType: "IN_STOCK", // Assuming items are in stock for pickup + fulfillmentTime: { // Fulfillment time for shipping + unit: "DAY", + value: 1 // Adjust based on your shipping fulfillment time + }, + merchantLocationKey: merchantLocationKey, // Specify the location for shipping availability + quantity: availableQuantity // Quantity available for shipping from the specified location + } + ] + }, + }, packageWeightAndSize: { weight: { value: parseFloat(packageWeightAndSize.weight.value), @@ -74,22 +87,28 @@ export const createAndListItem = async (req, res) => { // Optionally, you can parse the response body if eBay's API returns useful information in it const itemResponseData = await createItemResponse; - console.log(itemResponseData); // 2. Create the offer for the inventory item const offerPayload = { sku, marketplaceId, - format, - listing: { - categoryId, - listingDescription, - merchantLocationKey, + format, // This is equivalent to format: format, + categoryId, // Moved to top-level, outside of the 'listing' object + listingDescription, // Moved to top-level, outside of the 'listing' object + merchantLocationKey, // Moved to top-level, outside of the 'listing' object + pricingSummary: { + price: pricingSummary.price, }, - pricingSummary, - quantityLimitPerBuyer, + availableQuantity, + listingDuration, + listingPolicies: { // Include the listing policies with their respective IDs + fulfillmentPolicyId: "246576176016", + returnPolicyId: "246576188016", + paymentPolicyId: "246576154016", + }, + // Additional fields from the sample payload can be included here as needed }; - + const offerResponse = await fetch( `https://api.ebay.com/sell/inventory/v1/offer`, { @@ -103,6 +122,7 @@ export const createAndListItem = async (req, res) => { } ); + if (!offerResponse.ok) { // Handle error in creating the offer const errorBody = await offerResponse.text(); @@ -113,18 +133,23 @@ export const createAndListItem = async (req, res) => { const offerData = await offerResponse.json(); const offerId = offerData.offerId; + console.log(offerId) // 3. Publish the offer to convert it into a live listing - await fetch( - `https://api.ebay.com/sell/inventory/v1/offer/${offerId}/publish/`, + const publishOfferResponse = await fetch( + `https://api.ebay.com/sell/inventory/v1/offer/${offerId}/publish/`, // Ensure the offerId is correctly inserted { method: "POST", headers: { - Authorization: `Bearer ${token}`, + Authorization: `Bearer ${token}`, // Ensure your token is valid "Content-Type": "application/json", }, } ); + + const responseBody = await publishOfferResponse.json(); // Assuming the response will be in JSON format + console.log(responseBody); + res.json({ success: true, message: "Item listed successfully" }); } catch (error) { @@ -133,7 +158,7 @@ export const createAndListItem = async (req, res) => { success: false, message: "Failed to create and list item on eBay", error: error.message, - }); + }) } }; @@ -203,3 +228,38 @@ export const getAllInventory = async (req, res) => { } }; +export const getOffers = async (req, res) => { + const sku = "LEMUG2022212234120245"; // Assuming this is your SKU + const offerId = 418806088016 + + try { + const token = await fetchEbayUserToken(req, res); // Assuming fetchEbayUserToken handles token retrieval internally + + const response = await fetch('https://api.ebay.com/commerce/taxonomy/v1/get_default_category_tree_id?marketplace_id=EBAY_US', { + method: 'GET', + headers: { + "Content-Type": "application/json", + "Content-Language": "en-US", + "Authorization": `Bearer ${token}`, + }, + }); + console.log(response) + const offers = await response.json(); // Parsing the JSON body of the response + + res.json(offers); // Sending the offers back to the client + } catch (error) { + console.error('Error fetching offers:', error); + res.status(500).json({ + error: 'Internal Server Error', + message: error.message, + }); + } +}; + +// fulfill policy = 246576176016 +// return policy = 246576188016 +// payment policy = 246576154016 + + + + diff --git a/api/routes/inventoryRoutes.js b/api/routes/inventoryRoutes.js index 732edc4..d44be1e 100644 --- a/api/routes/inventoryRoutes.js +++ b/api/routes/inventoryRoutes.js @@ -1,12 +1,13 @@ // routes/dataRoutes.js import express from "express"; -import { createAndListItem, deleteItemBySku, getAllInventory } from "../controllers/inventoryController.js"; +import { createAndListItem, deleteItemBySku, getAllInventory, getOffers } from "../controllers/inventoryController.js"; const router = express.Router(); router.post("/create-list-item", createAndListItem); router.get("/delete-item-by-sku", deleteItemBySku); -router.get("/get-all-inventory", getAllInventory) +router.get("/get-all-inventory", getAllInventory); +router.get("/get-offers", getOffers) export default router; diff --git a/api/server.js b/api/server.js index d305819..2af3dc3 100644 --- a/api/server.js +++ b/api/server.js @@ -5,7 +5,6 @@ import dotenv from "dotenv"; import dataRoutes from "./routes/dataRoutes.js"; import inventoryRoutes from "./routes/inventoryRoutes.js"; import cookieParser from "cookie-parser"; -import fetchEbayUserToken from "./utils/fetchEbayUserToken.js"; dotenv.config(); @@ -18,35 +17,6 @@ app.use(cookieParser()); app.use("/api/data", dataRoutes); app.use("/api/inventory", inventoryRoutes); -app.get("/check-inventory", async (req, res) => { - try { - const token = "v^1.1#i^1#r^0#p^3#f^0#I^3#t^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" - const limit = req.query.limit || '100'; // Default limit to 10 if not specified - const offset = req.query.offset || '0'; // Default offset to 0 if not specified - - const response = await fetch(`https://api.ebay.com/sell/inventory/v1/inventory_item?limit=${limit}&offset=${offset}`, { - method: 'GET', - headers: { - "Content-Type": "application/json", - "Authorization": `Bearer ${token}`, - "Accept-Language": "en-US", // Explicitly setting the Accept-Language header - }, - }); - - console.log(response) - - const inventoryItems = await response.json(); - console.log(inventoryItems); - res.json(inventoryItems); - } catch (error) { - console.error('Error checking inventory:', error); - if (!res.headersSent) { - res.status(500).json({ error: 'Internal Server Error' }); - } - } -}); - - /* the below code needs to be encapsulated somehow. It requires a manual flow, including QUICKLY copy/pasting the code query string from the result of localhost:300/auth/ebay (below)