multivendor-wallet 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/README.md ADDED
@@ -0,0 +1,21 @@
1
+ # multivendor-wallet
2
+
3
+ Framework-agnostic wallet ledger engine for multi-vendor marketplaces.
4
+
5
+ ## Operations
6
+
7
+ - `credit` / `debit` — adjust available balance (integer minor units / paise)
8
+ - `hold` / `release` / `cancelHold` — escrow lifecycle
9
+ - `transfer` — atomic debit + credit
10
+ - `getBalance` — `{ available, held, total }` where `total = available + held`
11
+
12
+ ## Host integration
13
+
14
+ Implement `IWalletStore` with your persistence layer (TypeORM adapter ships in Myownbazaar_server). Pass `{ nativeTx: entityManager }` to join an existing database transaction.
15
+
16
+ ## Publish
17
+
18
+ ```bash
19
+ pnpm run build && pnpm run test
20
+ # tag: wallet-v0.0.1
21
+ ```
@@ -0,0 +1,681 @@
1
+ 'use strict';
2
+
3
+ var typeorm = require('typeorm');
4
+
5
+ var __defProp = Object.defineProperty;
6
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
8
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
9
+
10
+ // src/currency.ts
11
+ function toMinorUnit(amount) {
12
+ return Math.round(amount * 100);
13
+ }
14
+ __name(toMinorUnit, "toMinorUnit");
15
+ function fromMinorUnit(amount) {
16
+ return amount / 100;
17
+ }
18
+ __name(fromMinorUnit, "fromMinorUnit");
19
+
20
+ // src/types.ts
21
+ var WalletAccountType = /* @__PURE__ */ (function(WalletAccountType2) {
22
+ WalletAccountType2["CUSTOMER"] = "customer";
23
+ WalletAccountType2["VENDOR"] = "vendor";
24
+ WalletAccountType2["PLATFORM"] = "platform";
25
+ return WalletAccountType2;
26
+ })({});
27
+
28
+ // src/hooks/order.ts
29
+ function isWalletOnlyPayment(paymentMethod) {
30
+ return String(paymentMethod ?? "").trim().toLowerCase() === "wallet";
31
+ }
32
+ __name(isWalletOnlyPayment, "isWalletOnlyPayment");
33
+ function createOrderHooks(runtime) {
34
+ const { client, platformOwnerId, flags } = runtime;
35
+ return {
36
+ async onOrderPaid(ctx) {
37
+ if (!flags.enabled || !flags.ledgerWrites) {
38
+ return;
39
+ }
40
+ const txCtx = {
41
+ nativeTx: ctx.nativeTx
42
+ };
43
+ const platform = await client.getOrCreateAccount(WalletAccountType.PLATFORM, platformOwnerId, ctx.currency, txCtx);
44
+ const orderTotalPaise = toMinorUnit(ctx.orderTotalRupees);
45
+ const shouldDebitCustomer = isWalletOnlyPayment(ctx.paymentMethod) && ctx.customerId && !ctx.skipCustomerDebit;
46
+ if (shouldDebitCustomer) {
47
+ const debitRupees = ctx.walletAmountRupees ?? ctx.orderTotalRupees;
48
+ const customer = await client.getOrCreateAccount(WalletAccountType.CUSTOMER, ctx.customerId, ctx.currency, txCtx);
49
+ await client.debit({
50
+ accountId: customer.id,
51
+ amount: toMinorUnit(debitRupees),
52
+ idempotencyKey: `wallet:payment:${ctx.paymentNumber}`,
53
+ reference: {
54
+ referenceType: "order",
55
+ referenceId: String(ctx.orderId)
56
+ }
57
+ }, txCtx);
58
+ }
59
+ await client.credit({
60
+ accountId: platform.id,
61
+ amount: orderTotalPaise,
62
+ idempotencyKey: `payment:${ctx.paymentNumber}`,
63
+ reference: {
64
+ referenceType: "order",
65
+ referenceId: String(ctx.orderId)
66
+ }
67
+ }, txCtx);
68
+ for (const line of ctx.lines) {
69
+ const vendorNetRupees = line.commissionBaseRupees - line.commissionRupees;
70
+ if (vendorNetRupees <= 0) {
71
+ continue;
72
+ }
73
+ const vendor = await client.getOrCreateAccount(WalletAccountType.VENDOR, line.vendorId, ctx.currency, txCtx);
74
+ await client.hold({
75
+ sourceAccountId: platform.id,
76
+ targetAccountId: vendor.id,
77
+ amount: toMinorUnit(vendorNetRupees),
78
+ idempotencyKey: `order:${ctx.orderId}:hold:vendorOrder:${line.vendorOrderId}`,
79
+ reference: {
80
+ referenceType: "vendor_order",
81
+ referenceId: String(line.vendorOrderId)
82
+ }
83
+ }, txCtx);
84
+ }
85
+ },
86
+ async onLineDelivered(ctx) {
87
+ if (!flags.enabled || !flags.ledgerWrites) {
88
+ return;
89
+ }
90
+ await client.release({
91
+ reference: {
92
+ referenceType: "vendor_order",
93
+ referenceId: String(ctx.vendorOrderId)
94
+ },
95
+ idempotencyKey: `vendorOrder:${ctx.vendorOrderId}:release`
96
+ }, ctx.nativeTx != null ? {
97
+ nativeTx: ctx.nativeTx
98
+ } : void 0);
99
+ }
100
+ };
101
+ }
102
+ __name(createOrderHooks, "createOrderHooks");
103
+
104
+ // src/hooks/refund.ts
105
+ function isWalletPayment(paymentMethod) {
106
+ return String(paymentMethod ?? "").trim().toLowerCase() === "wallet";
107
+ }
108
+ __name(isWalletPayment, "isWalletPayment");
109
+ function walletCreditRupees(ctx) {
110
+ if (ctx.walletRefundRupees != null && ctx.walletRefundRupees > 0) {
111
+ return ctx.walletRefundRupees;
112
+ }
113
+ return isWalletPayment(ctx.paymentMethod) ? ctx.lineTotalRupees : 0;
114
+ }
115
+ __name(walletCreditRupees, "walletCreditRupees");
116
+ function idempotencyPrefix(ctx) {
117
+ const scope = ctx.idempotencyScope ?? String(ctx.orderProductId);
118
+ return ctx.refundReason === "return" ? `return:${scope}` : `refund:${ctx.orderProductId}`;
119
+ }
120
+ __name(idempotencyPrefix, "idempotencyPrefix");
121
+ function createRefundHooks(runtime) {
122
+ const { client, platformOwnerId, flags } = runtime;
123
+ return {
124
+ async onRefund(ctx) {
125
+ if (!flags.enabled || !flags.ledgerWrites) {
126
+ await ctx.processExternalRefund();
127
+ return;
128
+ }
129
+ const keyPrefix = idempotencyPrefix(ctx);
130
+ if (!ctx.skipEscrow) {
131
+ await client.cancelHold({
132
+ reference: {
133
+ referenceType: "vendor_order",
134
+ referenceId: String(ctx.vendorOrderId)
135
+ },
136
+ idempotencyKey: `${keyPrefix}:cancel_hold`
137
+ });
138
+ }
139
+ const refundPaise = toMinorUnit(ctx.lineTotalRupees);
140
+ if (refundPaise > 0) {
141
+ const platform = await client.getOrCreateAccount(WalletAccountType.PLATFORM, platformOwnerId, ctx.currency);
142
+ const balance = await client.getBalance(platform.id);
143
+ if (balance.available >= refundPaise) {
144
+ await client.debit({
145
+ accountId: platform.id,
146
+ amount: refundPaise,
147
+ idempotencyKey: `${keyPrefix}:platform_debit`,
148
+ reference: {
149
+ referenceType: "order_product",
150
+ referenceId: String(ctx.orderProductId)
151
+ }
152
+ });
153
+ }
154
+ const creditRupees = walletCreditRupees(ctx);
155
+ if (creditRupees > 0 && ctx.customerId) {
156
+ const customer = await client.getOrCreateAccount(WalletAccountType.CUSTOMER, ctx.customerId, ctx.currency);
157
+ await client.credit({
158
+ accountId: customer.id,
159
+ amount: toMinorUnit(creditRupees),
160
+ idempotencyKey: `${keyPrefix}:customer_credit`,
161
+ reference: {
162
+ referenceType: "order",
163
+ referenceId: String(ctx.orderId ?? ctx.orderProductId)
164
+ }
165
+ });
166
+ }
167
+ }
168
+ await ctx.processExternalRefund();
169
+ }
170
+ };
171
+ }
172
+ __name(createRefundHooks, "createRefundHooks");
173
+
174
+ // src/hooks/settlement.ts
175
+ function createSettlementHooks(runtime) {
176
+ const { client, flags } = runtime;
177
+ return {
178
+ async onSettlementDebit(ctx) {
179
+ if (!flags.enabled || !flags.settlementDebit) {
180
+ return;
181
+ }
182
+ const txCtx = {
183
+ nativeTx: ctx.nativeTx
184
+ };
185
+ const amountPaise = toMinorUnit(ctx.amountRupees);
186
+ const vendorAccount = await client.getOrCreateAccount(WalletAccountType.VENDOR, ctx.vendorId, ctx.currency, txCtx);
187
+ const balance = await client.getBalance(vendorAccount.id, txCtx);
188
+ if (balance.available < amountPaise) {
189
+ throw new Error(`Insufficient vendor wallet balance for settlement (vendor ${ctx.vendorId})`);
190
+ }
191
+ await client.debit({
192
+ accountId: vendorAccount.id,
193
+ amount: amountPaise,
194
+ idempotencyKey: `settlement:${ctx.settlementId}:debit:${ctx.vendorId}`,
195
+ reference: {
196
+ referenceType: "settlement",
197
+ referenceId: String(ctx.settlementId)
198
+ }
199
+ }, txCtx);
200
+ }
201
+ };
202
+ }
203
+ __name(createSettlementHooks, "createSettlementHooks");
204
+ function resolveWalletConnection() {
205
+ {
206
+ throw new Error("Wallet database connection is not registered. Pass host TypeORM Connection as dataSource.");
207
+ }
208
+ }
209
+ __name(resolveWalletConnection, "resolveWalletConnection");
210
+ function _ts_decorate(decorators, target, key, desc) {
211
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
212
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
213
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
214
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
215
+ }
216
+ __name(_ts_decorate, "_ts_decorate");
217
+ function _ts_metadata(k, v) {
218
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
219
+ }
220
+ __name(_ts_metadata, "_ts_metadata");
221
+ function nowTimestamp() {
222
+ return (/* @__PURE__ */ new Date()).toISOString().slice(0, 19).replace("T", " ");
223
+ }
224
+ __name(nowTimestamp, "nowTimestamp");
225
+ var _WalletAccountEntity = class _WalletAccountEntity {
226
+ constructor() {
227
+ __publicField(this, "id");
228
+ __publicField(this, "ownerType");
229
+ __publicField(this, "ownerId");
230
+ __publicField(this, "currency");
231
+ __publicField(this, "availableBalance");
232
+ __publicField(this, "heldBalance");
233
+ __publicField(this, "createdBy");
234
+ __publicField(this, "createdDate");
235
+ __publicField(this, "modifiedBy");
236
+ __publicField(this, "modifiedDate");
237
+ }
238
+ setCreated() {
239
+ this.createdDate = nowTimestamp();
240
+ this.modifiedDate = nowTimestamp();
241
+ }
242
+ setModified() {
243
+ this.modifiedDate = nowTimestamp();
244
+ }
245
+ };
246
+ __name(_WalletAccountEntity, "WalletAccountEntity");
247
+ var WalletAccountEntity = _WalletAccountEntity;
248
+ _ts_decorate([
249
+ typeorm.PrimaryGeneratedColumn({
250
+ name: "id"
251
+ }),
252
+ _ts_metadata("design:type", Number)
253
+ ], WalletAccountEntity.prototype, "id", void 0);
254
+ _ts_decorate([
255
+ typeorm.Column({
256
+ name: "owner_type",
257
+ length: 32
258
+ }),
259
+ _ts_metadata("design:type", String)
260
+ ], WalletAccountEntity.prototype, "ownerType", void 0);
261
+ _ts_decorate([
262
+ typeorm.Column({
263
+ name: "owner_id"
264
+ }),
265
+ _ts_metadata("design:type", Number)
266
+ ], WalletAccountEntity.prototype, "ownerId", void 0);
267
+ _ts_decorate([
268
+ typeorm.Column({
269
+ name: "currency",
270
+ length: 8,
271
+ default: "INR"
272
+ }),
273
+ _ts_metadata("design:type", String)
274
+ ], WalletAccountEntity.prototype, "currency", void 0);
275
+ _ts_decorate([
276
+ typeorm.Column({
277
+ name: "available_balance",
278
+ type: "bigint",
279
+ default: 0
280
+ }),
281
+ _ts_metadata("design:type", String)
282
+ ], WalletAccountEntity.prototype, "availableBalance", void 0);
283
+ _ts_decorate([
284
+ typeorm.Column({
285
+ name: "held_balance",
286
+ type: "bigint",
287
+ default: 0
288
+ }),
289
+ _ts_metadata("design:type", String)
290
+ ], WalletAccountEntity.prototype, "heldBalance", void 0);
291
+ _ts_decorate([
292
+ typeorm.Column({
293
+ name: "created_by",
294
+ nullable: true
295
+ }),
296
+ _ts_metadata("design:type", Number)
297
+ ], WalletAccountEntity.prototype, "createdBy", void 0);
298
+ _ts_decorate([
299
+ typeorm.Column({
300
+ name: "created_date",
301
+ nullable: true
302
+ }),
303
+ _ts_metadata("design:type", String)
304
+ ], WalletAccountEntity.prototype, "createdDate", void 0);
305
+ _ts_decorate([
306
+ typeorm.Column({
307
+ name: "modified_by",
308
+ nullable: true
309
+ }),
310
+ _ts_metadata("design:type", Number)
311
+ ], WalletAccountEntity.prototype, "modifiedBy", void 0);
312
+ _ts_decorate([
313
+ typeorm.Column({
314
+ name: "modified_date",
315
+ nullable: true
316
+ }),
317
+ _ts_metadata("design:type", String)
318
+ ], WalletAccountEntity.prototype, "modifiedDate", void 0);
319
+ _ts_decorate([
320
+ typeorm.BeforeInsert(),
321
+ _ts_metadata("design:type", Function),
322
+ _ts_metadata("design:paramtypes", []),
323
+ _ts_metadata("design:returntype", void 0)
324
+ ], WalletAccountEntity.prototype, "setCreated", null);
325
+ _ts_decorate([
326
+ typeorm.BeforeUpdate(),
327
+ _ts_metadata("design:type", Function),
328
+ _ts_metadata("design:paramtypes", []),
329
+ _ts_metadata("design:returntype", void 0)
330
+ ], WalletAccountEntity.prototype, "setModified", null);
331
+ WalletAccountEntity = _ts_decorate([
332
+ typeorm.Entity("wallet_account")
333
+ ], WalletAccountEntity);
334
+ var _WalletLedgerEntryEntity = class _WalletLedgerEntryEntity {
335
+ constructor() {
336
+ __publicField(this, "id");
337
+ __publicField(this, "accountId");
338
+ __publicField(this, "entryType");
339
+ __publicField(this, "amount");
340
+ __publicField(this, "balanceAfterAvailable");
341
+ __publicField(this, "balanceAfterHeld");
342
+ __publicField(this, "idempotencyKey");
343
+ __publicField(this, "referenceType");
344
+ __publicField(this, "referenceId");
345
+ __publicField(this, "metadata");
346
+ __publicField(this, "createdBy");
347
+ __publicField(this, "createdDate");
348
+ __publicField(this, "modifiedBy");
349
+ __publicField(this, "modifiedDate");
350
+ }
351
+ setCreated() {
352
+ this.createdDate = nowTimestamp();
353
+ this.modifiedDate = nowTimestamp();
354
+ }
355
+ };
356
+ __name(_WalletLedgerEntryEntity, "WalletLedgerEntryEntity");
357
+ var WalletLedgerEntryEntity = _WalletLedgerEntryEntity;
358
+ _ts_decorate([
359
+ typeorm.PrimaryGeneratedColumn({
360
+ name: "id"
361
+ }),
362
+ _ts_metadata("design:type", Number)
363
+ ], WalletLedgerEntryEntity.prototype, "id", void 0);
364
+ _ts_decorate([
365
+ typeorm.Column({
366
+ name: "account_id"
367
+ }),
368
+ _ts_metadata("design:type", Number)
369
+ ], WalletLedgerEntryEntity.prototype, "accountId", void 0);
370
+ _ts_decorate([
371
+ typeorm.Column({
372
+ name: "entry_type",
373
+ length: 32
374
+ }),
375
+ _ts_metadata("design:type", String)
376
+ ], WalletLedgerEntryEntity.prototype, "entryType", void 0);
377
+ _ts_decorate([
378
+ typeorm.Column({
379
+ name: "amount",
380
+ type: "bigint"
381
+ }),
382
+ _ts_metadata("design:type", String)
383
+ ], WalletLedgerEntryEntity.prototype, "amount", void 0);
384
+ _ts_decorate([
385
+ typeorm.Column({
386
+ name: "balance_after_available",
387
+ type: "bigint"
388
+ }),
389
+ _ts_metadata("design:type", String)
390
+ ], WalletLedgerEntryEntity.prototype, "balanceAfterAvailable", void 0);
391
+ _ts_decorate([
392
+ typeorm.Column({
393
+ name: "balance_after_held",
394
+ type: "bigint"
395
+ }),
396
+ _ts_metadata("design:type", String)
397
+ ], WalletLedgerEntryEntity.prototype, "balanceAfterHeld", void 0);
398
+ _ts_decorate([
399
+ typeorm.Column({
400
+ name: "idempotency_key",
401
+ length: 255,
402
+ unique: true
403
+ }),
404
+ _ts_metadata("design:type", String)
405
+ ], WalletLedgerEntryEntity.prototype, "idempotencyKey", void 0);
406
+ _ts_decorate([
407
+ typeorm.Column({
408
+ name: "reference_type",
409
+ length: 64,
410
+ nullable: true
411
+ }),
412
+ _ts_metadata("design:type", String)
413
+ ], WalletLedgerEntryEntity.prototype, "referenceType", void 0);
414
+ _ts_decorate([
415
+ typeorm.Column({
416
+ name: "reference_id",
417
+ length: 128,
418
+ nullable: true
419
+ }),
420
+ _ts_metadata("design:type", String)
421
+ ], WalletLedgerEntryEntity.prototype, "referenceId", void 0);
422
+ _ts_decorate([
423
+ typeorm.Column({
424
+ name: "metadata",
425
+ type: "json",
426
+ nullable: true
427
+ }),
428
+ _ts_metadata("design:type", typeof Record === "undefined" ? Object : Record)
429
+ ], WalletLedgerEntryEntity.prototype, "metadata", void 0);
430
+ _ts_decorate([
431
+ typeorm.Column({
432
+ name: "created_by",
433
+ nullable: true
434
+ }),
435
+ _ts_metadata("design:type", Number)
436
+ ], WalletLedgerEntryEntity.prototype, "createdBy", void 0);
437
+ _ts_decorate([
438
+ typeorm.Column({
439
+ name: "created_date",
440
+ nullable: true
441
+ }),
442
+ _ts_metadata("design:type", String)
443
+ ], WalletLedgerEntryEntity.prototype, "createdDate", void 0);
444
+ _ts_decorate([
445
+ typeorm.Column({
446
+ name: "modified_by",
447
+ nullable: true
448
+ }),
449
+ _ts_metadata("design:type", Number)
450
+ ], WalletLedgerEntryEntity.prototype, "modifiedBy", void 0);
451
+ _ts_decorate([
452
+ typeorm.Column({
453
+ name: "modified_date",
454
+ nullable: true
455
+ }),
456
+ _ts_metadata("design:type", String)
457
+ ], WalletLedgerEntryEntity.prototype, "modifiedDate", void 0);
458
+ _ts_decorate([
459
+ typeorm.BeforeInsert(),
460
+ _ts_metadata("design:type", Function),
461
+ _ts_metadata("design:paramtypes", []),
462
+ _ts_metadata("design:returntype", void 0)
463
+ ], WalletLedgerEntryEntity.prototype, "setCreated", null);
464
+ WalletLedgerEntryEntity = _ts_decorate([
465
+ typeorm.Entity("wallet_ledger_entry")
466
+ ], WalletLedgerEntryEntity);
467
+ var _WalletHoldEntity = class _WalletHoldEntity {
468
+ constructor() {
469
+ __publicField(this, "id");
470
+ __publicField(this, "sourceAccountId");
471
+ __publicField(this, "targetAccountId");
472
+ __publicField(this, "amount");
473
+ __publicField(this, "status");
474
+ __publicField(this, "referenceType");
475
+ __publicField(this, "referenceId");
476
+ __publicField(this, "idempotencyKey");
477
+ __publicField(this, "createdBy");
478
+ __publicField(this, "createdDate");
479
+ __publicField(this, "modifiedBy");
480
+ __publicField(this, "modifiedDate");
481
+ }
482
+ setCreated() {
483
+ this.createdDate = nowTimestamp();
484
+ this.modifiedDate = nowTimestamp();
485
+ }
486
+ setModified() {
487
+ this.modifiedDate = nowTimestamp();
488
+ }
489
+ };
490
+ __name(_WalletHoldEntity, "WalletHoldEntity");
491
+ var WalletHoldEntity = _WalletHoldEntity;
492
+ _ts_decorate([
493
+ typeorm.PrimaryGeneratedColumn({
494
+ name: "id"
495
+ }),
496
+ _ts_metadata("design:type", Number)
497
+ ], WalletHoldEntity.prototype, "id", void 0);
498
+ _ts_decorate([
499
+ typeorm.Column({
500
+ name: "source_account_id"
501
+ }),
502
+ _ts_metadata("design:type", Number)
503
+ ], WalletHoldEntity.prototype, "sourceAccountId", void 0);
504
+ _ts_decorate([
505
+ typeorm.Column({
506
+ name: "target_account_id"
507
+ }),
508
+ _ts_metadata("design:type", Number)
509
+ ], WalletHoldEntity.prototype, "targetAccountId", void 0);
510
+ _ts_decorate([
511
+ typeorm.Column({
512
+ name: "amount",
513
+ type: "bigint"
514
+ }),
515
+ _ts_metadata("design:type", String)
516
+ ], WalletHoldEntity.prototype, "amount", void 0);
517
+ _ts_decorate([
518
+ typeorm.Column({
519
+ name: "status",
520
+ length: 16,
521
+ default: "active"
522
+ }),
523
+ _ts_metadata("design:type", String)
524
+ ], WalletHoldEntity.prototype, "status", void 0);
525
+ _ts_decorate([
526
+ typeorm.Column({
527
+ name: "reference_type",
528
+ length: 64
529
+ }),
530
+ _ts_metadata("design:type", String)
531
+ ], WalletHoldEntity.prototype, "referenceType", void 0);
532
+ _ts_decorate([
533
+ typeorm.Column({
534
+ name: "reference_id",
535
+ length: 128
536
+ }),
537
+ _ts_metadata("design:type", String)
538
+ ], WalletHoldEntity.prototype, "referenceId", void 0);
539
+ _ts_decorate([
540
+ typeorm.Column({
541
+ name: "idempotency_key",
542
+ length: 255
543
+ }),
544
+ _ts_metadata("design:type", String)
545
+ ], WalletHoldEntity.prototype, "idempotencyKey", void 0);
546
+ _ts_decorate([
547
+ typeorm.Column({
548
+ name: "created_by",
549
+ nullable: true
550
+ }),
551
+ _ts_metadata("design:type", Number)
552
+ ], WalletHoldEntity.prototype, "createdBy", void 0);
553
+ _ts_decorate([
554
+ typeorm.Column({
555
+ name: "created_date",
556
+ nullable: true
557
+ }),
558
+ _ts_metadata("design:type", String)
559
+ ], WalletHoldEntity.prototype, "createdDate", void 0);
560
+ _ts_decorate([
561
+ typeorm.Column({
562
+ name: "modified_by",
563
+ nullable: true
564
+ }),
565
+ _ts_metadata("design:type", Number)
566
+ ], WalletHoldEntity.prototype, "modifiedBy", void 0);
567
+ _ts_decorate([
568
+ typeorm.Column({
569
+ name: "modified_date",
570
+ nullable: true
571
+ }),
572
+ _ts_metadata("design:type", String)
573
+ ], WalletHoldEntity.prototype, "modifiedDate", void 0);
574
+ _ts_decorate([
575
+ typeorm.BeforeInsert(),
576
+ _ts_metadata("design:type", Function),
577
+ _ts_metadata("design:paramtypes", []),
578
+ _ts_metadata("design:returntype", void 0)
579
+ ], WalletHoldEntity.prototype, "setCreated", null);
580
+ _ts_decorate([
581
+ typeorm.BeforeUpdate(),
582
+ _ts_metadata("design:type", Function),
583
+ _ts_metadata("design:paramtypes", []),
584
+ _ts_metadata("design:returntype", void 0)
585
+ ], WalletHoldEntity.prototype, "setModified", null);
586
+ WalletHoldEntity = _ts_decorate([
587
+ typeorm.Entity("wallet_hold")
588
+ ], WalletHoldEntity);
589
+
590
+ // src/hooks/reconciliation.ts
591
+ async function runWalletReconciliation() {
592
+ const parityDeltas = await findVendorPaymentHoldParityDeltas();
593
+ const cacheMismatches = await findCacheLedgerMismatches();
594
+ return {
595
+ parityDeltas,
596
+ cacheMismatches
597
+ };
598
+ }
599
+ __name(runWalletReconciliation, "runWalletReconciliation");
600
+ async function findVendorPaymentHoldParityDeltas() {
601
+ const rows = await resolveWalletConnection().query(`
602
+ SELECT
603
+ vo.order_id AS orderId,
604
+ vp.vendor_order_id AS vendorOrderId,
605
+ vp.amount AS vendorPaymentAmount,
606
+ wh.amount AS holdAmount,
607
+ wh.status AS holdStatus
608
+ FROM vendor_payment vp
609
+ INNER JOIN vendor_orders vo ON vo.vendor_order_id = vp.vendor_order_id
610
+ LEFT JOIN wallet_hold wh
611
+ ON wh.reference_type = 'vendor_order'
612
+ AND wh.reference_id = CAST(vp.vendor_order_id AS CHAR)
613
+ WHERE vp.vendor_order_id IS NOT NULL
614
+ `);
615
+ const deltas = [];
616
+ for (const row of rows) {
617
+ const vendorPaymentRupees = Number(row.vendorPaymentAmount) || 0;
618
+ const holdPaise = row.holdAmount != null ? Number(row.holdAmount) : 0;
619
+ const holdRupees = fromMinorUnit(holdPaise);
620
+ const delta = Math.abs(vendorPaymentRupees - holdRupees);
621
+ if (delta > 0.01 && row.holdStatus === "active") {
622
+ deltas.push({
623
+ orderId: Number(row.orderId),
624
+ vendorOrderId: Number(row.vendorOrderId),
625
+ vendorPaymentRupees,
626
+ holdPaise,
627
+ deltaRupees: delta
628
+ });
629
+ }
630
+ }
631
+ return deltas;
632
+ }
633
+ __name(findVendorPaymentHoldParityDeltas, "findVendorPaymentHoldParityDeltas");
634
+ async function findCacheLedgerMismatches() {
635
+ const connection = resolveWalletConnection();
636
+ const accounts = await connection.getRepository(WalletAccountEntity).find();
637
+ const mismatches = [];
638
+ for (const account of accounts) {
639
+ const lastEntry = await connection.getRepository(WalletLedgerEntryEntity).findOne({
640
+ where: {
641
+ accountId: account.id
642
+ },
643
+ order: {
644
+ id: "DESC"
645
+ }
646
+ });
647
+ if (!lastEntry) {
648
+ continue;
649
+ }
650
+ const cachedAvailable = Number(account.availableBalance);
651
+ const cachedHeld = Number(account.heldBalance);
652
+ const ledgerAvailable = Number(lastEntry.balanceAfterAvailable);
653
+ const ledgerHeld = Number(lastEntry.balanceAfterHeld);
654
+ if (cachedAvailable !== ledgerAvailable || cachedHeld !== ledgerHeld) {
655
+ mismatches.push({
656
+ accountId: account.id,
657
+ cachedAvailable,
658
+ cachedHeld,
659
+ ledgerAvailable,
660
+ ledgerHeld
661
+ });
662
+ }
663
+ }
664
+ return mismatches;
665
+ }
666
+ __name(findCacheLedgerMismatches, "findCacheLedgerMismatches");
667
+
668
+ // src/hooks/index.ts
669
+ function createLifecycleHooks(runtime) {
670
+ return {
671
+ ...createOrderHooks(runtime),
672
+ ...createSettlementHooks(runtime),
673
+ ...createRefundHooks(runtime)
674
+ };
675
+ }
676
+ __name(createLifecycleHooks, "createLifecycleHooks");
677
+
678
+ exports.createLifecycleHooks = createLifecycleHooks;
679
+ exports.runWalletReconciliation = runWalletReconciliation;
680
+ //# sourceMappingURL=index.cjs.map
681
+ //# sourceMappingURL=index.cjs.map