medusa-pos-plugin 0.0.1
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.
- package/.medusa/server/src/admin/index.js +23 -0
- package/.medusa/server/src/admin/index.mjs +24 -0
- package/.medusa/server/src/api/admin/pos/catalog/route.js +139 -0
- package/.medusa/server/src/api/admin/pos/draft-orders/[id]/confirm-lite/route.js +41 -0
- package/.medusa/server/src/api/admin/pos/draft-orders/[id]/customer/route.js +68 -0
- package/.medusa/server/src/api/admin/pos/draft-orders/[id]/finalize/route.js +424 -0
- package/.medusa/server/src/api/admin/pos/draft-orders/[id]/items/route.js +452 -0
- package/.medusa/server/src/api/admin/pos/draft-orders/[id]/items/update/route.js +137 -0
- package/.medusa/server/src/api/admin/pos/draft-orders/[id]/manual-discount/route.js +386 -0
- package/.medusa/server/src/api/admin/pos/draft-orders/[id]/promotions/route.js +59 -0
- package/.medusa/server/src/api/admin/pos/draft-orders/[id]/route.js +178 -0
- package/.medusa/server/src/api/admin/pos/draft-orders/[id]/wallet-debit/route.js +220 -0
- package/.medusa/server/src/api/admin/pos/draft-orders/route.js +193 -0
- package/.medusa/server/src/api/admin/pos/manual-discounts/route.js +76 -0
- package/.medusa/server/src/api/admin/pos/orders/[id]/fulfill/route.js +103 -0
- package/.medusa/server/src/api/admin/pos/orders/[id]/returns/route.js +512 -0
- package/.medusa/server/src/api/admin/pos/orders/fulfill-pos-items.js +63 -0
- package/.medusa/server/src/api/admin/pos/orders/validators.js +62 -0
- package/.medusa/server/src/api/admin/pos/payments/config/route.js +15 -0
- package/.medusa/server/src/api/admin/pos/payments/device/[orderId]/route.js +39 -0
- package/.medusa/server/src/api/admin/pos/payments/device/cancel/route.js +27 -0
- package/.medusa/server/src/api/admin/pos/payments/device/route.js +107 -0
- package/.medusa/server/src/api/admin/pos/payments/qr/[qrId]/close/route.js +36 -0
- package/.medusa/server/src/api/admin/pos/payments/qr/[qrId]/route.js +42 -0
- package/.medusa/server/src/api/admin/pos/payments/qr/route.js +78 -0
- package/.medusa/server/src/index.js +8 -0
- package/.medusa/server/src/types.js +3 -0
- package/.medusa/server/src/utils/pos-draft-edit.js +178 -0
- package/.medusa/server/src/utils/pos-finalize.js +166 -0
- package/.medusa/server/src/utils/pos-inventory.js +265 -0
- package/.medusa/server/src/utils/pos-returns.js +339 -0
- package/.medusa/server/src/utils/razorpay-pos-device.js +122 -0
- package/.medusa/server/src/utils/razorpay-pos.js +134 -0
- package/README.md +39 -0
- package/index.js +9 -0
- package/package.json +82 -0
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POS_GUEST_EMAIL = void 0;
|
|
4
|
+
exports.toAmount = toAmount;
|
|
5
|
+
exports.toMinorUnit = toMinorUnit;
|
|
6
|
+
exports.digitsOnly = digitsOnly;
|
|
7
|
+
exports.normalizeEmail = normalizeEmail;
|
|
8
|
+
exports.isPosGuestEmail = isPosGuestEmail;
|
|
9
|
+
exports.isPosWalkInCustomer = isPosWalkInCustomer;
|
|
10
|
+
exports.syntheticPosEmail = syntheticPosEmail;
|
|
11
|
+
exports.localMobileDigits = localMobileDigits;
|
|
12
|
+
exports.toCanonicalPosPhone = toCanonicalPosPhone;
|
|
13
|
+
exports.getFulfilledQuantity = getFulfilledQuantity;
|
|
14
|
+
exports.getUnfulfilledQuantity = getUnfulfilledQuantity;
|
|
15
|
+
exports.getReturnableQuantity = getReturnableQuantity;
|
|
16
|
+
exports.getItemsToFulfill = getItemsToFulfill;
|
|
17
|
+
exports.getLineRefundAmount = getLineRefundAmount;
|
|
18
|
+
exports.sumRefundAmount = sumRefundAmount;
|
|
19
|
+
exports.roundMoney = roundMoney;
|
|
20
|
+
exports.applyWalletTender = applyWalletTender;
|
|
21
|
+
exports.posWalletDebitIdempotencyKey = posWalletDebitIdempotencyKey;
|
|
22
|
+
exports.decidePosWalletDebit = decidePosWalletDebit;
|
|
23
|
+
exports.decidePosWalletRefund = decidePosWalletRefund;
|
|
24
|
+
exports.formatPosPaymentLabel = formatPosPaymentLabel;
|
|
25
|
+
exports.hasWalletCustomerDetails = hasWalletCustomerDetails;
|
|
26
|
+
exports.resolveCreatedCustomerEmail = resolveCreatedCustomerEmail;
|
|
27
|
+
exports.extractReturnId = extractReturnId;
|
|
28
|
+
exports.getThrownErrorMessage = getThrownErrorMessage;
|
|
29
|
+
exports.POS_GUEST_EMAIL = "noreply+pos-guest@chocomelon.com";
|
|
30
|
+
function toAmount(value) {
|
|
31
|
+
if (value == null)
|
|
32
|
+
return 0;
|
|
33
|
+
if (typeof value === "number")
|
|
34
|
+
return Number.isFinite(value) ? value : 0;
|
|
35
|
+
if (typeof value === "bigint")
|
|
36
|
+
return Number(value);
|
|
37
|
+
if (typeof value === "string") {
|
|
38
|
+
const n = Number(value);
|
|
39
|
+
return Number.isFinite(n) ? n : 0;
|
|
40
|
+
}
|
|
41
|
+
if (typeof value === "object") {
|
|
42
|
+
const rec = value;
|
|
43
|
+
if (typeof rec.numeric === "number" && Number.isFinite(rec.numeric))
|
|
44
|
+
return rec.numeric;
|
|
45
|
+
if (typeof rec.numeric === "string") {
|
|
46
|
+
const n = Number(rec.numeric);
|
|
47
|
+
if (Number.isFinite(n))
|
|
48
|
+
return n;
|
|
49
|
+
}
|
|
50
|
+
if (typeof rec.value === "number" && Number.isFinite(rec.value))
|
|
51
|
+
return rec.value;
|
|
52
|
+
if (typeof rec.value === "string") {
|
|
53
|
+
const n = Number(rec.value);
|
|
54
|
+
if (Number.isFinite(n))
|
|
55
|
+
return n;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const n = Number(value);
|
|
59
|
+
return Number.isFinite(n) ? n : 0;
|
|
60
|
+
}
|
|
61
|
+
function toMinorUnit(amount) {
|
|
62
|
+
return Math.round(amount * 100);
|
|
63
|
+
}
|
|
64
|
+
function digitsOnly(value) {
|
|
65
|
+
return (value ?? "").replace(/\D/g, "");
|
|
66
|
+
}
|
|
67
|
+
function normalizeEmail(value) {
|
|
68
|
+
return (value ?? "").trim().toLowerCase();
|
|
69
|
+
}
|
|
70
|
+
function isPosGuestEmail(email) {
|
|
71
|
+
return normalizeEmail(email) === exports.POS_GUEST_EMAIL;
|
|
72
|
+
}
|
|
73
|
+
/** Shared walk-in cart customer only. Phone-only customers are not walk-in. */
|
|
74
|
+
function isPosWalkInCustomer(input) {
|
|
75
|
+
if (localMobileDigits(input?.phone).length >= 8) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
return isPosGuestEmail(input?.email);
|
|
79
|
+
}
|
|
80
|
+
function syntheticPosEmail(phone) {
|
|
81
|
+
return `${digitsOnly(phone)}@pos.customer.local`;
|
|
82
|
+
}
|
|
83
|
+
function localMobileDigits(phone) {
|
|
84
|
+
const digits = digitsOnly(phone);
|
|
85
|
+
if (digits.length === 12 && digits.startsWith("91")) {
|
|
86
|
+
return digits.slice(2);
|
|
87
|
+
}
|
|
88
|
+
if (digits.length > 10) {
|
|
89
|
+
return digits.slice(-10);
|
|
90
|
+
}
|
|
91
|
+
return digits;
|
|
92
|
+
}
|
|
93
|
+
/** Persist POS mobiles as +91XXXXXXXXXX. Empty when no usable number. */
|
|
94
|
+
function toCanonicalPosPhone(phone) {
|
|
95
|
+
const trimmed = (phone ?? "").trim();
|
|
96
|
+
if (!trimmed)
|
|
97
|
+
return "";
|
|
98
|
+
const digits = digitsOnly(trimmed);
|
|
99
|
+
if (digits.length === 10)
|
|
100
|
+
return `+91${digits}`;
|
|
101
|
+
if (digits.length === 12 && digits.startsWith("91"))
|
|
102
|
+
return `+${digits}`;
|
|
103
|
+
if (trimmed.startsWith("+") && digits.length >= 10 && digits.length <= 15) {
|
|
104
|
+
return `+${digits}`;
|
|
105
|
+
}
|
|
106
|
+
return "";
|
|
107
|
+
}
|
|
108
|
+
function getFulfilledQuantity(item) {
|
|
109
|
+
return Math.max(0, Math.floor(toAmount(item.detail?.fulfilled_quantity)));
|
|
110
|
+
}
|
|
111
|
+
function getUnfulfilledQuantity(item) {
|
|
112
|
+
const quantity = Math.max(0, Math.floor(toAmount(item.quantity)));
|
|
113
|
+
return Math.max(0, quantity - getFulfilledQuantity(item));
|
|
114
|
+
}
|
|
115
|
+
function getReturnableQuantity(item) {
|
|
116
|
+
const quantity = Math.max(0, Math.floor(toAmount(item.quantity)));
|
|
117
|
+
const detail = item.detail ?? {};
|
|
118
|
+
const requested = Math.max(0, Math.floor(toAmount(detail.return_requested_quantity)));
|
|
119
|
+
const received = Math.max(0, Math.floor(toAmount(detail.return_received_quantity ?? detail.returned_quantity)));
|
|
120
|
+
const dismissed = Math.max(0, Math.floor(toAmount(detail.return_dismissed_quantity)));
|
|
121
|
+
const writtenOff = Math.max(0, Math.floor(toAmount(detail.written_off_quantity)));
|
|
122
|
+
return Math.max(0, quantity - requested - received - dismissed - writtenOff);
|
|
123
|
+
}
|
|
124
|
+
/** Remaining unfulfilled qty for selected lines so Medusa will allow a return. */
|
|
125
|
+
function getItemsToFulfill(items, selections) {
|
|
126
|
+
const byId = new Map(items.map((item) => [item.id, item]));
|
|
127
|
+
const toFulfill = [];
|
|
128
|
+
for (const selection of selections) {
|
|
129
|
+
const item = byId.get(selection.id);
|
|
130
|
+
if (!item)
|
|
131
|
+
continue;
|
|
132
|
+
const unfulfilled = getUnfulfilledQuantity(item);
|
|
133
|
+
if (unfulfilled <= 0)
|
|
134
|
+
continue;
|
|
135
|
+
toFulfill.push({ id: selection.id, quantity: unfulfilled });
|
|
136
|
+
}
|
|
137
|
+
return toFulfill;
|
|
138
|
+
}
|
|
139
|
+
function getLineRefundAmount(item, quantity) {
|
|
140
|
+
const qty = Math.max(0, quantity);
|
|
141
|
+
if (qty <= 0)
|
|
142
|
+
return 0;
|
|
143
|
+
const itemQty = Math.max(1, toAmount(item.quantity));
|
|
144
|
+
const unitPrice = toAmount(item.unit_price);
|
|
145
|
+
const fromTotal = toAmount(item.total) / itemQty;
|
|
146
|
+
const fromSubtotal = toAmount(item.subtotal) / itemQty;
|
|
147
|
+
const perUnit = Math.max(unitPrice, fromTotal, fromSubtotal);
|
|
148
|
+
return roundMoney(perUnit * qty);
|
|
149
|
+
}
|
|
150
|
+
function sumRefundAmount(items, selections) {
|
|
151
|
+
const byId = new Map(items.map((item) => [item.id, item]));
|
|
152
|
+
return roundMoney(selections.reduce((sum, selection) => {
|
|
153
|
+
const item = byId.get(selection.id);
|
|
154
|
+
if (!item)
|
|
155
|
+
return sum;
|
|
156
|
+
return sum + getLineRefundAmount(item, selection.quantity);
|
|
157
|
+
}, 0));
|
|
158
|
+
}
|
|
159
|
+
function roundMoney(amount) {
|
|
160
|
+
return Math.round(amount * 100) / 100;
|
|
161
|
+
}
|
|
162
|
+
function applyWalletTender(total, available, useWallet) {
|
|
163
|
+
const bill = Math.max(0, roundMoney(total));
|
|
164
|
+
if (!useWallet) {
|
|
165
|
+
return { applied: 0, remainder: bill };
|
|
166
|
+
}
|
|
167
|
+
const applied = roundMoney(Math.min(Math.max(0, available), bill));
|
|
168
|
+
return { applied, remainder: roundMoney(Math.max(0, bill - applied)) };
|
|
169
|
+
}
|
|
170
|
+
function posWalletDebitIdempotencyKey(draftOrderId) {
|
|
171
|
+
return `pos:draft:${draftOrderId}:wallet`;
|
|
172
|
+
}
|
|
173
|
+
function decidePosWalletDebit(input) {
|
|
174
|
+
if (input.isWalkIn) {
|
|
175
|
+
return {
|
|
176
|
+
ok: false,
|
|
177
|
+
status: 400,
|
|
178
|
+
message: "Wallet payment requires a registered customer",
|
|
179
|
+
type: "WALLET_REQUIRES_CUSTOMER",
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
if (!input.emailVerified && !input.phoneVerified) {
|
|
183
|
+
return {
|
|
184
|
+
ok: false,
|
|
185
|
+
status: 400,
|
|
186
|
+
message: "Wallet payment is only available for registered customers",
|
|
187
|
+
type: "WALLET_REQUIRES_REGISTERED",
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
const requested = roundMoney(input.requested);
|
|
191
|
+
if (!(requested > 0)) {
|
|
192
|
+
return {
|
|
193
|
+
ok: false,
|
|
194
|
+
status: 400,
|
|
195
|
+
message: "Wallet amount must be greater than zero",
|
|
196
|
+
type: "INVALID_DATA",
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
if (requested > roundMoney(input.available) + 0.001) {
|
|
200
|
+
return {
|
|
201
|
+
ok: false,
|
|
202
|
+
status: 400,
|
|
203
|
+
message: "Insufficient wallet balance",
|
|
204
|
+
type: "INSUFFICIENT_BALANCE",
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
const applied = roundMoney(Math.min(requested, Math.max(0, input.total), Math.max(0, input.available)));
|
|
208
|
+
if (!(applied > 0)) {
|
|
209
|
+
return {
|
|
210
|
+
ok: false,
|
|
211
|
+
status: 400,
|
|
212
|
+
message: "Insufficient wallet balance",
|
|
213
|
+
type: "INSUFFICIENT_BALANCE",
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
return { ok: true, applied };
|
|
217
|
+
}
|
|
218
|
+
function decidePosWalletRefund(input) {
|
|
219
|
+
if (!input.hasCustomer || input.isWalkIn) {
|
|
220
|
+
return {
|
|
221
|
+
ok: false,
|
|
222
|
+
status: 400,
|
|
223
|
+
message: "Wallet refund requires a registered customer",
|
|
224
|
+
type: "WALLET_REQUIRES_CUSTOMER",
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
if (!input.emailVerified && !input.phoneVerified) {
|
|
228
|
+
return {
|
|
229
|
+
ok: false,
|
|
230
|
+
status: 400,
|
|
231
|
+
message: "Verify this customer before refunding to wallet",
|
|
232
|
+
type: "WALLET_REQUIRES_REGISTERED",
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
return { ok: true };
|
|
236
|
+
}
|
|
237
|
+
function formatPosPaymentLabel(method, walletAmount) {
|
|
238
|
+
const wallet = toAmount(walletAmount);
|
|
239
|
+
if (typeof method !== "string" || !method.trim()) {
|
|
240
|
+
return wallet > 0 ? "Wallet" : "In-store POS";
|
|
241
|
+
}
|
|
242
|
+
const normalized = method.trim().toLowerCase();
|
|
243
|
+
const map = {
|
|
244
|
+
cash: "Cash",
|
|
245
|
+
upi: "UPI",
|
|
246
|
+
"upi-qr": "UPI",
|
|
247
|
+
upi_qr: "UPI",
|
|
248
|
+
card: "Card",
|
|
249
|
+
"pos-machine": "Card (POS Machine)",
|
|
250
|
+
pos_machine: "Card (POS Machine)",
|
|
251
|
+
razorpay: "Online Payment",
|
|
252
|
+
wallet: "Wallet",
|
|
253
|
+
};
|
|
254
|
+
const base = map[normalized] || method.replace(/[_-]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
255
|
+
if (wallet > 0 && normalized !== "wallet") {
|
|
256
|
+
return `Wallet + ${base}`;
|
|
257
|
+
}
|
|
258
|
+
return base;
|
|
259
|
+
}
|
|
260
|
+
function hasWalletCustomerDetails(input) {
|
|
261
|
+
if (!input)
|
|
262
|
+
return false;
|
|
263
|
+
const email = normalizeEmail(input.email);
|
|
264
|
+
const phone = localMobileDigits(input.phone);
|
|
265
|
+
return Boolean(email) || phone.length >= 8;
|
|
266
|
+
}
|
|
267
|
+
function resolveCreatedCustomerEmail(input) {
|
|
268
|
+
const email = normalizeEmail(input.email);
|
|
269
|
+
return email || undefined;
|
|
270
|
+
}
|
|
271
|
+
function isPlainRecord(value) {
|
|
272
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
273
|
+
}
|
|
274
|
+
function isReturnId(value) {
|
|
275
|
+
return typeof value === "string" && value.startsWith("return");
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* beginReturnOrderWorkflow returns an OrderChangeDTO (`ordch_…`) with `return_id`.
|
|
279
|
+
* Workflow serialization may wrap that object, use camelCase, or return an array.
|
|
280
|
+
*/
|
|
281
|
+
function extractReturnId(result, fromJson = false) {
|
|
282
|
+
const queue = [result];
|
|
283
|
+
const seen = new Set();
|
|
284
|
+
while (queue.length) {
|
|
285
|
+
const current = queue.shift();
|
|
286
|
+
if (current == null || seen.has(current))
|
|
287
|
+
continue;
|
|
288
|
+
if (isReturnId(current))
|
|
289
|
+
return current;
|
|
290
|
+
if (typeof current !== "object")
|
|
291
|
+
continue;
|
|
292
|
+
seen.add(current);
|
|
293
|
+
if (Array.isArray(current)) {
|
|
294
|
+
queue.push(...current);
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
if (!isPlainRecord(current))
|
|
298
|
+
continue;
|
|
299
|
+
if (isReturnId(current.return_id))
|
|
300
|
+
return current.return_id;
|
|
301
|
+
if (isReturnId(current.returnId))
|
|
302
|
+
return current.returnId;
|
|
303
|
+
if (isReturnId(current.id))
|
|
304
|
+
return current.id;
|
|
305
|
+
if (isPlainRecord(current.return) && isReturnId(current.return.id)) {
|
|
306
|
+
return current.return.id;
|
|
307
|
+
}
|
|
308
|
+
queue.push(current.result, current.output, current.data, current.return, current.order_change, current.orderChange);
|
|
309
|
+
}
|
|
310
|
+
if (!fromJson) {
|
|
311
|
+
try {
|
|
312
|
+
return extractReturnId(JSON.parse(JSON.stringify(result)), true);
|
|
313
|
+
}
|
|
314
|
+
catch {
|
|
315
|
+
return null;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
function getThrownErrorMessage(error, fallback) {
|
|
321
|
+
if (typeof error === "string" && error.trim())
|
|
322
|
+
return error;
|
|
323
|
+
if (error instanceof Error && error.message)
|
|
324
|
+
return error.message;
|
|
325
|
+
if (Array.isArray(error) && error.length) {
|
|
326
|
+
return getThrownErrorMessage(error[0], fallback);
|
|
327
|
+
}
|
|
328
|
+
if (isPlainRecord(error)) {
|
|
329
|
+
if (error.error != null)
|
|
330
|
+
return getThrownErrorMessage(error.error, fallback);
|
|
331
|
+
if (typeof error.message === "string" && error.message)
|
|
332
|
+
return error.message;
|
|
333
|
+
if (Array.isArray(error.errors) && error.errors.length) {
|
|
334
|
+
return getThrownErrorMessage(error.errors[0], fallback);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return fallback;
|
|
338
|
+
}
|
|
339
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9zLXJldHVybnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdXRpbHMvcG9zLXJldHVybnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBMkJBLDRCQXVCQztBQUVELGtDQUVDO0FBRUQsZ0NBRUM7QUFFRCx3Q0FFQztBQUVELDBDQUVDO0FBR0Qsa0RBUUM7QUFFRCw4Q0FFQztBQUVELDhDQVNDO0FBR0Qsa0RBVUM7QUFFRCxvREFFQztBQUVELHdEQUdDO0FBRUQsc0RBV0M7QUFHRCw4Q0FjQztBQUVELGtEQVNDO0FBRUQsMENBWUM7QUFFRCxnQ0FFQztBQUVELDhDQVdDO0FBRUQsb0VBRUM7QUFNRCxvREFtREM7QUFNRCxzREF1QkM7QUFFRCxzREFzQkM7QUFFRCw0REFPQztBQUVELGtFQUtDO0FBY0QsMENBMkNDO0FBRUQsc0RBY0M7QUFyWVksUUFBQSxlQUFlLEdBQUcsa0NBQWtDLENBQUE7QUEyQmpFLFNBQWdCLFFBQVEsQ0FBQyxLQUFjO0lBQ3JDLElBQUksS0FBSyxJQUFJLElBQUk7UUFBRSxPQUFPLENBQUMsQ0FBQTtJQUMzQixJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVE7UUFBRSxPQUFPLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQ3hFLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUTtRQUFFLE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQ25ELElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDOUIsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ3ZCLE9BQU8sTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7SUFDbkMsQ0FBQztJQUNELElBQUksT0FBTyxL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
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isPosIntegrationTestMode = isPosIntegrationTestMode;
|
|
4
|
+
exports.createPosDeviceOrder = createPosDeviceOrder;
|
|
5
|
+
exports.initiatePosDeviceCheckout = initiatePosDeviceCheckout;
|
|
6
|
+
exports.fetchPosDeviceOrder = fetchPosDeviceOrder;
|
|
7
|
+
exports.closePosDeviceCheckout = closePosDeviceCheckout;
|
|
8
|
+
exports.getPosOrderPaymentStatus = getPosOrderPaymentStatus;
|
|
9
|
+
const razorpay_pos_1 = require("./razorpay-pos");
|
|
10
|
+
function getAuthHeader() {
|
|
11
|
+
const key_id = process.env.RAZORPAY_KEY_ID;
|
|
12
|
+
const key_secret = process.env.RAZORPAY_KEY_SECRET;
|
|
13
|
+
if (!key_id || !key_secret) {
|
|
14
|
+
throw new Error("RAZORPAY_KEY_ID and RAZORPAY_KEY_SECRET must be set");
|
|
15
|
+
}
|
|
16
|
+
return "Basic " + Buffer.from(`${key_id}:${key_secret}`).toString("base64");
|
|
17
|
+
}
|
|
18
|
+
function getDeviceMode() {
|
|
19
|
+
const mode = (process.env.RAZORPAY_POS_DEVICE_MODE || "wired").toLowerCase();
|
|
20
|
+
return mode === "wireless" ? "wireless" : "wired";
|
|
21
|
+
}
|
|
22
|
+
function getDeviceId() {
|
|
23
|
+
const id = process.env.RAZORPAY_POS_DEVICE_ID?.trim();
|
|
24
|
+
return id || undefined;
|
|
25
|
+
}
|
|
26
|
+
function isPosIntegrationTestMode() {
|
|
27
|
+
const value = (process.env.RAZORPAY_POS_INTEGRATION_TEST || "true").toLowerCase();
|
|
28
|
+
return value === "1" || value === "true" || value === "yes";
|
|
29
|
+
}
|
|
30
|
+
async function razorpayPosFetch(path, init) {
|
|
31
|
+
const deviceMode = getDeviceMode();
|
|
32
|
+
const separator = path.includes("?") ? "&" : "?";
|
|
33
|
+
const url = `https://api.razorpay.com/v1${path}${separator}device_mode=${deviceMode}`;
|
|
34
|
+
const response = await fetch(url, {
|
|
35
|
+
...init,
|
|
36
|
+
headers: {
|
|
37
|
+
Authorization: getAuthHeader(),
|
|
38
|
+
"Content-Type": "application/json",
|
|
39
|
+
...(init?.headers || {}),
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
const data = await response.json().catch(() => ({}));
|
|
43
|
+
if (!response.ok) {
|
|
44
|
+
const error = new Error(data?.error?.description || data?.message || "Razorpay POS request failed");
|
|
45
|
+
error.status = response.status;
|
|
46
|
+
error.error = data?.error;
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
49
|
+
return data;
|
|
50
|
+
}
|
|
51
|
+
async function createPosDeviceOrder(input) {
|
|
52
|
+
const amount = (0, razorpay_pos_1.toPaise)(input.amount);
|
|
53
|
+
return razorpayPosFetch("/orders", {
|
|
54
|
+
method: "POST",
|
|
55
|
+
body: JSON.stringify({
|
|
56
|
+
amount,
|
|
57
|
+
currency: "INR",
|
|
58
|
+
receipt: `pos_${input.draftOrderId}`.slice(0, 40),
|
|
59
|
+
notes: {
|
|
60
|
+
draft_order_id: input.draftOrderId,
|
|
61
|
+
source: "medusa_pos_machine",
|
|
62
|
+
description: input.description || `POS ${input.draftOrderId}`,
|
|
63
|
+
},
|
|
64
|
+
}),
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
async function initiatePosDeviceCheckout(input) {
|
|
68
|
+
const amount = (0, razorpay_pos_1.toPaise)(input.amount);
|
|
69
|
+
const deviceId = getDeviceId();
|
|
70
|
+
const body = {
|
|
71
|
+
action: "initiate_checkout",
|
|
72
|
+
notes: {
|
|
73
|
+
draft_order_id: input.draftOrderId,
|
|
74
|
+
source: "medusa_pos_machine",
|
|
75
|
+
},
|
|
76
|
+
initiate_checkout: {
|
|
77
|
+
name: "Chocomelon POS",
|
|
78
|
+
amount,
|
|
79
|
+
currency: "INR",
|
|
80
|
+
description: input.description || `POS ${input.draftOrderId}`,
|
|
81
|
+
type: "in_person",
|
|
82
|
+
order_id: input.razorpayOrderId,
|
|
83
|
+
prefill: {
|
|
84
|
+
method: "upi",
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
if (deviceId) {
|
|
89
|
+
body.device_id = deviceId;
|
|
90
|
+
}
|
|
91
|
+
return razorpayPosFetch("/device_activity", {
|
|
92
|
+
method: "POST",
|
|
93
|
+
body: JSON.stringify(body),
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
async function fetchPosDeviceOrder(orderId) {
|
|
97
|
+
return razorpayPosFetch(`/orders/${orderId}`);
|
|
98
|
+
}
|
|
99
|
+
async function closePosDeviceCheckout() {
|
|
100
|
+
const deviceId = getDeviceId();
|
|
101
|
+
const body = {
|
|
102
|
+
action: "close_checkout",
|
|
103
|
+
};
|
|
104
|
+
if (deviceId) {
|
|
105
|
+
body.device_id = deviceId;
|
|
106
|
+
}
|
|
107
|
+
return razorpayPosFetch("/device_activity", {
|
|
108
|
+
method: "POST",
|
|
109
|
+
body: JSON.stringify(body),
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
function getPosOrderPaymentStatus(order) {
|
|
113
|
+
if (order.status === "paid") {
|
|
114
|
+
return "paid";
|
|
115
|
+
}
|
|
116
|
+
if (order.status === "attempted" && (order.amount_due ?? 0) > 0) {
|
|
117
|
+
return "pending";
|
|
118
|
+
}
|
|
119
|
+
// created / attempted with no clear fail → pending for polling
|
|
120
|
+
return "pending";
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmF6b3JwYXktcG9zLWRldmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy91dGlscy9yYXpvcnBheS1wb3MtZGV2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBa0NBLDREQUdDO0FBOEJELG9EQW9CQztBQUVELDhEQW1DQztBQUVELGtEQUVDO0FBRUQsd0RBYUM7QUFFRCw0REFXQztBQTVKRCxpREFBd0M7QUFheEMsU0FBUyxhQUFhO0lBQ3BCLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFBO0lBQzFDLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLENBQUE7SUFFbEQsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQzNCLE1BQU0sSUFBSSxLQUFLLENBQUMscURBQXFELENBQUMsQ0FBQTtJQUN4RSxDQUFDO0lBRUQsT0FBTyxRQUFRLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLE1BQU0sSUFBSSxVQUFVLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQTtBQUM3RSxDQUFDO0FBRUQsU0FBUyxhQUFhO0lBQ3BCLE1BQU0sSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyx3QkFBd0IsSUFBSSxPQUFPLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQTtJQUM1RSxPQUFPLElBQUksS0FBSyxVQUFVLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFBO0FBQ25ELENBQUM7QUFFRCxTQUFTLFdBQVc7SUFDbEIsTUFBTSxFQUFFLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsRUFBRSxJQUFJLEVBQUUsQ0FBQTtJQUNyRCxPQUFPLEVBQUUsSUFBSSxTQUFTLENBQUE7QUFDeEIsQ0FBQztBQUVELFNBQWdCLHdCQUF3QjtJQUN0QyxNQUFNLEtB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
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isRazorpayConfigured = isRazorpayConfigured;
|
|
4
|
+
exports.toPaise = toPaise;
|
|
5
|
+
exports.createPosUpiQr = createPosUpiQr;
|
|
6
|
+
exports.fetchPosUpiQr = fetchPosUpiQr;
|
|
7
|
+
exports.fetchPosUpiQrPayments = fetchPosUpiQrPayments;
|
|
8
|
+
exports.closePosUpiQr = closePosUpiQr;
|
|
9
|
+
exports.fetchPosUpiQrPayload = fetchPosUpiQrPayload;
|
|
10
|
+
exports.getUpiQrStatus = getUpiQrStatus;
|
|
11
|
+
function getAuthHeader() {
|
|
12
|
+
const key_id = process.env.RAZORPAY_KEY_ID;
|
|
13
|
+
const key_secret = process.env.RAZORPAY_KEY_SECRET;
|
|
14
|
+
if (!key_id || !key_secret) {
|
|
15
|
+
throw new Error("RAZORPAY_KEY_ID and RAZORPAY_KEY_SECRET must be set");
|
|
16
|
+
}
|
|
17
|
+
return "Basic " + Buffer.from(`${key_id}:${key_secret}`).toString("base64");
|
|
18
|
+
}
|
|
19
|
+
/** True when both Razorpay admin API credentials are present. */
|
|
20
|
+
function isRazorpayConfigured() {
|
|
21
|
+
const keyId = process.env.RAZORPAY_KEY_ID?.trim();
|
|
22
|
+
const keySecret = process.env.RAZORPAY_KEY_SECRET?.trim();
|
|
23
|
+
return Boolean(keyId && keySecret);
|
|
24
|
+
}
|
|
25
|
+
async function razorpayFetch(path, init) {
|
|
26
|
+
const response = await fetch(`https://api.razorpay.com/v1${path}`, {
|
|
27
|
+
...init,
|
|
28
|
+
headers: {
|
|
29
|
+
Authorization: getAuthHeader(),
|
|
30
|
+
"Content-Type": "application/json",
|
|
31
|
+
...(init?.headers || {}),
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
const data = await response.json().catch(() => ({}));
|
|
35
|
+
if (!response.ok) {
|
|
36
|
+
const error = new Error(data?.error?.description || data?.message || "Razorpay request failed");
|
|
37
|
+
error.status = response.status;
|
|
38
|
+
error.error = data?.error;
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
return data;
|
|
42
|
+
}
|
|
43
|
+
/** Medusa amounts may be number, string, or BigNumber-like. Razorpay expects paise. */
|
|
44
|
+
function toPaise(amount) {
|
|
45
|
+
let raw = amount;
|
|
46
|
+
if (raw && typeof raw === "object") {
|
|
47
|
+
const obj = raw;
|
|
48
|
+
if (typeof obj.numeric === "number" || typeof obj.numeric === "string") {
|
|
49
|
+
raw = obj.numeric;
|
|
50
|
+
}
|
|
51
|
+
else if (typeof obj.value === "number" || typeof obj.value === "string") {
|
|
52
|
+
raw = obj.value;
|
|
53
|
+
}
|
|
54
|
+
else if (typeof obj.toNumber === "function") {
|
|
55
|
+
raw = obj.toNumber();
|
|
56
|
+
}
|
|
57
|
+
else if (typeof obj.toString === "function") {
|
|
58
|
+
const asString = obj.toString();
|
|
59
|
+
if (asString !== "[object Object]") {
|
|
60
|
+
raw = asString;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const value = typeof raw === "string" ? Number(raw) : Number(raw);
|
|
65
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
66
|
+
throw new Error(`Invalid payment amount: ${JSON.stringify(amount)}`);
|
|
67
|
+
}
|
|
68
|
+
return Math.round(value * 100);
|
|
69
|
+
}
|
|
70
|
+
async function createPosUpiQr(input) {
|
|
71
|
+
const paymentAmount = toPaise(input.amount);
|
|
72
|
+
return razorpayFetch("/payments/qr_codes", {
|
|
73
|
+
method: "POST",
|
|
74
|
+
body: JSON.stringify({
|
|
75
|
+
type: "upi_qr",
|
|
76
|
+
name: "Chocomelon POS",
|
|
77
|
+
usage: "single_use",
|
|
78
|
+
fixed_amount: true,
|
|
79
|
+
payment_amount: paymentAmount,
|
|
80
|
+
description: input.description || `POS ${input.draftOrderId}`,
|
|
81
|
+
notes: {
|
|
82
|
+
draft_order_id: input.draftOrderId,
|
|
83
|
+
source: "medusa_pos",
|
|
84
|
+
},
|
|
85
|
+
}),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
async function fetchPosUpiQr(qrId) {
|
|
89
|
+
return razorpayFetch(`/payments/qr_codes/${qrId}`);
|
|
90
|
+
}
|
|
91
|
+
async function fetchPosUpiQrPayments(qrId) {
|
|
92
|
+
return razorpayFetch(`/payments/qr_codes/${qrId}/payments?count=10`);
|
|
93
|
+
}
|
|
94
|
+
async function closePosUpiQr(qrId) {
|
|
95
|
+
return razorpayFetch(`/payments/qr_codes/${qrId}/close`, {
|
|
96
|
+
method: "POST",
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
/** Prefer UPI intent string when available; otherwise use Razorpay QR image URL for <Image>. */
|
|
100
|
+
async function fetchPosUpiQrPayload(qrId) {
|
|
101
|
+
try {
|
|
102
|
+
const response = await fetch(`https://api.razorpay.com/v1/payments/qr_codes/${qrId}/image_content`, {
|
|
103
|
+
headers: {
|
|
104
|
+
Authorization: getAuthHeader(),
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
if (!response.ok) {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
const data = await response.json().catch(() => null);
|
|
111
|
+
if (typeof data === "string" && data.startsWith("upi://")) {
|
|
112
|
+
return data;
|
|
113
|
+
}
|
|
114
|
+
if (data && typeof data.image_content === "string") {
|
|
115
|
+
return data.image_content;
|
|
116
|
+
}
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function getUpiQrStatus(qr) {
|
|
124
|
+
const received = Number(qr.payments_count_received || 0);
|
|
125
|
+
const amountReceived = Number(qr.payments_amount_received || 0);
|
|
126
|
+
if (received > 0 || amountReceived > 0) {
|
|
127
|
+
return "paid";
|
|
128
|
+
}
|
|
129
|
+
if (qr.status === "closed") {
|
|
130
|
+
return "closed";
|
|
131
|
+
}
|
|
132
|
+
return "pending";
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmF6b3JwYXktcG9zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL3Jhem9ycGF5LXBvcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQWdDQSxvREFJQztBQTJCRCwwQkEwQkM7QUFFRCx3Q0FzQkM7QUFFRCxzQ0FFQztBQUVELHNEQUlDO0FBRUQsc0NBSUM7QUFHRCxvREEwQkM7QUFFRCx3Q0FhQztBQXpKRCxTQUFTLGFBQWE7SUFDcEIsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxlQUFlLENBQUE7SUFDMUMsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsQ0FBQTtJQUVsRCxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDM0IsTUFBTSxJQUFJLEtBQUssQ0FBQyxxREFBcUQsQ0FBQyxDQUFBO0lBQ3hFLENBQUM7SUFFRCxPQUFPLFFBQVEsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsTUFBTSxJQUFJLFVBQVUsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFBO0FBQzdFLENBQUM7QUFFRCxpRUFBaUU7QUFDakUsU0FBZ0Isb0JBQW9CO0lBQ2xDLE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsZUFBZSxFQUFFLElBQUksRUFBRSxDQUFBO0lBQ2pELE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLEVBQUUsSUFBSSxFQUFFLENBQUE7SUFDekQsT0FBTyxPQUFPLENBQUMsS0FBSyxJQUFJLFNBQVMsQ0FBQyxDQUFBO0FBQ3BDLENBQUM7QUFFRCxLQUFLLFVBQVUsYUFBYSxDQUFJLElBQVksRUFBRSxJQUFrQjtJQUM5RCxNQUFNLFFBQVEsR0FBRyxNQUFNLEtBQUssQ0FBQyw4QkFBOEIsSUFBSSxFQUFFLEVBQUU7UUFDakUsR0FBRyxJQUFJO1FBQ1AsT0FB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
|
package/README.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# medusa-pos-plugin
|
|
2
|
+
|
|
3
|
+
Medusa v2 plugin for **POS operations**: draft carts, finalize/checkout, Razorpay UPI QR & device payments, returns, catalog, and manual discounts.
|
|
4
|
+
|
|
5
|
+
Analytics live in **`medusa-analytics`** (`/admin/analytics/pos/*`). This plugin only **writes** POS metadata on finalize for those reports to read.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install medusa-pos-plugin
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Register in `medusa-config.ts`:
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
{
|
|
17
|
+
resolve: "medusa-pos-plugin",
|
|
18
|
+
options: {
|
|
19
|
+
guestEmail: "noreply+pos-guest@example.com",
|
|
20
|
+
timezone: "Asia/Kolkata",
|
|
21
|
+
razorpay: {
|
|
22
|
+
keyId: process.env.RAZORPAY_KEY_ID,
|
|
23
|
+
keySecret: process.env.RAZORPAY_KEY_SECRET,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Razorpay credentials also fall back to `RAZORPAY_KEY_ID` / `RAZORPAY_KEY_SECRET` env vars.
|
|
30
|
+
|
|
31
|
+
## Admin APIs
|
|
32
|
+
|
|
33
|
+
All routes keep the `/admin/pos/*` paths used by the `medusa-pos` client.
|
|
34
|
+
|
|
35
|
+
## Build
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npx medusa plugin:build
|
|
39
|
+
```
|