medusa-shiprocket-fulfillment-plugin 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,82 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { defineWidgetConfig } from "@medusajs/admin-sdk";
3
+ import { Container, Heading, Text } from "@medusajs/ui";
4
+ const ShiprocketTrackingWidget = ({ data: order }) => {
5
+ var _a;
6
+ if (!(order == null ? void 0 : order.id) || !(order == null ? void 0 : order.fulfillments)) return null;
7
+ const activeShipments = (_a = order.fulfillments) == null ? void 0 : _a.filter(
8
+ (f) => {
9
+ var _a2;
10
+ return !f.canceled_at && f.data.awb && f.data.shipment_id && ((_a2 = f.provider) == null ? void 0 : _a2.id) === "shiprocket_shiprocket";
11
+ }
12
+ );
13
+ return /* @__PURE__ */ jsxs(Container, { className: "p-6 rounded-lg shadow-lg border border-neutral-700", children: [
14
+ /* @__PURE__ */ jsx("header", { className: "mb-6", children: /* @__PURE__ */ jsx(Heading, { level: "h2", className: "font-semibold text-lg text-white", children: "Shiprocket Printables" }) }),
15
+ (activeShipments == null ? void 0 : activeShipments.length) === 0 ? /* @__PURE__ */ jsx(Text, { className: "text-sm italic text-gray-400", children: "No active shipments" }) : /* @__PURE__ */ jsx("ul", { className: "space-y-6", children: activeShipments.map((fulfillment) => {
16
+ var _a2, _b, _c, _d, _e, _f, _g;
17
+ return /* @__PURE__ */ jsxs(
18
+ "li",
19
+ {
20
+ className: "bg-neutral-900/10 rounded-xl shadow-none p-5 flex flex-col gap-4 border border-neutral-900/10",
21
+ children: [
22
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-between items-center", children: [
23
+ /* @__PURE__ */ jsxs(Text, { className: "text-sm text-gray-300 font-normal", children: [
24
+ /* @__PURE__ */ jsx("span", { className: "text-xs font-normal text-white", children: "Shipment ID:" }),
25
+ " ",
26
+ ((_a2 = fulfillment.data) == null ? void 0 : _a2.shipment_id) || "No AWB found"
27
+ ] }),
28
+ /* @__PURE__ */ jsx("span", { className: `
29
+ px-2 py-1 rounded-lg shadow-none text-[9px] font-semibold uppercase select-none
30
+ ${fulfillment.status === "delivered" ? "bg-green-500 text-black" : fulfillment.status === "pending" ? "bg-yellow-400 text-black" : "bg-red-700 text-white"}
31
+ min-w-[4.5rem] text-center`, children: fulfillment.status || "Cancelled" })
32
+ ] }),
33
+ JSON.stringify(fulfillment, null, 2),
34
+ /* @__PURE__ */ jsxs("div", { className: "flex justify-center items-center gap-3 mt-4", children: [
35
+ ((_b = fulfillment.labels) == null ? void 0 : _b.label_url) && /* @__PURE__ */ jsx(
36
+ "a",
37
+ {
38
+ href: `${(_c = fulfillment.labels) == null ? void 0 : _c.label_url}`,
39
+ target: "_blank",
40
+ rel: "noopener noreferrer",
41
+ className: "flex-1 px-4 py-1 text-xs bg-neutral-900/60 font-medium hover:bg-neutral-900/90 rounded-lg transition-colors text-center",
42
+ "aria-disabled": "false",
43
+ children: "Label"
44
+ }
45
+ ),
46
+ ((_d = fulfillment.labels) == null ? void 0 : _d.manifest_url) && /* @__PURE__ */ jsx(
47
+ "a",
48
+ {
49
+ href: `${(_e = fulfillment.labels) == null ? void 0 : _e.manifest_url}`,
50
+ target: "_blank",
51
+ rel: "noopener noreferrer",
52
+ className: "flex-1 px-4 py-1 text-xs bg-neutral-900/60 font-medium hover:bg-neutral-900/90 rounded-lg transition-colors text-center",
53
+ "aria-disabled": "false",
54
+ children: "Manifest"
55
+ }
56
+ ),
57
+ ((_f = fulfillment.labels) == null ? void 0 : _f.invoice_url) && /* @__PURE__ */ jsx(
58
+ "a",
59
+ {
60
+ href: `${(_g = fulfillment.labels) == null ? void 0 : _g.invoice_url}`,
61
+ target: "_blank",
62
+ rel: "noopener noreferrer",
63
+ className: "flex-1 px-4 py-1 text-xs bg-neutral-900/60 font-medium hover:bg-neutral-900/90 rounded-lg transition-colors text-center",
64
+ "aria-disabled": "false",
65
+ children: "Invoice"
66
+ }
67
+ )
68
+ ] })
69
+ ]
70
+ },
71
+ fulfillment.id
72
+ );
73
+ }) })
74
+ ] });
75
+ };
76
+ const config = defineWidgetConfig({
77
+ zone: "order.details.side.after"
78
+ });
79
+ export {
80
+ config,
81
+ ShiprocketTrackingWidget as default
82
+ };
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GET = GET;
4
+ async function GET(req, res) {
5
+ res.sendStatus(200);
6
+ }
7
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2FkbWluL3BsdWdpbi9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUVBLGtCQUtDO0FBTE0sS0FBSyxVQUFVLEdBQUcsQ0FDdkIsR0FBa0IsRUFDbEIsR0FBbUI7SUFFbkIsR0FBRyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN0QixDQUFDIn0=
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GET = GET;
4
+ async function GET(req, res) {
5
+ res.sendStatus(200);
6
+ }
7
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL3BsdWdpbi9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUVBLGtCQUtDO0FBTE0sS0FBSyxVQUFVLEdBQUcsQ0FDdkIsR0FBa0IsRUFDbEIsR0FBbUI7SUFFbkIsR0FBRyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUN0QixDQUFDIn0=
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.config = void 0;
7
+ exports.default = refreshShiprocketTokenJob;
8
+ const client_1 = __importDefault(require("../providers/shiprocket/client"));
9
+ async function refreshShiprocketTokenJob(container) {
10
+ const options = {
11
+ email: process.env.SHIPROCKET_EMAIL,
12
+ password: process.env.SHIPROCKET_PASSWORD,
13
+ };
14
+ const client = new client_1.default(options);
15
+ try {
16
+ await client["ensureAuthenticated"]?.();
17
+ // Optionally, log or store the refreshed token somewhere if needed
18
+ container.resolve("logger").info("Shiprocket token refreshed");
19
+ }
20
+ catch (err) {
21
+ // Optionally, log error
22
+ container.resolve("logger").error("Failed to refresh Shiprocket token", err);
23
+ }
24
+ finally {
25
+ client.dispose();
26
+ }
27
+ }
28
+ exports.config = {
29
+ name: "refresh-shiprocket-token",
30
+ schedule: "0 0 */8 * *", // every 8 days at 00:00
31
+ };
32
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVmcmVzaC1zaGlwcm9ja2V0LXRva2VuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2pvYnMvcmVmcmVzaC1zaGlwcm9ja2V0LXRva2VuLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUlBLDRDQWdCQztBQWxCRCw0RUFBNkQ7QUFFOUMsS0FBSyxVQUFVLHlCQUF5QixDQUFDLFNBQTBCO0lBQzlFLE1BQU0sT0FBTyxHQUE0QjtRQUNyQyxLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQkFBaUI7UUFDcEMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW9CO0tBQzdDLENBQUE7SUFDRCxNQUFNLE1BQU0sR0FBRyxJQUFJLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQzVDLElBQUksQ0FBQztRQUNELE1BQU0sTUFBTSxDQUFDLHFCQUFxQixDQUFDLEVBQUUsRUFBRSxDQUFBO1FBQ3ZDLG1FQUFtRTtRQUNuRSxTQUFTLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLElBQUksQ0FBQyw0QkFBNEIsQ0FBQyxDQUFBO0lBQ2xFLENBQUM7SUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ1gsd0JBQXdCO1FBQ3hCLFNBQVMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsS0FBSyxDQUFDLG9DQUFvQyxFQUFFLEdBQUcsQ0FBQyxDQUFBO0lBQ2hGLENBQUM7WUFBUyxDQUFDO1FBQ1AsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFBO0lBQ3BCLENBQUM7QUFDTCxDQUFDO0FBRVksUUFBQSxNQUFNLEdBQUc7SUFDbEIsSUFBSSxFQUFFLDBCQUEwQjtJQUNoQyxRQUFRLEVBQUUsYUFBYSxFQUFFLHdCQUF3QjtDQUNwRCxDQUFBIn0=
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleError = void 0;
4
+ const utils_1 = require("@medusajs/utils");
5
+ const handleError = (error) => {
6
+ const message = error.response?.data?.message || error.message;
7
+ const code = error.response?.status || 500;
8
+ if (code === 401) {
9
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNAUTHORIZED, "Authentication failed with Shiprocket");
10
+ }
11
+ if (code === 429) {
12
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Rate limit exceeded. Please try again later.");
13
+ }
14
+ if (code === 400 && error.response?.data?.errors) {
15
+ const validationErrors = Object.entries(error.response.data.errors)
16
+ .map(([field, msgs]) => `${field}: ${Array.isArray(msgs) ? msgs.join(", ") : msgs}`)
17
+ .join("; ");
18
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Validation failed: ${validationErrors}`);
19
+ }
20
+ throw new utils_1.MedusaError(code === 404
21
+ ? utils_1.MedusaError.Types.NOT_FOUND
22
+ : code === 400
23
+ ? utils_1.MedusaError.Types.INVALID_DATA
24
+ : utils_1.MedusaError.Types.UNEXPECTED_STATE, message);
25
+ };
26
+ exports.handleError = handleError;
27
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFuZGxlLWVycm9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL3Byb3ZpZGVycy9zaGlwcm9ja2V0L2NsaWVudC9oYW5kbGUtZXJyb3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsMkNBQTZDO0FBR3RDLE1BQU0sV0FBVyxHQUFHLENBQUMsS0FBa0MsRUFBUyxFQUFFO0lBQ3JFLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQUUsSUFBSSxFQUFFLE9BQU8sSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFBO0lBQzlELE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQUUsTUFBTSxJQUFJLEdBQUcsQ0FBQTtJQUUxQyxJQUFJLElBQUksS0FBSyxHQUFHLEVBQUUsQ0FBQztRQUNmLE1BQU0sSUFBSSxtQkFBVyxDQUNqQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLHVDQUF1QyxDQUMxQyxDQUFBO0lBQ0wsQ0FBQztJQUVELElBQUksSUFBSSxLQUFLLEdBQUcsRUFBRSxDQUFDO1FBQ2YsTUFBTSxJQUFJLG1CQUFXLENBQ2pCLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsOENBQThDLENBQ2pELENBQUE7SUFDTCxDQUFDO0lBRUQsSUFBSSxJQUFJLEtBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxRQUFRLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDO1FBQy9DLE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7YUFDOUQsR0FBRyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsS0FBSyxLQUFLLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO2FBQ25GLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUNmLE1BQU0sSUFBSSxtQkFBVyxDQUNqQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLHNCQUFzQixnQkFBZ0IsRUFBRSxDQUMzQyxDQUFBO0lBQ0wsQ0FBQztJQUVELE1BQU0sSUFBSSxtQkFBVyxDQUNqQixJQUFJLEtBQUssR0FBRztRQUNSLENBQUMsQ0FBQyxtQkFBVyxDQUFDLEtBQUssQ0FBQyxTQUFTO1FBQzdCLENBQUMsQ0FBQyxJQUFJLEtBQUssR0FBRztZQUNkLENBQUMsQ0FBQyxtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZO1lBQ2hDLENBQUMsQ0FBQyxtQkFBVyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsRUFDeEMsT0FBTyxDQUNWLENBQUE7QUFDTCxDQUFDLENBQUE7QUFwQ1ksUUFBQSxXQUFXLGVBb0N2QiJ9
@@ -0,0 +1,311 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const axios_1 = __importDefault(require("axios"));
7
+ const utils_1 = require("@medusajs/utils");
8
+ const authenticate_1 = require("./methods/authenticate");
9
+ const handle_error_1 = require("./handle-error");
10
+ class ShiprocketClient {
11
+ constructor(options) {
12
+ this.token = null;
13
+ this.tokenExpiry = null;
14
+ this.refreshTimeout = null;
15
+ this.isDisposed = false;
16
+ if (!options.email || !options.password) {
17
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Shiprocket API credentials are required");
18
+ }
19
+ this.email = options.email;
20
+ this.password = options.password;
21
+ this.pickup_location = options.pickup_location;
22
+ this.axios = axios_1.default.create({
23
+ baseURL: "https://apiv2.shiprocket.in/v1/external",
24
+ headers: { "Content-Type": "application/json" },
25
+ timeout: 10000,
26
+ });
27
+ process.on("beforeExit", () => this.dispose());
28
+ }
29
+ dispose() {
30
+ if (this.isDisposed)
31
+ return;
32
+ if (this.refreshTimeout) {
33
+ clearTimeout(this.refreshTimeout);
34
+ this.refreshTimeout = null;
35
+ }
36
+ this.token = null;
37
+ this.tokenExpiry = null;
38
+ this.isDisposed = true;
39
+ }
40
+ async ensureAuthenticated() {
41
+ if (!this.token || !this.tokenExpiry || Date.now() > this.tokenExpiry) {
42
+ const auth = await (0, authenticate_1.authenticate)(this.axios, this.email, this.password, this.isDisposed);
43
+ this.token = auth.token;
44
+ this.tokenExpiry = auth.tokenExpiry;
45
+ this.axios.defaults.headers.common["Authorization"] = `Bearer ${this.token}`;
46
+ if (this.refreshTimeout)
47
+ clearTimeout(this.refreshTimeout);
48
+ this.refreshTimeout = setTimeout(() => {
49
+ this.ensureAuthenticated().catch((error) => {
50
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, `Failed to refresh Shiprocket token: ${error.message}`);
51
+ });
52
+ }, 8 * 24 * 60 * 60 * 1000 // Refresh after 8 days
53
+ );
54
+ }
55
+ }
56
+ async calculate(data) {
57
+ await this.ensureAuthenticated();
58
+ try {
59
+ const response = await this.axios.get("/courier/serviceability/", { params: data });
60
+ const availableCouriers = response.data.data.available_courier_companies;
61
+ if (!availableCouriers?.length) {
62
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "No couriers available for this route");
63
+ }
64
+ const filtered = data.allowed_courier_ids?.length
65
+ ? availableCouriers.filter((c) => data.allowed_courier_ids.includes(c.id))
66
+ : availableCouriers;
67
+ if (!filtered?.length) {
68
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "No allowed couriers available for this route");
69
+ }
70
+ const cheapest = filtered.reduce((min, curr) => Number(curr.rate) < Number(min.rate) ? curr : min);
71
+ return Math.ceil(Number(cheapest?.rate) || 0);
72
+ }
73
+ catch (error) {
74
+ (0, handle_error_1.handleError)(error);
75
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Rate calculation failed unexpectedly");
76
+ }
77
+ }
78
+ async create(fulfillment, items, order) {
79
+ await this.ensureAuthenticated();
80
+ const safe = (v, fallback) => (v != null ? v : fallback);
81
+ const orderItemMap = new Map();
82
+ if (Array.isArray(order.items)) {
83
+ order.items.forEach((orderItem) => {
84
+ orderItemMap.set(orderItem.id, orderItem);
85
+ });
86
+ }
87
+ let totalWeight = 0;
88
+ let totalLength = 0;
89
+ let totalBreadth = 0;
90
+ let totalHeight = 0;
91
+ try {
92
+ const order_date = new Date(order.created_at)
93
+ .toLocaleString("en-GB", {
94
+ day: "2-digit",
95
+ month: "2-digit",
96
+ year: "numeric",
97
+ hour: "2-digit",
98
+ minute: "2-digit",
99
+ hour12: false,
100
+ })
101
+ .replace(",", "")
102
+ .replace(/\//g, "-");
103
+ const totalCost = items.reduce((sum, fi) => {
104
+ const orderItem = orderItemMap.get(fi.line_item_id);
105
+ if (!orderItem) {
106
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Fulfillment item ${fi.id} (${fi.title}) has no matching order item with line_item_id: ${fi.line_item_id}`);
107
+ }
108
+ const unit = Number(orderItem.unit_price ?? orderItem.detail?.unit_price ?? 0);
109
+ const qty = Number(fi.quantity ?? fi.raw_quantity?.value ?? 0);
110
+ if (!unit || !qty) {
111
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Missing unit price or quantity for fulfillment item: ${JSON.stringify(fi)}`);
112
+ }
113
+ return sum + unit * qty;
114
+ }, 0);
115
+ const shipping = order.shipping_address || fulfillment?.delivery_address || {};
116
+ const billing = order.customer || {};
117
+ const region = order.region || {};
118
+ items.forEach((item) => {
119
+ const orderItem = orderItemMap.get(item.line_item_id);
120
+ if (!orderItem) {
121
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Order item not found for fulfillment item: ${item.title} (line_item_id: ${item.line_item_id})`);
122
+ }
123
+ const variant = orderItem.variant;
124
+ if (!variant) {
125
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Variant data not found for order item: ${orderItem.id}`);
126
+ }
127
+ const weight = Number(variant.weight || 0) / 1000;
128
+ const length = Number(variant.length || 0);
129
+ const breadth = Number(variant.width || 0);
130
+ const height = Number(variant.height || 0);
131
+ if (!weight || !length || !breadth || !height) {
132
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, `Missing dimensions/weight for item "${item.title}" (Order Item: ${orderItem.id}, Variant: ${variant.id}).
133
+ Please set weight, length, width, and height in the product variant settings in Medusa Admin.`);
134
+ }
135
+ const quantity = Number(item.quantity || item.raw_quantity?.value || 1);
136
+ totalWeight += weight * quantity;
137
+ totalLength = Math.max(totalLength, length);
138
+ totalBreadth = Math.max(totalBreadth, breadth);
139
+ totalHeight += height * quantity;
140
+ });
141
+ const orderData = {
142
+ order_id: order.id + "-" + Math.random().toString().slice(2, 12),
143
+ order_date,
144
+ pickup_location: this.pickup_location || "Primary",
145
+ billing_customer_name: safe(billing.first_name, ""),
146
+ billing_last_name: safe(billing.last_name, ""),
147
+ billing_address: safe(shipping.address_1, ""),
148
+ billing_address_2: safe(shipping.address_2, ""),
149
+ billing_city: safe(shipping.city, ""),
150
+ billing_pincode: Number(safe(shipping.postal_code, "110001")),
151
+ billing_state: safe(shipping.province, ""),
152
+ billing_country: safe(region.name, "India"),
153
+ billing_email: safe(billing.email, ""),
154
+ billing_phone: Number(safe(shipping.phone, "9999999999").toString().replace(/[^0-9]/g, "")),
155
+ shipping_is_billing: true,
156
+ shipping_customer_name: safe(shipping.first_name, ""),
157
+ shipping_last_name: safe(shipping.last_name, ""),
158
+ shipping_address: safe(shipping.address_1, ""),
159
+ shipping_address_2: safe(shipping.address_2, ""),
160
+ shipping_city: safe(shipping.city, ""),
161
+ shipping_pincode: Number(safe(shipping.postal_code, "110001")),
162
+ shipping_country: safe(region.name, "India"),
163
+ shipping_state: safe(shipping.province, ""),
164
+ shipping_email: safe(billing.email, ""),
165
+ shipping_phone: Number(safe(shipping.phone, "9999999999").toString().replace(/[^0-9]/g, "")),
166
+ order_items: items.map((item) => {
167
+ const orderItem = orderItemMap.get(item.line_item_id);
168
+ const variant = orderItem.variant;
169
+ const selling_price = Math.round(Number(orderItem.unit_price || orderItem.detail?.unit_price || 0));
170
+ const hsn_code = variant.hs_code ? Number(variant.hs_code) : 0;
171
+ return {
172
+ name: item.title,
173
+ sku: variant.sku || orderItem.variant_sku || item.sku || item.id,
174
+ units: Number(item.quantity || item.raw_quantity?.value || 1),
175
+ selling_price,
176
+ discount: "",
177
+ tax: "",
178
+ hsn: hsn_code,
179
+ };
180
+ }),
181
+ payment_method: "Prepaid",
182
+ shipping_charges: 0,
183
+ giftwrap_charges: 0,
184
+ transaction_charges: 0,
185
+ total_discount: Number(order.discount_total || 0),
186
+ sub_total: totalCost,
187
+ length: totalLength,
188
+ breadth: totalBreadth,
189
+ height: totalHeight,
190
+ weight: totalWeight,
191
+ };
192
+ const orderCreated = await this.axios
193
+ .post("/orders/create/adhoc", orderData)
194
+ .catch((err) => {
195
+ const apiError = err;
196
+ const firstError = apiError.response?.data?.errors
197
+ ? Object.values(apiError.response.data.errors)[0][0]
198
+ : "Unknown error";
199
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, firstError);
200
+ });
201
+ if (!orderCreated.data?.shipment_id) {
202
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Failed to create Shiprocket order");
203
+ }
204
+ const awbCreated = await this.axios.post(`/courier/assign/awb`, {
205
+ shipment_id: orderCreated.data.shipment_id,
206
+ courier_id: orderCreated.data.courier_company_id,
207
+ });
208
+ if (awbCreated.data.awb_assign_status !== 1) {
209
+ try {
210
+ await this.cancel(orderCreated.data.order_id);
211
+ }
212
+ catch (err) {
213
+ // swallow cancel error but log upstream if needed
214
+ }
215
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_ALLOWED, awbCreated.data.message || "AWB assignment failed");
216
+ }
217
+ return {
218
+ order_id: orderCreated.data.order_id,
219
+ shipment_id: orderCreated.data.shipment_id,
220
+ status: orderCreated.data.status,
221
+ status_code: orderCreated.data.status_code,
222
+ awb: awbCreated.data.response.data.awb_code,
223
+ courier_company_id: awbCreated.data.response.data.courier_company_id,
224
+ courier_name: orderCreated.data.courier_name,
225
+ tracking_number: awbCreated.data.response.data.awb_code,
226
+ tracking_url: "https://shiprocket.co/tracking/" + awbCreated.data.response.data.awb_code,
227
+ label_url: orderCreated.data.label_url,
228
+ shipping_charges: orderCreated.data.shipping_charges,
229
+ payment_method: orderCreated.data.payment_method,
230
+ transaction_charges: orderCreated.data.transaction_charges,
231
+ giftwrap_charges: orderCreated.data.giftwrap_charges,
232
+ };
233
+ }
234
+ catch (error) {
235
+ (0, handle_error_1.handleError)(error);
236
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Order creation failed unexpectedly");
237
+ }
238
+ }
239
+ async cancel(orderId) {
240
+ await this.ensureAuthenticated();
241
+ try {
242
+ await this.axios.post(`/orders/cancel`, { ids: [orderId] });
243
+ }
244
+ catch (error) {
245
+ (0, handle_error_1.handleError)(error);
246
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, error.message || "Order cancellation failed unexpectedly");
247
+ }
248
+ }
249
+ async getTrackingInfo(trackingNumber) {
250
+ await this.ensureAuthenticated();
251
+ try {
252
+ const response = await this.axios.get(`/courier/track/awb/${trackingNumber}`);
253
+ return response.data;
254
+ }
255
+ catch (error) {
256
+ (0, handle_error_1.handleError)(error);
257
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Tracking info retrieval failed unexpectedly");
258
+ }
259
+ }
260
+ async createReturn(fulfillment) {
261
+ await this.ensureAuthenticated();
262
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_ALLOWED, "Not Implemented. Please create a return order manually.");
263
+ return {
264
+ order_id: fulfillment.external_id,
265
+ shipment_id: fulfillment.external_id,
266
+ status: "success",
267
+ status_code: 200,
268
+ awb: "1234567890",
269
+ courier_company_id: 1,
270
+ courier_name: "DHL",
271
+ tracking_number: "1234567890",
272
+ tracking_url: "",
273
+ label_url: "",
274
+ payment_method: "cod",
275
+ shipping_charges: "0",
276
+ transaction_charges: "0",
277
+ giftwrap_charges: "0",
278
+ };
279
+ }
280
+ async createDocuments(fulfillment) {
281
+ await this.ensureAuthenticated();
282
+ const manifest = await this.axios.get(`/manifests/generate`, {
283
+ params: { order_ids: [fulfillment.shipment_id] },
284
+ });
285
+ const label = await this.axios.get(`/courier/generate/label`, {
286
+ params: { shipment_id: [fulfillment.shipment_id] },
287
+ });
288
+ const invoice = await this.axios.get(`/orders/print/invoice`, {
289
+ params: { ids: [fulfillment.order_id] },
290
+ });
291
+ return {
292
+ label: label[0].label_created === 1 ? label[0].label_url : "",
293
+ manifest: manifest[0].status === 1 ? manifest[0].manifest_url : "",
294
+ invoice: invoice[0].is_invoice_created ? invoice[0].invoice_url : "",
295
+ };
296
+ }
297
+ async generateLabel(fulfillment) {
298
+ const label = await this.axios.get(`/courier/generate/label`, {
299
+ params: { shipment_id: [fulfillment.shipment_id] },
300
+ });
301
+ return label[0].label_url;
302
+ }
303
+ async generateInvoice(fulfillment) {
304
+ const invoice = await this.axios.get(`/orders/print/invoice`, {
305
+ params: { ids: [fulfillment.order_id] },
306
+ });
307
+ return invoice[0].invoice_url;
308
+ }
309
+ }
310
+ exports.default = ShiprocketClient;
311
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvcHJvdmlkZXJzL3NoaXByb2NrZXQvY2xpZW50L2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsa0RBQTRDO0FBQzVDLDJDQUE2QztBQUM3Qyx5REFBcUQ7QUFDckQsaURBQTRDO0FBVTVDLE1BQU0sZ0JBQWdCO0lBVWxCLFlBQVksT0FBZ0M7UUFMcEMsVUFBSyxHQUFrQixJQUFJLENBQUE7UUFDM0IsZ0JBQVcsR0FBa0IsSUFBSSxDQUFBO1FBQ2pDLG1CQUFjLEdBQTBCLElBQUksQ0FBQTtRQUM1QyxlQUFVLEdBQUcsS0FBSyxDQUFBO1FBR3RCLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ3RDLE1BQU0sSUFBSSxtQkFBVyxDQUNqQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLHlDQUF5QyxDQUM1QyxDQUFBO1FBQ0wsQ0FBQztRQUNELElBQUksQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQTtRQUMxQixJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUE7UUFDaEMsSUFBSSxDQUFDLGVBQWUsR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFBO1FBQzlDLElBQUksQ0FBQyxLQUFLLEdBQUcsZUFBSyxDQUFDLE1BQU0sQ0FBQztZQUN0QixPQUFPLEVBQUUseUNBQXlDO1lBQ2xELE9BQU8sRUFBRSxFQUFFLGNBQWMsRUFBRSxrQkFBa0IsRUFBRTtZQUMvQyxPQUFPLEVBQUUsS0FBSztTQUNqQixDQUFDLENBQUE7UUFDRixPQUFPLENBQUMsRUFBRSxDQUFDLFlBQVksRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQTtJQUNsRCxDQUFDO0lBRUQsT0FBTztRQUNILElBQUksSUFBSSxD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
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.authenticate = void 0;
4
+ const utils_1 = require("@medusajs/utils");
5
+ const handle_error_1 = require("../handle-error");
6
+ /**
7
+ * Authenticates with the Shiprocket API to get a token.
8
+ * @param axios - The Axios instance to use for the request.
9
+ * @param email - The user's email.
10
+ * @param password - The user's password.
11
+ * @param isDisposed - Whether the client is disposed.
12
+ * @returns The authentication token and its expiry time.
13
+ */
14
+ const authenticate = async (axios, email, password, isDisposed) => {
15
+ if (isDisposed) {
16
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Cannot authenticate disposed client");
17
+ }
18
+ try {
19
+ const response = await axios.post("/auth/login", {
20
+ email,
21
+ password,
22
+ });
23
+ if (!response.data.token) {
24
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "No token received in authentication response");
25
+ }
26
+ return {
27
+ token: response.data.token,
28
+ // Token valid for 10 days, refresh after 8
29
+ tokenExpiry: Date.now() + 8 * 24 * 60 * 60 * 1000,
30
+ };
31
+ }
32
+ catch (error) {
33
+ (0, handle_error_1.handleError)(error);
34
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Authentication failed unexpectedly");
35
+ }
36
+ };
37
+ exports.authenticate = authenticate;
38
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aGVudGljYXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL3Byb3ZpZGVycy9zaGlwcm9ja2V0L2NsaWVudC9tZXRob2RzL2F1dGhlbnRpY2F0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwyQ0FBNkM7QUFFN0Msa0RBQTZDO0FBRzdDOzs7Ozs7O0dBT0c7QUFDSSxNQUFNLFlBQVksR0FBRyxLQUFLLEVBQzdCLEtBQW9CLEVBQ3BCLEtBQWEsRUFDYixRQUFnQixFQUNoQixVQUFtQixFQUM0QixFQUFFO0lBQ2pELElBQUksVUFBVSxFQUFFLENBQUM7UUFDYixNQUFNLElBQUksbUJBQVcsQ0FDakIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEVBQ2xDLHFDQUFxQyxDQUN4QyxDQUFBO0lBQ0wsQ0FBQztJQUVELElBQUksQ0FBQztRQUNELE1BQU0sUUFBUSxHQUFHLE1BQU0sS0FBSyxDQUFDLElBQUksQ0FBeUIsYUFBYSxFQUFFO1lBQ3JFLEtBQUs7WUFDTCxRQUFRO1NBQ1gsQ0FBQyxDQUFBO1FBRUYsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDdkIsTUFBTSxJQUFJLG1CQUFXLENBQ2pCLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsOENBQThDLENBQ2pELENBQUE7UUFDTCxDQUFDO1FBRUQsT0FBTztZQUNILEtBQUssRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUs7WUFDMUIsMkNBQTJDO1lBQzNDLFdBQVcsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUk7U0FDcEQsQ0FBQTtJQUNMLENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2IsSUFBQSwwQkFBVyxFQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ2xCLE1BQU0sSUFBSSxtQkFBVyxDQUNqQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsRUFDbEMsb0NBQW9DLENBQ3ZDLENBQUE7SUFDTCxDQUFDO0FBQ0wsQ0FBQyxDQUFBO0FBdENZLFFBQUEsWUFBWSxnQkFzQ3hCIn0=
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvcHJvdmlkZXJzL3NoaXByb2NrZXQvY2xpZW50L3R5cGVzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIifQ==
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const utils_1 = require("@medusajs/framework/utils");
7
+ const service_1 = __importDefault(require("./service"));
8
+ exports.default = (0, utils_1.ModuleProvider)(utils_1.Modules.FULFILLMENT, {
9
+ services: [service_1.default],
10
+ });
11
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvcHJvdmlkZXJzL3NoaXByb2NrZXQvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxxREFBbUU7QUFDbkUsd0RBQTREO0FBRTVELGtCQUFlLElBQUEsc0JBQWMsRUFBQyxlQUFPLENBQUMsV0FBVyxFQUFFO0lBQy9DLFFBQVEsRUFBRSxDQUFDLGlCQUFvQyxDQUFDO0NBQ25ELENBQUMsQ0FBQSJ9
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const utils_1 = require("@medusajs/framework/utils");
7
+ const client_1 = __importDefault(require("./client"));
8
+ class ShipRocketFulfillmentProviderService extends utils_1.AbstractFulfillmentProviderService {
9
+ /**
10
+ * Constructs a new instance of the ShipRocketFulfillmentProviderService.
11
+ * @param {Logger} logger - The logger instance.
12
+ * @param {Options} options - The options for the Shiprocket client.
13
+ */
14
+ constructor({ logger }, options) {
15
+ super();
16
+ this.logger_ = logger;
17
+ this.options_ = options;
18
+ this.client = new client_1.default({
19
+ email: options.email,
20
+ password: options.password,
21
+ pickup_location: options.pickup_location,
22
+ });
23
+ }
24
+ /**
25
+ * Returns the fulfillment options for Shiprocket.
26
+ * @returns An array of fulfillment options.
27
+ */
28
+ async getFulfillmentOptions() {
29
+ return [
30
+ {
31
+ id: "Standard Shipping",
32
+ name: "Standard Shipping",
33
+ is_return: false,
34
+ },
35
+ {
36
+ id: "Return Shipping",
37
+ name: "Return Shipping",
38
+ is_return: true,
39
+ },
40
+ ];
41
+ }
42
+ /**
43
+ * Determines whether the fulfillment option can calculate the shipping rate.
44
+ * @param data - The fulfillment option data.
45
+ * @returns A promise that resolves to a boolean indicating whether the option can calculate the rate.
46
+ */
47
+ async canCalculate(data) {
48
+ return true;
49
+ }
50
+ /**
51
+ * Calculates the shipping rate for a given order.
52
+ * @param optionData - The fulfillment option data.
53
+ * @param data - The fulfillment data.
54
+ * @param context - The fulfillment context.
55
+ * @returns The calculated shipping rate.
56
+ * @throws {Error} If either pickup or delivery postcodes are missing.
57
+ * @throws {Error} If weight is missing.
58
+ */
59
+ async calculatePrice(optionData, data, context) {
60
+ const params = {
61
+ pickup_postcode: context["from_location"]?.address?.postal_code,
62
+ delivery_postcode: context["shipping_address"]?.postal_code,
63
+ weight: (context["items"]?.[0]?.metadata?.weight),
64
+ cod: (this.options_.cod !== "true") ? 0 : 1,
65
+ };
66
+ if (!params.pickup_postcode || !params.delivery_postcode) {
67
+ throw new Error("Both pickup and delivery postcodes are required for rate calculation.");
68
+ }
69
+ if (!params.weight) {
70
+ throw new Error("Weight is required for rate calculation.");
71
+ }
72
+ const price = await this.client.calculate(params);
73
+ return {
74
+ calculated_amount: price,
75
+ is_calculated_price_tax_inclusive: true,
76
+ };
77
+ }
78
+ /**
79
+ * Creates a fulfillment in Shiprocket.
80
+ * @param data - The fulfillment data.
81
+ * @param items - The items in the fulfillment.
82
+ * @param order - The order associated with the fulfillment.
83
+ * @param fulfillment - The fulfillment data.
84
+ * @returns The created fulfillment data.
85
+ */
86
+ async createFulfillment(data, items, order, fulfillment) {
87
+ try {
88
+ const externalData = await this.client.create(fulfillment, items, order);
89
+ const { label, manifest, invoice } = await this.client.createDocuments(externalData);
90
+ return {
91
+ data: {
92
+ ...(fulfillment || {}),
93
+ ...externalData,
94
+ },
95
+ labels: [
96
+ {
97
+ tracking_number: externalData.tracking_number || "",
98
+ tracking_url: externalData.tracking_url || "",
99
+ label_url: label || "",
100
+ invoice_url: invoice || "",
101
+ manifest_url: manifest || "",
102
+ },
103
+ ],
104
+ };
105
+ }
106
+ catch (err) {
107
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, (err?.message || err?.response?.data?.message || "Failed to create fulfillment"));
108
+ }
109
+ }
110
+ /**
111
+ * Cancels a fulfillment in Shiprocket.
112
+ * @param data - The fulfillment data.
113
+ * @throws {MedusaError} If the order ID is not provided.
114
+ */
115
+ async cancelFulfillment(data) {
116
+ const { order_id } = data;
117
+ if (!order_id) {
118
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Order ID is required");
119
+ }
120
+ await this.client.cancel(order_id);
121
+ }
122
+ /**
123
+ * Creates a return fulfillment in Shiprocket.
124
+ * @param fulfillment - The fulfillment data.
125
+ * @returns The created return fulfillment data.
126
+ */
127
+ async createReturnFulfillment(fulfillment) {
128
+ const externalData = await this.client.createReturn(fulfillment);
129
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_ALLOWED, "Not Implemented. Please create a return order manually.");
130
+ return {
131
+ data: {
132
+ ...(fulfillment || {}),
133
+ ...externalData,
134
+ },
135
+ labels: [
136
+ {
137
+ tracking_number: externalData.tracking_number || "",
138
+ tracking_url: externalData.tracking_url || "",
139
+ label_url: externalData.label_url || "",
140
+ },
141
+ ],
142
+ };
143
+ }
144
+ /**
145
+ * Retrieves the documents associated with a fulfillment.
146
+ * @param data - The fulfillment data.
147
+ * @returns An array of documents associated with the fulfillment.
148
+ */
149
+ async getFulfillmentDocuments(data) {
150
+ const invoice = await this.client.generateInvoice(data);
151
+ return invoice || [];
152
+ }
153
+ /**
154
+ * Retrieves the documents associated with a shipment.
155
+ * @param data - The shipment data.
156
+ * @returns An array of documents associated with the shipment.
157
+ */
158
+ async getShipmentDocuments(data) {
159
+ const label = await this.client.generateLabel(data);
160
+ return label || [];
161
+ }
162
+ /**
163
+ * Retrieves the documents associated with a return fulfillment.
164
+ * @param data - The return fulfillment data.
165
+ * @returns An empty array, as document retrieval is not supported for returns.
166
+ */
167
+ async getReturnDocuments(data) {
168
+ return [];
169
+ }
170
+ /**
171
+ * Retrieves the documents associated with a fulfillment, given its data and the type of documents to retrieve.
172
+ * @param fulfillmentData - The fulfillment data.
173
+ * @param documentType - The type of documents to retrieve.
174
+ * @returns A promise that resolves once the documents have been retrieved.
175
+ * @remarks Document retrieval is not supported by this provider.
176
+ */
177
+ async retrieveDocuments(fulfillmentData, documentType) {
178
+ this.logger_.debug("Document retrieval not supported");
179
+ }
180
+ /**
181
+ * Validates the fulfillment data to ensure it has the required information.
182
+ * If the external ID is not present, it will be generated automatically.
183
+ * @param optionData - The data provided by the user when creating a fulfillment option.
184
+ * @param data - The data provided by the user when creating a fulfillment.
185
+ * @param context - The context of the fulfillment.
186
+ * @returns A promise that resolves with the validated fulfillment data.
187
+ */
188
+ async validateFulfillmentData(optionData, data, context) {
189
+ return {
190
+ ...data,
191
+ external_id: `temp_${Date.now()}`,
192
+ };
193
+ }
194
+ /**
195
+ * Validates a fulfillment option to ensure it has the required information.
196
+ * @param data - The data provided by the user when creating a fulfillment option.
197
+ * @returns A promise that resolves with a boolean indicating whether the option is valid.
198
+ * @remarks A fulfillment option is valid if it has an external ID.
199
+ */
200
+ async validateOption(data) {
201
+ return data.external_id !== undefined;
202
+ }
203
+ }
204
+ ShipRocketFulfillmentProviderService.identifier = "shiprocket";
205
+ exports.default = ShipRocketFulfillmentProviderService;
206
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9wcm92aWRlcnMvc2hpcHJvY2tldC9zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEscURBQTRGO0FBYTVGLHNEQUF3QztBQWF4QyxNQUFNLG9DQUFxQyxTQUFRLDBDQUFrQztJQU9qRjs7OztPQUlHO0lBQ0gsWUFBWSxFQUFFLE1BQU0sRUFBd0IsRUFBRSxPQUFnQjtRQUMxRCxLQUFLLEVBQUUsQ0FBQztRQUNSLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDO1FBQ3hCLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxnQkFBZ0IsQ0FBQztZQUMvQixLQUFLLEVBQUUsT0FBTyxDQUFDLEtBQUs7WUFDcEIsUUFBUSxFQUFFLE9BQU8sQ0FBQyxRQUFRO1lBQzFCLGVBQWUsRUFBRSxPQUFPLENBQUMsZUFBZTtTQUMzQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsS0FBSyxDQUFDLHFCQUFxQjtRQUN2QixPQUFPO1lBQ0g7Z0JBQ0ksRUFBRSxFQUFFLG1CQUFtQjtnQkFDdkIsSUFBSSxFQUFFLG1CQUFtQjtnQkFDekIsU0FBUyxFQUFFLEtBQUs7YUFDbkI7WUFDRDtnQkFDSSxFQUFFLEVBQUUsaUJBQWlCO2dCQUNyQixJQUFJLEVBQUUsaUJBQWlCO2dCQUN2QixTQUFTLEVBQUUsSUFBSTthQUNsQjtTQUNKLENBQUM7SUFDTixDQUFDO0lBR0Q7Ozs7T0FJRztJQUNILEtBQUssQ0FBQyxZQUFZLENBQUMsSUFBNkI7UUFDNUMsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUNEOzs7Ozs7OztPQVFHO0lBRUgsS0FBSyxDQUFDLGNBQWMsQ0FDaEIsVUFBeUQsRUFDekQsSUFBNkMsRUFDN0MsT0FBbUQ7UUFFbkQsTUFBTSxNQUFNLEdBQUc7WUFD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
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvcHJvdmlkZXJzL3NoaXByb2NrZXQvdHlwZXMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCheapestCourier = getCheapestCourier;
4
+ exports.filterAllowedCouriers = filterAllowedCouriers;
5
+ exports.slugify = slugify;
6
+ function getCheapestCourier(couriers) {
7
+ const validCouriers = couriers.filter((c) => !!c.rate && !isNaN(Number(c.rate)));
8
+ if (validCouriers.length === 0)
9
+ return null;
10
+ return validCouriers.reduce((min, curr) => {
11
+ return Number(curr.rate) < Number(min.rate) ? curr : min;
12
+ });
13
+ }
14
+ function filterAllowedCouriers(couriers, allowedCourierIds) {
15
+ return couriers.filter((courier) => allowedCourierIds.includes(courier.courier_company_id));
16
+ }
17
+ function slugify(str) {
18
+ return str
19
+ .toLowerCase()
20
+ .trim()
21
+ .replace(/[^a-z0-9\s-]/g, '')
22
+ .replace(/\s+/g, '-')
23
+ .replace(/-+/g, '-');
24
+ }
25
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvcHJvdmlkZXJzL3NoaXByb2NrZXQvdXRpbHMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFFQSxnREFVQztBQUVELHNEQU9DO0FBRUQsMEJBT0M7QUE1QkQsU0FBZ0Isa0JBQWtCLENBQUMsUUFBbUI7SUFDbEQsTUFBTSxhQUFhLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FDakMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FDNUMsQ0FBQztJQUVGLElBQUksYUFBYSxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFFNUMsT0FBTyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFO1FBQ3RDLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztJQUM3RCxDQUFDLENBQUMsQ0FBQztBQUNQLENBQUM7QUFFRCxTQUFnQixxQkFBcUIsQ0FDakMsUUFBbUIsRUFDbkIsaUJBQTJCO0lBRTNCLE9BQU8sUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQy9CLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsa0JBQWtCLENBQUMsQ0FDekQsQ0FBQztBQUNOLENBQUM7QUFFRCxTQUFnQixPQUFPLENBQUMsR0FBVztJQUMvQixPQUFPLEdBQUc7U0FDTCxXQUFXLEVBQUU7U0FDYixJQUFJLEVBQUU7U0FDTixPQUFPLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQztTQUM1QixPQUFPLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQztTQUNwQixPQUFPLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQzdCLENBQUMifQ==
package/README.md ADDED
@@ -0,0 +1,236 @@
1
+ <h1 align="center">
2
+ <br>
3
+ <a href="http://www.shiprocket.in"><img src="https://i.postimg.cc/zGzTRdqp/id-Nga-I3rk-T-logos.png" alt="Markdownify" width="200"></a>
4
+ <br>
5
+ for Medusa 2.0+
6
+ <br>
7
+ </h1>
8
+
9
+ <p align="center">
10
+ <img src="https://img.shields.io/npm/v/medusa-cashfree-payment-plugin" alt="medusa-cashfree-payment-plugin">
11
+ <img src="https://img.shields.io/npm/dw/medusa-cashfree-payment-plugin" alt="medusa-cashfree-payment-plugin">
12
+ <img src="https://img.shields.io/github/contributors/SAM-AEL/medusa-cashfree-payment-plugin" alt="medusa-cashfree-payment-plugin">
13
+ <img src="https://img.shields.io/github/last-commit/SAM-AEL/medusa-cashfree-payment-plugin" alt="medusa-cashfree-payment-plugin">
14
+ </p>
15
+
16
+ <h4 align="center">From checkout to doorstep — simplify logistics with <a href="https://www.shiprocket.in" target="_blank">Shiprocket</a> for Medusa.</h4>
17
+
18
+ <p align="center">
19
+ <a href="#-features">Features</a> •
20
+ <a href="#%EF%B8%8F-installation">Installation</a> •
21
+ <a href="#-setup-guide">Setup Guide</a> •
22
+ <a href="#-api-reference">API Reference</a> •
23
+ <a href="#-troubleshooting">Troubleshooting</a> •
24
+ <a href="#-contributing">Contributing</a> •
25
+ <a href="#-license">License</a>
26
+ </p>
27
+
28
+ ## ✨ Features
29
+
30
+ - 🚚 **Seamless Shipping** - _Create and manage shipments directly from Medusa admin panel_
31
+
32
+ - 💸 **Automated Rate Calculation** - _Fetch real-time courier rates at checkout_
33
+
34
+ - ❌ **Easy Cancellations** - _Cancel shipments instantly from Medusa_
35
+
36
+ - 📦 **Pickup Location Support** - _Configure and use multiple Shiprocket pickup points_
37
+
38
+ - 🌍 **India-first Logistics** - _Optimized for Indian e-commerce and Shiprocket’s courier network_
39
+
40
+ ## 📋 Prerequisites
41
+
42
+ - [MedusaJS](https://docs.medusajs.com/) 2 store
43
+
44
+ - [Shiprocket](https://www.shiprocket.in/) account
45
+
46
+ ## 🚧 To Do:
47
+
48
+ - 💱 **Return Shipping** - _Initiate Refund and replacement directly through Admin Dashboard_
49
+
50
+ - 🔗 **Webhooks integration** - _Stay updated with shipment updates in Admin Dashboard_
51
+
52
+ - 🔎 **Live Tracking** - _Get shipment status and tracking updates without leaving Medusa Admin Dashboard_
53
+
54
+ - 📚 **Label, Manifest and Invoice** - _Directly accessible in Medusa Admin_
55
+ - **_Rewrite the plugin with more optimizations and code cleanup._**
56
+
57
+ ## 🛠️ Installation
58
+
59
+ #### Step 1: Install the Plugin
60
+
61
+ Choose your preferred package manager:
62
+
63
+ ```bash
64
+
65
+ # npm
66
+
67
+ npm install medusa-shiprocket-fulfillment-plugin
68
+
69
+
70
+
71
+ # yarn
72
+
73
+ yarn add medusa-shiprocket-fulfillment-plugin
74
+
75
+
76
+
77
+ # pnpm
78
+
79
+ pnpm add medusa-shiprocket-fulfillment-plugin
80
+
81
+ ```
82
+
83
+ #### Step 2: Configure Plugin
84
+
85
+ Add the plugin to your `medusa-config.js`:
86
+
87
+ ```javascript
88
+ module.exports = defineConfig({
89
+
90
+ // other configs
91
+
92
+ modules: [
93
+
94
+ // other plugins
95
+
96
+ {
97
+ resolve: "@medusajs/medusa/fulfillment",
98
+ options: {
99
+ providers: [
100
+ {
101
+ resolve:
102
+ "medusa-shiprocket-fulfillment-plugin/providers/shiprocket",
103
+ id: "shiprocket",
104
+ options: {
105
+ email: process.env.SHIPROCKET_EMAIL,
106
+ password: process.env.SHIPROCKET_PASSWORD,
107
+ pickup_location: process.env.SHIPROCKET_PICKUP_LOCATION,
108
+ },
109
+ },
110
+ ],
111
+ },
112
+ },
113
+ ],
114
+ plugins: [
115
+ {
116
+ resolve: "medusa-shiprocket-fulfillment-plugin",
117
+ options: {
118
+ email: process.env.SHIPROCKET_EMAIL,
119
+ password: process.env.SHIPROCKET_PASSWORD,
120
+ pickup_location: process.env.SHIPROCKET_PICKUP_LOCATION,
121
+ },
122
+ },
123
+ ],
124
+ });
125
+ ```
126
+
127
+ #### Step 3: Environment Variables
128
+
129
+ Create or update your `.env` file:
130
+
131
+ ```env
132
+
133
+ # Shiprocket Configuration
134
+
135
+ SHIPROCKET_EMAIL=your email
136
+ SHIPROCKET_PASSWORD=password
137
+ SHIPROCKET_PICKUP_LOCATION=Primary
138
+
139
+ ```
140
+
141
+ > ⚠️ **Security Note**: Never commit your production credentials to version control.
142
+
143
+ ### ⚙️ Configuration Options
144
+
145
+ | Option | Type | Required | Default | Description |
146
+ | ----------------- | ------ | -------- | ------- | ------------------------------------------------------------------------------------ |
147
+ | `email` | string | ✅ | - | Your Shiprocket account email |
148
+ | `password` | string | ✅ | - | Your Shiprocket account password |
149
+ | `pickup_location` | string | ✅ | - | The Shiprocket pickup location name (must match one created in Shiprocket dashboard) |
150
+
151
+ ### 🎯 Setup Guide
152
+
153
+ ### Enable Fulfillment Provider
154
+
155
+ 1. Navigate to **Medusa Admin → Settings → Regions**
156
+ 2. Select your target region - India (or any region you want Shiprocket to serve).
157
+ 3. In **Fulfillment Providers**, select `shiprocket`.
158
+ 4. Click **Save Changes**.
159
+
160
+ ---
161
+
162
+ ### Configure Shiprocket Credentials
163
+
164
+ 1. Go to your [Shiprocket Dashboard](https://app.shiprocket.in/).
165
+ 2. Ensure you have:
166
+ - **Email** and **Password** of your Shiprocket account.
167
+ - At least one **Pickup Location** set up (e.g., `Primary`).
168
+ 3. Add credentials to your `.env` file:
169
+
170
+ ### 🔧 API Reference
171
+
172
+ This plugin implements the complete `AbstractFulfillmentProvider` interface:
173
+
174
+ #### Core Methods
175
+
176
+ - `createFulfillment()` - Create a fulfillment in Shiprocket.
177
+ - `cancelFulfillment()` - Cancel a fulfillment in Shiprocket.
178
+ - `getFulfillmentDocuments()` - Retrieve labels, manifests, and invoices for a fulfillment.
179
+ - `getTrackingInfo()` - Get tracking information for a shipment.
180
+
181
+ #### Utility Methods
182
+
183
+ - `calculateShippingRate()` - Calculate shipping rates for an order.
184
+ - `createReturn()` - Create a return shipment in Shiprocket.
185
+ - `generateLabel()` - Generate shipping label for a fulfillment.
186
+ - `generateInvoice()` - Generate invoice for a fulfillment.
187
+
188
+ ### 🐛 Troubleshooting
189
+
190
+ **_Plugin not appearing in admin_**
191
+
192
+ - Follow the setup and reload the server.
193
+
194
+ **_Admin UI Widget not working_**
195
+
196
+ - Add the plugin to plugin import in medusa-config. reload the server.
197
+
198
+ ### Getting Help
199
+
200
+ - 📖 [Shiprocket API Documentation](https://api.shiprocket.in/)
201
+
202
+ - 💬 [MedusaJS Discord](https://discord.gg/medusajs)
203
+
204
+ - 🐛 [Report Issues](https://github.com/SAM-AEL/medusa-shiprocket-fulfillment-plugin/issues)
205
+
206
+ ### 🤝 Contributing
207
+
208
+ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
209
+
210
+ 1. Fork the repository
211
+
212
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
213
+
214
+ 3. Commit your changes (`git commit -m 'Add amazing feature'`)
215
+
216
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
217
+
218
+ 5. Open a Pull Request
219
+
220
+ ### 📄 License
221
+
222
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
223
+
224
+ ### 🙏 Acknowledgments
225
+
226
+ - [MedusaJS](https://medusajs.com/) - for the best open-source e-commerce platform.
227
+
228
+ - [Shiprocket](https://www.shiprocket.in/) - for making the life of a shipper easier.
229
+
230
+ ---
231
+
232
+ <h1 align="center">
233
+ <br>
234
+ Thank you 🫶
235
+ <br>
236
+ </h1>
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "medusa-shiprocket-fulfillment-plugin",
3
+ "version": "0.1.8",
4
+ "description": "Shiprocket Fulfillment Provider Plugin for MedusaJS 2",
5
+ "author": "SAM-AEL",
6
+ "homepage": "https://github.com/SAM-AEL",
7
+ "repository": "https://github.com/SAM-AEL/medusa-shiprocket-fulfillment-plugin",
8
+ "license": "MIT",
9
+ "files": [
10
+ ".medusa/server"
11
+ ],
12
+ "exports": {
13
+ "./package.json": "./package.json",
14
+ "./workflows": "./.medusa/server/src/workflows/index.js",
15
+ "./.medusa/server/src/modules/*": "./.medusa/server/src/modules/*/index.js",
16
+ "./modules/*": "./.medusa/server/src/modules/*/index.js",
17
+ "./providers/*": "./.medusa/server/src/providers/*/index.js",
18
+ "./*": "./.medusa/server/src/*.js"
19
+ },
20
+ "keywords": [
21
+ "medusa",
22
+ "plugin",
23
+ "medusa-plugin",
24
+ "medusa-v2",
25
+ "medusa-plugin-shipping"
26
+ ],
27
+ "scripts": {
28
+ "build": "medusa plugin:build",
29
+ "dev": "medusa plugin:develop",
30
+ "prepublishOnly": "medusa plugin:build"
31
+ },
32
+ "devDependencies": {
33
+ "@medusajs/admin-sdk": "2.4.0",
34
+ "@medusajs/cli": "2.4.0",
35
+ "@medusajs/framework": "2.4.0",
36
+ "@medusajs/icons": "2.4.0",
37
+ "@medusajs/medusa": "2.4.0",
38
+ "@medusajs/test-utils": "2.4.0",
39
+ "@medusajs/ui": "4.0.4",
40
+ "@mikro-orm/cli": "6.4.3",
41
+ "@mikro-orm/core": "6.4.3",
42
+ "@mikro-orm/knex": "6.4.3",
43
+ "@mikro-orm/migrations": "6.4.3",
44
+ "@mikro-orm/postgresql": "6.4.3",
45
+ "@swc/core": "1.5.7",
46
+ "@types/node": "^20.0.0",
47
+ "@types/react": "^18.3.2",
48
+ "@types/react-dom": "^18.2.25",
49
+ "awilix": "^8.0.1",
50
+ "pg": "^8.13.0",
51
+ "prop-types": "^15.8.1",
52
+ "react": "^18.2.0",
53
+ "react-dom": "^18.2.0",
54
+ "ts-node": "^10.9.2",
55
+ "typescript": "^5.6.2",
56
+ "vite": "^5.2.11",
57
+ "yalc": "^1.0.0-pre.53"
58
+ },
59
+ "peerDependencies": {
60
+ "@medusajs/admin-sdk": "2.4.0",
61
+ "@medusajs/cli": "2.4.0",
62
+ "@medusajs/framework": "2.4.0",
63
+ "@medusajs/icons": "2.4.0",
64
+ "@medusajs/medusa": "2.4.0",
65
+ "@medusajs/test-utils": "2.4.0",
66
+ "@medusajs/ui": "4.0.3",
67
+ "@mikro-orm/cli": "6.4.3",
68
+ "@mikro-orm/core": "6.4.3",
69
+ "@mikro-orm/knex": "6.4.3",
70
+ "@mikro-orm/migrations": "6.4.3",
71
+ "@mikro-orm/postgresql": "6.4.3",
72
+ "awilix": "^8.0.1",
73
+ "pg": "^8.13.0"
74
+ },
75
+ "engines": {
76
+ "node": ">=20"
77
+ }
78
+ }