multivendor-wallet 0.0.4 → 0.0.6
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 +9 -0
- package/dist/hooks/index.cjs +25 -6
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.d.mts +3 -3
- package/dist/hooks/index.d.ts +3 -3
- package/dist/hooks/index.js +25 -6
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.cjs +347 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +41 -6
- package/dist/index.d.ts +41 -6
- package/dist/index.js +334 -29
- package/dist/index.js.map +1 -1
- package/dist/{store-By30oqos.d.mts → store-nWCfzvwf.d.mts} +1 -0
- package/dist/{store-By30oqos.d.ts → store-nWCfzvwf.d.ts} +1 -0
- package/dist/typeorm/index.cjs +174 -9
- package/dist/typeorm/index.cjs.map +1 -1
- package/dist/typeorm/index.d.mts +11 -2
- package/dist/typeorm/index.d.ts +11 -2
- package/dist/typeorm/index.js +175 -11
- package/dist/typeorm/index.js.map +1 -1
- package/dist/{types-BzaT7Aqh.d.ts → types-B4R1zaTK.d.ts} +16 -2
- package/dist/{types-D46FcrKZ.d.mts → types-D1Q4XCwx.d.mts} +16 -2
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { e as WalletPluginConfig, f as WalletPlugin, I as IWalletPaymentProvider } from './types-
|
|
2
|
-
export { D as DeliveredContext, O as OrderPaidContext, P as PaymentProviderWallet, R as RefundContext, S as SettlementDebitContext, g as WALLET_PLUGIN_TOKEN, h as WalletAdminMutationEvent, i as WalletConfig, C as WalletCreatePaymentInput, j as
|
|
3
|
-
import { W as WalletAccountType } from './store-
|
|
4
|
-
export { B as BalanceDeltas, d as CancelHoldParams, C as CreditParams, D as DebitParams, G as GetTransactionsParams, H as HoldParams, f as HoldStatus, I as IWalletStore, g as IWalletStoreTx, h as LedgerEntryType, L as LedgerMutationResult, R as ReleaseParams, T as TransferParams, b as WalletAccount, c as WalletBalance, i as WalletHold, e as WalletLedgerEntry, j as WalletReference, a as WalletStoreContext } from './store-
|
|
5
|
-
export { CreateWalletTables1790000000000, TypeOrmWalletStore, WalletAccountEntity, WalletHoldEntity, WalletLedgerEntryEntity, getWalletOrmMetadata } from './typeorm/index.mjs';
|
|
1
|
+
import { e as WalletPluginConfig, f as WalletPlugin, I as IWalletPaymentProvider } from './types-D1Q4XCwx.mjs';
|
|
2
|
+
export { D as DeliveredContext, O as OrderPaidContext, P as PaymentProviderWallet, R as RefundContext, S as SettlementDebitContext, g as WALLET_PLUGIN_TOKEN, h as WalletAdminMutationEvent, i as WalletConfig, C as WalletCreatePaymentInput, j as WalletDuplicateOrderDebitInfo, k as WalletDuplicateOrderDebitKind, l as WalletFeatureFlags, m as WalletHttpConfig, n as WalletLedgerClient, W as WalletLifecycleHooks, b as WalletOrderPaidLine, o as WalletReconciliationConfig } from './types-D1Q4XCwx.mjs';
|
|
3
|
+
import { W as WalletAccountType } from './store-nWCfzvwf.mjs';
|
|
4
|
+
export { B as BalanceDeltas, d as CancelHoldParams, C as CreditParams, D as DebitParams, G as GetTransactionsParams, H as HoldParams, f as HoldStatus, I as IWalletStore, g as IWalletStoreTx, h as LedgerEntryType, L as LedgerMutationResult, R as ReleaseParams, T as TransferParams, b as WalletAccount, c as WalletBalance, i as WalletHold, e as WalletLedgerEntry, j as WalletReference, a as WalletStoreContext } from './store-nWCfzvwf.mjs';
|
|
5
|
+
export { AddOrderCustomerDebitUnique1790000001000, CreateWalletTables1790000000000, TypeOrmWalletStore, WalletAccountEntity, WalletHoldEntity, WalletLedgerEntryEntity, getWalletOrmMetadata } from './typeorm/index.mjs';
|
|
6
6
|
import { Router } from 'express';
|
|
7
7
|
import 'typeorm';
|
|
8
8
|
|
|
@@ -39,6 +39,41 @@ declare function registerWalletPlugin(config: WalletPluginConfig): WalletPlugin;
|
|
|
39
39
|
|
|
40
40
|
declare function createWalletPaymentAdapter(plugin: WalletPlugin): IWalletPaymentProvider;
|
|
41
41
|
|
|
42
|
+
/** Server-local wall clock `YYYY-MM-DD HH:mm:ss` (matches host order paidDate, not UTC ISO). */
|
|
43
|
+
declare function nowTimestamp(date?: Date): string;
|
|
44
|
+
/** Parse naive datetime as local wall clock (do not treat as UTC). */
|
|
45
|
+
declare function parseLedgerDate(value: string | Date): Date;
|
|
46
|
+
|
|
47
|
+
declare const CUSTOMER_CHECKOUT_DEBIT_PURPOSE = "customer_checkout_debit";
|
|
48
|
+
declare const CUSTOMER_CHECKOUT_DEBIT_REVERSAL_PURPOSE = "customer_checkout_debit_reversal";
|
|
49
|
+
declare const BACKFILL_SENTINEL_KEY = "customer_checkout_debit_backfill";
|
|
50
|
+
declare const WALLET_OPS_TABLE = "wallet_ops";
|
|
51
|
+
declare function orderCustomerDebitIdempotencyKey(orderId: number | string): string;
|
|
52
|
+
declare function paymentReversalIdempotencyKey(paymentNumber: string): string;
|
|
53
|
+
declare function paymentNumberFromWalletPaymentKey(idempotencyKey: string): string | null;
|
|
54
|
+
/**
|
|
55
|
+
* True when this debit is a customer checkout (product-amount) debit for an order.
|
|
56
|
+
* Settlement/vendor/affiliate debits must not use these keys or purpose.
|
|
57
|
+
*/
|
|
58
|
+
declare function isCustomerCheckoutDebit(params: {
|
|
59
|
+
idempotencyKey: string;
|
|
60
|
+
referenceType?: string;
|
|
61
|
+
purpose?: unknown;
|
|
62
|
+
}): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Legacy keys accepted during rollout only.
|
|
65
|
+
* Sunset: `npm run wallet:legacy-order-debit-sunset` — drop this helper when LEGACY_ORDER_DEBIT_SUNSET_SQL returns 0 on prod.
|
|
66
|
+
*/
|
|
67
|
+
declare function isLegacyCustomerCheckoutDebitKey(key: string): boolean;
|
|
68
|
+
/** Unreimbursed full/split + wallet:payment twins (duplicate customer checkout debits). */
|
|
69
|
+
declare const UNREIMBURSED_TWIN_COUNT_SQL = "\nSELECT COUNT(*) AS c\nFROM wallet_ledger_entry f\nJOIN wallet_ledger_entry p\n ON p.account_id = f.account_id\n AND p.reference_type = 'order'\n AND p.reference_id = f.reference_id\n AND p.entry_type = 'debit'\n AND p.idempotency_key LIKE 'wallet:payment:%'\nWHERE f.entry_type = 'debit'\n AND f.reference_type = 'order'\n AND (\n f.idempotency_key LIKE 'wallet:full:%'\n OR f.idempotency_key LIKE 'wallet:split:%'\n )\n AND NOT EXISTS (\n SELECT 1 FROM wallet_ledger_entry r\n WHERE r.entry_type = 'credit'\n AND r.account_id = p.account_id\n AND r.reference_type = 'order'\n AND r.reference_id = p.reference_id\n AND (\n r.idempotency_key = CONCAT('wallet:payment-reversal:', SUBSTRING(p.idempotency_key, 17))\n OR JSON_UNQUOTE(JSON_EXTRACT(r.metadata, '$.purpose')) = 'customer_checkout_debit_reversal'\n )\n )\n";
|
|
70
|
+
declare const UNREIMBURSED_TWIN_DETAIL_SQL = "\nSELECT\n f.reference_id AS order_id,\n f.account_id,\n f.amount AS first_paise,\n p.amount AS second_paise,\n f.idempotency_key AS kept_key,\n p.idempotency_key AS duplicate_key,\n f.created_date AS first_at,\n p.created_date AS duplicate_at,\n f.id AS kept_id,\n p.id AS duplicate_id\nFROM wallet_ledger_entry f\nJOIN wallet_ledger_entry p\n ON p.account_id = f.account_id\n AND p.reference_type = 'order'\n AND p.reference_id = f.reference_id\n AND p.entry_type = 'debit'\n AND p.idempotency_key LIKE 'wallet:payment:%'\nWHERE f.entry_type = 'debit'\n AND f.reference_type = 'order'\n AND (\n f.idempotency_key LIKE 'wallet:full:%'\n OR f.idempotency_key LIKE 'wallet:split:%'\n )\n AND NOT EXISTS (\n SELECT 1 FROM wallet_ledger_entry r\n WHERE r.entry_type = 'credit'\n AND r.account_id = p.account_id\n AND r.reference_type = 'order'\n AND r.reference_id = p.reference_id\n AND (\n r.idempotency_key = CONCAT('wallet:payment-reversal:', SUBSTRING(p.idempotency_key, 17))\n OR JSON_UNQUOTE(JSON_EXTRACT(r.metadata, '$.purpose')) = 'customer_checkout_debit_reversal'\n )\n )\n";
|
|
71
|
+
/**
|
|
72
|
+
* Exit condition for removing isLegacyCustomerCheckoutDebitKey from debit lookup.
|
|
73
|
+
* File the sunset PR the same week this count hits 0 on prod.
|
|
74
|
+
*/
|
|
75
|
+
declare const LEGACY_ORDER_DEBIT_SUNSET_SQL = "\nSELECT COUNT(*) AS c\nFROM wallet_ledger_entry\nWHERE entry_type = 'debit'\n AND reference_type = 'order'\n AND (\n idempotency_key LIKE 'wallet:full:%'\n OR idempotency_key LIKE 'wallet:split:%'\n OR idempotency_key LIKE 'wallet:payment:%'\n )\n";
|
|
76
|
+
|
|
42
77
|
declare class WalletCreditDebitRequest {
|
|
43
78
|
ownerType: WalletAccountType;
|
|
44
79
|
ownerId: number;
|
|
@@ -128,4 +163,4 @@ declare class VendorWalletController {
|
|
|
128
163
|
|
|
129
164
|
declare function createExpressWalletRouter(plugin: WalletPlugin, _basePath?: string): Router;
|
|
130
165
|
|
|
131
|
-
export { AdminWalletController, CustomerWalletController, DuplicateOperationError, HoldNotFoundError, IWalletPaymentProvider, InsufficientBalanceError, InvalidAmountError, VendorWalletController, WalletAccountType, WalletConfigError, WalletError, WalletPlugin, WalletPluginConfig, createExpressWalletRouter, createWalletPaymentAdapter, fromMinorUnit, registerWalletPlugin, toMinorUnit };
|
|
166
|
+
export { AdminWalletController, BACKFILL_SENTINEL_KEY, CUSTOMER_CHECKOUT_DEBIT_PURPOSE, CUSTOMER_CHECKOUT_DEBIT_REVERSAL_PURPOSE, CustomerWalletController, DuplicateOperationError, HoldNotFoundError, IWalletPaymentProvider, InsufficientBalanceError, InvalidAmountError, LEGACY_ORDER_DEBIT_SUNSET_SQL, UNREIMBURSED_TWIN_COUNT_SQL, UNREIMBURSED_TWIN_DETAIL_SQL, VendorWalletController, WALLET_OPS_TABLE, WalletAccountType, WalletConfigError, WalletError, WalletPlugin, WalletPluginConfig, createExpressWalletRouter, createWalletPaymentAdapter, fromMinorUnit, isCustomerCheckoutDebit, isLegacyCustomerCheckoutDebitKey, nowTimestamp, orderCustomerDebitIdempotencyKey, parseLedgerDate, paymentNumberFromWalletPaymentKey, paymentReversalIdempotencyKey, registerWalletPlugin, toMinorUnit };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { e as WalletPluginConfig, f as WalletPlugin, I as IWalletPaymentProvider } from './types-
|
|
2
|
-
export { D as DeliveredContext, O as OrderPaidContext, P as PaymentProviderWallet, R as RefundContext, S as SettlementDebitContext, g as WALLET_PLUGIN_TOKEN, h as WalletAdminMutationEvent, i as WalletConfig, C as WalletCreatePaymentInput, j as
|
|
3
|
-
import { W as WalletAccountType } from './store-
|
|
4
|
-
export { B as BalanceDeltas, d as CancelHoldParams, C as CreditParams, D as DebitParams, G as GetTransactionsParams, H as HoldParams, f as HoldStatus, I as IWalletStore, g as IWalletStoreTx, h as LedgerEntryType, L as LedgerMutationResult, R as ReleaseParams, T as TransferParams, b as WalletAccount, c as WalletBalance, i as WalletHold, e as WalletLedgerEntry, j as WalletReference, a as WalletStoreContext } from './store-
|
|
5
|
-
export { CreateWalletTables1790000000000, TypeOrmWalletStore, WalletAccountEntity, WalletHoldEntity, WalletLedgerEntryEntity, getWalletOrmMetadata } from './typeorm/index.js';
|
|
1
|
+
import { e as WalletPluginConfig, f as WalletPlugin, I as IWalletPaymentProvider } from './types-B4R1zaTK.js';
|
|
2
|
+
export { D as DeliveredContext, O as OrderPaidContext, P as PaymentProviderWallet, R as RefundContext, S as SettlementDebitContext, g as WALLET_PLUGIN_TOKEN, h as WalletAdminMutationEvent, i as WalletConfig, C as WalletCreatePaymentInput, j as WalletDuplicateOrderDebitInfo, k as WalletDuplicateOrderDebitKind, l as WalletFeatureFlags, m as WalletHttpConfig, n as WalletLedgerClient, W as WalletLifecycleHooks, b as WalletOrderPaidLine, o as WalletReconciliationConfig } from './types-B4R1zaTK.js';
|
|
3
|
+
import { W as WalletAccountType } from './store-nWCfzvwf.js';
|
|
4
|
+
export { B as BalanceDeltas, d as CancelHoldParams, C as CreditParams, D as DebitParams, G as GetTransactionsParams, H as HoldParams, f as HoldStatus, I as IWalletStore, g as IWalletStoreTx, h as LedgerEntryType, L as LedgerMutationResult, R as ReleaseParams, T as TransferParams, b as WalletAccount, c as WalletBalance, i as WalletHold, e as WalletLedgerEntry, j as WalletReference, a as WalletStoreContext } from './store-nWCfzvwf.js';
|
|
5
|
+
export { AddOrderCustomerDebitUnique1790000001000, CreateWalletTables1790000000000, TypeOrmWalletStore, WalletAccountEntity, WalletHoldEntity, WalletLedgerEntryEntity, getWalletOrmMetadata } from './typeorm/index.js';
|
|
6
6
|
import { Router } from 'express';
|
|
7
7
|
import 'typeorm';
|
|
8
8
|
|
|
@@ -39,6 +39,41 @@ declare function registerWalletPlugin(config: WalletPluginConfig): WalletPlugin;
|
|
|
39
39
|
|
|
40
40
|
declare function createWalletPaymentAdapter(plugin: WalletPlugin): IWalletPaymentProvider;
|
|
41
41
|
|
|
42
|
+
/** Server-local wall clock `YYYY-MM-DD HH:mm:ss` (matches host order paidDate, not UTC ISO). */
|
|
43
|
+
declare function nowTimestamp(date?: Date): string;
|
|
44
|
+
/** Parse naive datetime as local wall clock (do not treat as UTC). */
|
|
45
|
+
declare function parseLedgerDate(value: string | Date): Date;
|
|
46
|
+
|
|
47
|
+
declare const CUSTOMER_CHECKOUT_DEBIT_PURPOSE = "customer_checkout_debit";
|
|
48
|
+
declare const CUSTOMER_CHECKOUT_DEBIT_REVERSAL_PURPOSE = "customer_checkout_debit_reversal";
|
|
49
|
+
declare const BACKFILL_SENTINEL_KEY = "customer_checkout_debit_backfill";
|
|
50
|
+
declare const WALLET_OPS_TABLE = "wallet_ops";
|
|
51
|
+
declare function orderCustomerDebitIdempotencyKey(orderId: number | string): string;
|
|
52
|
+
declare function paymentReversalIdempotencyKey(paymentNumber: string): string;
|
|
53
|
+
declare function paymentNumberFromWalletPaymentKey(idempotencyKey: string): string | null;
|
|
54
|
+
/**
|
|
55
|
+
* True when this debit is a customer checkout (product-amount) debit for an order.
|
|
56
|
+
* Settlement/vendor/affiliate debits must not use these keys or purpose.
|
|
57
|
+
*/
|
|
58
|
+
declare function isCustomerCheckoutDebit(params: {
|
|
59
|
+
idempotencyKey: string;
|
|
60
|
+
referenceType?: string;
|
|
61
|
+
purpose?: unknown;
|
|
62
|
+
}): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Legacy keys accepted during rollout only.
|
|
65
|
+
* Sunset: `npm run wallet:legacy-order-debit-sunset` — drop this helper when LEGACY_ORDER_DEBIT_SUNSET_SQL returns 0 on prod.
|
|
66
|
+
*/
|
|
67
|
+
declare function isLegacyCustomerCheckoutDebitKey(key: string): boolean;
|
|
68
|
+
/** Unreimbursed full/split + wallet:payment twins (duplicate customer checkout debits). */
|
|
69
|
+
declare const UNREIMBURSED_TWIN_COUNT_SQL = "\nSELECT COUNT(*) AS c\nFROM wallet_ledger_entry f\nJOIN wallet_ledger_entry p\n ON p.account_id = f.account_id\n AND p.reference_type = 'order'\n AND p.reference_id = f.reference_id\n AND p.entry_type = 'debit'\n AND p.idempotency_key LIKE 'wallet:payment:%'\nWHERE f.entry_type = 'debit'\n AND f.reference_type = 'order'\n AND (\n f.idempotency_key LIKE 'wallet:full:%'\n OR f.idempotency_key LIKE 'wallet:split:%'\n )\n AND NOT EXISTS (\n SELECT 1 FROM wallet_ledger_entry r\n WHERE r.entry_type = 'credit'\n AND r.account_id = p.account_id\n AND r.reference_type = 'order'\n AND r.reference_id = p.reference_id\n AND (\n r.idempotency_key = CONCAT('wallet:payment-reversal:', SUBSTRING(p.idempotency_key, 17))\n OR JSON_UNQUOTE(JSON_EXTRACT(r.metadata, '$.purpose')) = 'customer_checkout_debit_reversal'\n )\n )\n";
|
|
70
|
+
declare const UNREIMBURSED_TWIN_DETAIL_SQL = "\nSELECT\n f.reference_id AS order_id,\n f.account_id,\n f.amount AS first_paise,\n p.amount AS second_paise,\n f.idempotency_key AS kept_key,\n p.idempotency_key AS duplicate_key,\n f.created_date AS first_at,\n p.created_date AS duplicate_at,\n f.id AS kept_id,\n p.id AS duplicate_id\nFROM wallet_ledger_entry f\nJOIN wallet_ledger_entry p\n ON p.account_id = f.account_id\n AND p.reference_type = 'order'\n AND p.reference_id = f.reference_id\n AND p.entry_type = 'debit'\n AND p.idempotency_key LIKE 'wallet:payment:%'\nWHERE f.entry_type = 'debit'\n AND f.reference_type = 'order'\n AND (\n f.idempotency_key LIKE 'wallet:full:%'\n OR f.idempotency_key LIKE 'wallet:split:%'\n )\n AND NOT EXISTS (\n SELECT 1 FROM wallet_ledger_entry r\n WHERE r.entry_type = 'credit'\n AND r.account_id = p.account_id\n AND r.reference_type = 'order'\n AND r.reference_id = p.reference_id\n AND (\n r.idempotency_key = CONCAT('wallet:payment-reversal:', SUBSTRING(p.idempotency_key, 17))\n OR JSON_UNQUOTE(JSON_EXTRACT(r.metadata, '$.purpose')) = 'customer_checkout_debit_reversal'\n )\n )\n";
|
|
71
|
+
/**
|
|
72
|
+
* Exit condition for removing isLegacyCustomerCheckoutDebitKey from debit lookup.
|
|
73
|
+
* File the sunset PR the same week this count hits 0 on prod.
|
|
74
|
+
*/
|
|
75
|
+
declare const LEGACY_ORDER_DEBIT_SUNSET_SQL = "\nSELECT COUNT(*) AS c\nFROM wallet_ledger_entry\nWHERE entry_type = 'debit'\n AND reference_type = 'order'\n AND (\n idempotency_key LIKE 'wallet:full:%'\n OR idempotency_key LIKE 'wallet:split:%'\n OR idempotency_key LIKE 'wallet:payment:%'\n )\n";
|
|
76
|
+
|
|
42
77
|
declare class WalletCreditDebitRequest {
|
|
43
78
|
ownerType: WalletAccountType;
|
|
44
79
|
ownerId: number;
|
|
@@ -128,4 +163,4 @@ declare class VendorWalletController {
|
|
|
128
163
|
|
|
129
164
|
declare function createExpressWalletRouter(plugin: WalletPlugin, _basePath?: string): Router;
|
|
130
165
|
|
|
131
|
-
export { AdminWalletController, CustomerWalletController, DuplicateOperationError, HoldNotFoundError, IWalletPaymentProvider, InsufficientBalanceError, InvalidAmountError, VendorWalletController, WalletAccountType, WalletConfigError, WalletError, WalletPlugin, WalletPluginConfig, createExpressWalletRouter, createWalletPaymentAdapter, fromMinorUnit, registerWalletPlugin, toMinorUnit };
|
|
166
|
+
export { AdminWalletController, BACKFILL_SENTINEL_KEY, CUSTOMER_CHECKOUT_DEBIT_PURPOSE, CUSTOMER_CHECKOUT_DEBIT_REVERSAL_PURPOSE, CustomerWalletController, DuplicateOperationError, HoldNotFoundError, IWalletPaymentProvider, InsufficientBalanceError, InvalidAmountError, LEGACY_ORDER_DEBIT_SUNSET_SQL, UNREIMBURSED_TWIN_COUNT_SQL, UNREIMBURSED_TWIN_DETAIL_SQL, VendorWalletController, WALLET_OPS_TABLE, WalletAccountType, WalletConfigError, WalletError, WalletPlugin, WalletPluginConfig, createExpressWalletRouter, createWalletPaymentAdapter, fromMinorUnit, isCustomerCheckoutDebit, isLegacyCustomerCheckoutDebitKey, nowTimestamp, orderCustomerDebitIdempotencyKey, parseLedgerDate, paymentNumberFromWalletPaymentKey, paymentReversalIdempotencyKey, registerWalletPlugin, toMinorUnit };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PrimaryGeneratedColumn, Column, BeforeInsert, BeforeUpdate, Entity } from 'typeorm';
|
|
1
|
+
import { PrimaryGeneratedColumn, Column, BeforeInsert, BeforeUpdate, Entity, Brackets } from 'typeorm';
|
|
2
2
|
import 'reflect-metadata';
|
|
3
3
|
import { Get, Authorized, QueryParam, Res, Param, Post, Body, Req, JsonController } from 'routing-controllers';
|
|
4
4
|
import { IsString, IsNotEmpty, IsInt, Min, IsNumber, IsOptional } from 'class-validator';
|
|
@@ -67,6 +67,121 @@ var _InvalidAmountError = class _InvalidAmountError extends WalletError {
|
|
|
67
67
|
__name(_InvalidAmountError, "InvalidAmountError");
|
|
68
68
|
var InvalidAmountError = _InvalidAmountError;
|
|
69
69
|
|
|
70
|
+
// src/orderCustomerDebit.ts
|
|
71
|
+
var CUSTOMER_CHECKOUT_DEBIT_PURPOSE = "customer_checkout_debit";
|
|
72
|
+
var CUSTOMER_CHECKOUT_DEBIT_REVERSAL_PURPOSE = "customer_checkout_debit_reversal";
|
|
73
|
+
var BACKFILL_SENTINEL_KEY = "customer_checkout_debit_backfill";
|
|
74
|
+
var WALLET_OPS_TABLE = "wallet_ops";
|
|
75
|
+
function orderCustomerDebitIdempotencyKey(orderId) {
|
|
76
|
+
return `wallet:order:${orderId}:customer_debit`;
|
|
77
|
+
}
|
|
78
|
+
__name(orderCustomerDebitIdempotencyKey, "orderCustomerDebitIdempotencyKey");
|
|
79
|
+
function paymentReversalIdempotencyKey(paymentNumber) {
|
|
80
|
+
return `wallet:payment-reversal:${paymentNumber}`;
|
|
81
|
+
}
|
|
82
|
+
__name(paymentReversalIdempotencyKey, "paymentReversalIdempotencyKey");
|
|
83
|
+
function paymentNumberFromWalletPaymentKey(idempotencyKey) {
|
|
84
|
+
const prefix = "wallet:payment:";
|
|
85
|
+
if (!idempotencyKey.startsWith(prefix)) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
return idempotencyKey.slice(prefix.length);
|
|
89
|
+
}
|
|
90
|
+
__name(paymentNumberFromWalletPaymentKey, "paymentNumberFromWalletPaymentKey");
|
|
91
|
+
function isCustomerCheckoutDebit(params) {
|
|
92
|
+
if (params.purpose === CUSTOMER_CHECKOUT_DEBIT_PURPOSE) {
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
const key = params.idempotencyKey;
|
|
96
|
+
if (key.startsWith("wallet:order:") && key.endsWith(":customer_debit")) {
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
if (params.referenceType !== "order") {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
return isLegacyCustomerCheckoutDebitKey(key);
|
|
103
|
+
}
|
|
104
|
+
__name(isCustomerCheckoutDebit, "isCustomerCheckoutDebit");
|
|
105
|
+
function isLegacyCustomerCheckoutDebitKey(key) {
|
|
106
|
+
return key.startsWith("wallet:full:") || key.startsWith("wallet:split:") || key.startsWith("wallet:payment:");
|
|
107
|
+
}
|
|
108
|
+
__name(isLegacyCustomerCheckoutDebitKey, "isLegacyCustomerCheckoutDebitKey");
|
|
109
|
+
var UNREIMBURSED_TWIN_COUNT_SQL = `
|
|
110
|
+
SELECT COUNT(*) AS c
|
|
111
|
+
FROM wallet_ledger_entry f
|
|
112
|
+
JOIN wallet_ledger_entry p
|
|
113
|
+
ON p.account_id = f.account_id
|
|
114
|
+
AND p.reference_type = 'order'
|
|
115
|
+
AND p.reference_id = f.reference_id
|
|
116
|
+
AND p.entry_type = 'debit'
|
|
117
|
+
AND p.idempotency_key LIKE 'wallet:payment:%'
|
|
118
|
+
WHERE f.entry_type = 'debit'
|
|
119
|
+
AND f.reference_type = 'order'
|
|
120
|
+
AND (
|
|
121
|
+
f.idempotency_key LIKE 'wallet:full:%'
|
|
122
|
+
OR f.idempotency_key LIKE 'wallet:split:%'
|
|
123
|
+
)
|
|
124
|
+
AND NOT EXISTS (
|
|
125
|
+
SELECT 1 FROM wallet_ledger_entry r
|
|
126
|
+
WHERE r.entry_type = 'credit'
|
|
127
|
+
AND r.account_id = p.account_id
|
|
128
|
+
AND r.reference_type = 'order'
|
|
129
|
+
AND r.reference_id = p.reference_id
|
|
130
|
+
AND (
|
|
131
|
+
r.idempotency_key = CONCAT('wallet:payment-reversal:', SUBSTRING(p.idempotency_key, 17))
|
|
132
|
+
OR JSON_UNQUOTE(JSON_EXTRACT(r.metadata, '$.purpose')) = 'customer_checkout_debit_reversal'
|
|
133
|
+
)
|
|
134
|
+
)
|
|
135
|
+
`;
|
|
136
|
+
var UNREIMBURSED_TWIN_DETAIL_SQL = `
|
|
137
|
+
SELECT
|
|
138
|
+
f.reference_id AS order_id,
|
|
139
|
+
f.account_id,
|
|
140
|
+
f.amount AS first_paise,
|
|
141
|
+
p.amount AS second_paise,
|
|
142
|
+
f.idempotency_key AS kept_key,
|
|
143
|
+
p.idempotency_key AS duplicate_key,
|
|
144
|
+
f.created_date AS first_at,
|
|
145
|
+
p.created_date AS duplicate_at,
|
|
146
|
+
f.id AS kept_id,
|
|
147
|
+
p.id AS duplicate_id
|
|
148
|
+
FROM wallet_ledger_entry f
|
|
149
|
+
JOIN wallet_ledger_entry p
|
|
150
|
+
ON p.account_id = f.account_id
|
|
151
|
+
AND p.reference_type = 'order'
|
|
152
|
+
AND p.reference_id = f.reference_id
|
|
153
|
+
AND p.entry_type = 'debit'
|
|
154
|
+
AND p.idempotency_key LIKE 'wallet:payment:%'
|
|
155
|
+
WHERE f.entry_type = 'debit'
|
|
156
|
+
AND f.reference_type = 'order'
|
|
157
|
+
AND (
|
|
158
|
+
f.idempotency_key LIKE 'wallet:full:%'
|
|
159
|
+
OR f.idempotency_key LIKE 'wallet:split:%'
|
|
160
|
+
)
|
|
161
|
+
AND NOT EXISTS (
|
|
162
|
+
SELECT 1 FROM wallet_ledger_entry r
|
|
163
|
+
WHERE r.entry_type = 'credit'
|
|
164
|
+
AND r.account_id = p.account_id
|
|
165
|
+
AND r.reference_type = 'order'
|
|
166
|
+
AND r.reference_id = p.reference_id
|
|
167
|
+
AND (
|
|
168
|
+
r.idempotency_key = CONCAT('wallet:payment-reversal:', SUBSTRING(p.idempotency_key, 17))
|
|
169
|
+
OR JSON_UNQUOTE(JSON_EXTRACT(r.metadata, '$.purpose')) = 'customer_checkout_debit_reversal'
|
|
170
|
+
)
|
|
171
|
+
)
|
|
172
|
+
`;
|
|
173
|
+
var LEGACY_ORDER_DEBIT_SUNSET_SQL = `
|
|
174
|
+
SELECT COUNT(*) AS c
|
|
175
|
+
FROM wallet_ledger_entry
|
|
176
|
+
WHERE entry_type = 'debit'
|
|
177
|
+
AND reference_type = 'order'
|
|
178
|
+
AND (
|
|
179
|
+
idempotency_key LIKE 'wallet:full:%'
|
|
180
|
+
OR idempotency_key LIKE 'wallet:split:%'
|
|
181
|
+
OR idempotency_key LIKE 'wallet:payment:%'
|
|
182
|
+
)
|
|
183
|
+
`;
|
|
184
|
+
|
|
70
185
|
// src/types.ts
|
|
71
186
|
var WalletAccountType = /* @__PURE__ */ (function(WalletAccountType2) {
|
|
72
187
|
WalletAccountType2["CUSTOMER"] = "customer";
|
|
@@ -194,6 +309,7 @@ var _WalletLedgerClient = class _WalletLedgerClient {
|
|
|
194
309
|
async debitInTx(tx, params) {
|
|
195
310
|
const existing = await tx.findLedgerByIdempotencyKey(params.idempotencyKey);
|
|
196
311
|
if (existing) {
|
|
312
|
+
this.notifyDuplicateOrderDebit(params, existing, "idempotent_retry");
|
|
197
313
|
const account = await tx.getAccountById(existing.accountId);
|
|
198
314
|
if (!account) {
|
|
199
315
|
throw new Error(`Wallet account ${existing.accountId} not found`);
|
|
@@ -204,27 +320,85 @@ var _WalletLedgerClient = class _WalletLedgerClient {
|
|
|
204
320
|
};
|
|
205
321
|
}
|
|
206
322
|
const locked = await tx.lockAccount(params.accountId);
|
|
323
|
+
const orderId = params.reference?.referenceId;
|
|
324
|
+
const checkoutDebit = isCustomerCheckoutDebit({
|
|
325
|
+
idempotencyKey: params.idempotencyKey,
|
|
326
|
+
referenceType: params.reference?.referenceType,
|
|
327
|
+
purpose: params.metadata?.purpose
|
|
328
|
+
});
|
|
329
|
+
if (checkoutDebit && orderId) {
|
|
330
|
+
const existingPurpose = await tx.findOrderCustomerCheckoutDebit(params.accountId, orderId);
|
|
331
|
+
if (existingPurpose) {
|
|
332
|
+
const kind = existingPurpose.idempotencyKey === params.idempotencyKey ? "idempotent_retry" : "cross_key_collision";
|
|
333
|
+
this.notifyDuplicateOrderDebit(params, existingPurpose, kind);
|
|
334
|
+
return {
|
|
335
|
+
entry: existingPurpose,
|
|
336
|
+
account: locked
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
}
|
|
207
340
|
if (locked.availableBalance < params.amount) {
|
|
208
341
|
throw new InsufficientBalanceError();
|
|
209
342
|
}
|
|
210
343
|
const updated = await tx.updateBalances(params.accountId, {
|
|
211
344
|
availableDelta: -params.amount
|
|
212
345
|
});
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
346
|
+
try {
|
|
347
|
+
const entry = await tx.appendLedgerEntry({
|
|
348
|
+
accountId: params.accountId,
|
|
349
|
+
entryType: LedgerEntryType.DEBIT,
|
|
350
|
+
amount: params.amount,
|
|
351
|
+
balanceAfterAvailable: updated.availableBalance,
|
|
352
|
+
balanceAfterHeld: updated.heldBalance,
|
|
353
|
+
idempotencyKey: params.idempotencyKey,
|
|
354
|
+
referenceType: params.reference?.referenceType,
|
|
355
|
+
referenceId: params.reference?.referenceId,
|
|
356
|
+
metadata: params.metadata
|
|
357
|
+
});
|
|
358
|
+
return {
|
|
359
|
+
entry,
|
|
360
|
+
account: updated
|
|
361
|
+
};
|
|
362
|
+
} catch (error) {
|
|
363
|
+
if (error instanceof DuplicateOperationError && checkoutDebit && orderId) {
|
|
364
|
+
const dup = await tx.findOrderCustomerCheckoutDebit(params.accountId, orderId);
|
|
365
|
+
if (dup) {
|
|
366
|
+
const restored = await tx.updateBalances(params.accountId, {
|
|
367
|
+
availableDelta: params.amount
|
|
368
|
+
});
|
|
369
|
+
this.notifyDuplicateOrderDebit(params, dup, "cross_key_collision");
|
|
370
|
+
return {
|
|
371
|
+
entry: dup,
|
|
372
|
+
account: restored
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
throw error;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
notifyDuplicateOrderDebit(params, existing, kind) {
|
|
380
|
+
const orderId = params.reference?.referenceId ?? existing.referenceId;
|
|
381
|
+
if (!orderId) {
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
const checkoutDebit = isCustomerCheckoutDebit({
|
|
219
385
|
idempotencyKey: params.idempotencyKey,
|
|
220
|
-
referenceType: params.reference?.referenceType,
|
|
221
|
-
|
|
222
|
-
metadata: params.metadata
|
|
386
|
+
referenceType: params.reference?.referenceType ?? existing.referenceType,
|
|
387
|
+
purpose: params.metadata?.purpose ?? existing.metadata?.purpose
|
|
223
388
|
});
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
389
|
+
if (!checkoutDebit) {
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
try {
|
|
393
|
+
this.config.onDuplicateOrderDebit?.({
|
|
394
|
+
orderId,
|
|
395
|
+
accountId: params.accountId,
|
|
396
|
+
requestedKey: params.idempotencyKey,
|
|
397
|
+
existingKey: existing.idempotencyKey,
|
|
398
|
+
kind
|
|
399
|
+
});
|
|
400
|
+
} catch {
|
|
401
|
+
}
|
|
228
402
|
}
|
|
229
403
|
async holdInTx(tx, params) {
|
|
230
404
|
const existing = await tx.findLedgerByIdempotencyKey(params.idempotencyKey);
|
|
@@ -448,10 +622,14 @@ function createOrderHooks(runtime) {
|
|
|
448
622
|
await client.debit({
|
|
449
623
|
accountId: customer.id,
|
|
450
624
|
amount: toMinorUnit(debitRupees),
|
|
451
|
-
idempotencyKey:
|
|
625
|
+
idempotencyKey: orderCustomerDebitIdempotencyKey(ctx.orderId),
|
|
452
626
|
reference: {
|
|
453
627
|
referenceType: "order",
|
|
454
628
|
referenceId: String(ctx.orderId)
|
|
629
|
+
},
|
|
630
|
+
metadata: {
|
|
631
|
+
purpose: CUSTOMER_CHECKOUT_DEBIT_PURPOSE,
|
|
632
|
+
paymentNumber: ctx.paymentNumber
|
|
455
633
|
}
|
|
456
634
|
}, txCtx);
|
|
457
635
|
}
|
|
@@ -465,7 +643,7 @@ function createOrderHooks(runtime) {
|
|
|
465
643
|
}
|
|
466
644
|
}, txCtx);
|
|
467
645
|
for (const line of ctx.lines) {
|
|
468
|
-
const vendorNetRupees = line.commissionBaseRupees - line.commissionRupees;
|
|
646
|
+
const vendorNetRupees = line.sellerNetRupees != null && Number.isFinite(Number(line.sellerNetRupees)) ? Number(line.sellerNetRupees) : line.commissionBaseRupees - line.commissionRupees;
|
|
469
647
|
if (vendorNetRupees <= 0) {
|
|
470
648
|
continue;
|
|
471
649
|
}
|
|
@@ -606,6 +784,29 @@ function resolveWalletConnection() {
|
|
|
606
784
|
return activeConnection;
|
|
607
785
|
}
|
|
608
786
|
__name(resolveWalletConnection, "resolveWalletConnection");
|
|
787
|
+
|
|
788
|
+
// src/timestamps.ts
|
|
789
|
+
function pad2(value) {
|
|
790
|
+
return String(value).padStart(2, "0");
|
|
791
|
+
}
|
|
792
|
+
__name(pad2, "pad2");
|
|
793
|
+
function nowTimestamp(date = /* @__PURE__ */ new Date()) {
|
|
794
|
+
return `${date.getFullYear()}-${pad2(date.getMonth() + 1)}-${pad2(date.getDate())} ${pad2(date.getHours())}:${pad2(date.getMinutes())}:${pad2(date.getSeconds())}`;
|
|
795
|
+
}
|
|
796
|
+
__name(nowTimestamp, "nowTimestamp");
|
|
797
|
+
function parseLedgerDate(value) {
|
|
798
|
+
if (value instanceof Date) {
|
|
799
|
+
return value;
|
|
800
|
+
}
|
|
801
|
+
const match = /^(\d{4})-(\d{2})-(\d{2})[ T](\d{2}):(\d{2}):(\d{2})/.exec(String(value));
|
|
802
|
+
if (!match) {
|
|
803
|
+
return new Date(value);
|
|
804
|
+
}
|
|
805
|
+
return new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3]), Number(match[4]), Number(match[5]), Number(match[6]));
|
|
806
|
+
}
|
|
807
|
+
__name(parseLedgerDate, "parseLedgerDate");
|
|
808
|
+
|
|
809
|
+
// src/typeorm/entities.ts
|
|
609
810
|
function _ts_decorate(decorators, target, key, desc) {
|
|
610
811
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
611
812
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -617,10 +818,6 @@ function _ts_metadata(k, v) {
|
|
|
617
818
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
618
819
|
}
|
|
619
820
|
__name(_ts_metadata, "_ts_metadata");
|
|
620
|
-
function nowTimestamp() {
|
|
621
|
-
return (/* @__PURE__ */ new Date()).toISOString().slice(0, 19).replace("T", " ");
|
|
622
|
-
}
|
|
623
|
-
__name(nowTimestamp, "nowTimestamp");
|
|
624
821
|
var _WalletAccountEntity = class _WalletAccountEntity {
|
|
625
822
|
constructor() {
|
|
626
823
|
__publicField(this, "id");
|
|
@@ -1702,8 +1899,6 @@ function createWalletPaymentAdapter(plugin) {
|
|
|
1702
1899
|
};
|
|
1703
1900
|
}
|
|
1704
1901
|
__name(createWalletPaymentAdapter, "createWalletPaymentAdapter");
|
|
1705
|
-
|
|
1706
|
-
// src/typeorm/store.ts
|
|
1707
1902
|
function toNumber(value) {
|
|
1708
1903
|
if (value == null) {
|
|
1709
1904
|
return 0;
|
|
@@ -1732,7 +1927,7 @@ function toLedgerHold(row) {
|
|
|
1732
1927
|
referenceType: row.referenceType,
|
|
1733
1928
|
referenceId: row.referenceId,
|
|
1734
1929
|
idempotencyKey: row.idempotencyKey,
|
|
1735
|
-
createdAt:
|
|
1930
|
+
createdAt: parseLedgerDate(row.createdDate)
|
|
1736
1931
|
};
|
|
1737
1932
|
}
|
|
1738
1933
|
__name(toLedgerHold, "toLedgerHold");
|
|
@@ -1748,7 +1943,7 @@ function toLedgerEntry(row) {
|
|
|
1748
1943
|
referenceType: row.referenceType,
|
|
1749
1944
|
referenceId: row.referenceId,
|
|
1750
1945
|
metadata: row.metadata,
|
|
1751
|
-
createdAt:
|
|
1946
|
+
createdAt: parseLedgerDate(row.createdDate)
|
|
1752
1947
|
};
|
|
1753
1948
|
}
|
|
1754
1949
|
__name(toLedgerEntry, "toLedgerEntry");
|
|
@@ -1886,7 +2081,7 @@ var TypeOrmWalletStoreTx = (_a2 = class {
|
|
|
1886
2081
|
where: {
|
|
1887
2082
|
id: hold.id
|
|
1888
2083
|
}
|
|
1889
|
-
});
|
|
2084
|
+
}) ?? void 0;
|
|
1890
2085
|
}
|
|
1891
2086
|
if (!row) {
|
|
1892
2087
|
row = await repo.findOne({
|
|
@@ -1894,7 +2089,7 @@ var TypeOrmWalletStoreTx = (_a2 = class {
|
|
|
1894
2089
|
referenceType: hold.referenceType,
|
|
1895
2090
|
referenceId: hold.referenceId
|
|
1896
2091
|
}
|
|
1897
|
-
});
|
|
2092
|
+
}) ?? void 0;
|
|
1898
2093
|
}
|
|
1899
2094
|
if (!row) {
|
|
1900
2095
|
row = repo.create({
|
|
@@ -1924,6 +2119,36 @@ var TypeOrmWalletStoreTx = (_a2 = class {
|
|
|
1924
2119
|
});
|
|
1925
2120
|
return row ? toLedgerEntry(row) : null;
|
|
1926
2121
|
}
|
|
2122
|
+
async findOrderCustomerCheckoutDebit(accountId, orderId) {
|
|
2123
|
+
const canonical = orderCustomerDebitIdempotencyKey(orderId);
|
|
2124
|
+
const row = await this.em.getRepository(WalletLedgerEntryEntity).createQueryBuilder("e").where("e.account_id = :accountId", {
|
|
2125
|
+
accountId
|
|
2126
|
+
}).andWhere("e.entry_type = :entryType", {
|
|
2127
|
+
entryType: "debit"
|
|
2128
|
+
}).andWhere("e.reference_type = :referenceType", {
|
|
2129
|
+
referenceType: "order"
|
|
2130
|
+
}).andWhere("e.reference_id = :orderId", {
|
|
2131
|
+
orderId
|
|
2132
|
+
}).andWhere(new Brackets((qb) => {
|
|
2133
|
+
qb.where(`JSON_UNQUOTE(JSON_EXTRACT(e.metadata, '$.purpose')) = :purpose`, {
|
|
2134
|
+
purpose: CUSTOMER_CHECKOUT_DEBIT_PURPOSE
|
|
2135
|
+
}).orWhere("e.idempotency_key = :canonical", {
|
|
2136
|
+
canonical
|
|
2137
|
+
}).orWhere("e.idempotency_key LIKE :fullPrefix", {
|
|
2138
|
+
fullPrefix: "wallet:full:%"
|
|
2139
|
+
}).orWhere("e.idempotency_key LIKE :splitPrefix", {
|
|
2140
|
+
splitPrefix: "wallet:split:%"
|
|
2141
|
+
}).orWhere("e.idempotency_key LIKE :paymentPrefix", {
|
|
2142
|
+
paymentPrefix: "wallet:payment:%"
|
|
2143
|
+
});
|
|
2144
|
+
})).orderBy(`CASE
|
|
2145
|
+
WHEN JSON_UNQUOTE(JSON_EXTRACT(e.metadata, '$.purpose')) = :purpose THEN 0
|
|
2146
|
+
WHEN e.idempotency_key = :canonical THEN 1
|
|
2147
|
+
WHEN e.idempotency_key LIKE 'wallet:full:%' OR e.idempotency_key LIKE 'wallet:split:%' THEN 2
|
|
2148
|
+
ELSE 3
|
|
2149
|
+
END`, "ASC").addOrderBy("e.id", "ASC").setParameter("purpose", CUSTOMER_CHECKOUT_DEBIT_PURPOSE).setParameter("canonical", canonical).getOne();
|
|
2150
|
+
return row ? toLedgerEntry(row) : null;
|
|
2151
|
+
}
|
|
1927
2152
|
async listLedgerEntries(accountId, limit, offset) {
|
|
1928
2153
|
const rows = await this.em.getRepository(WalletLedgerEntryEntity).find({
|
|
1929
2154
|
where: {
|
|
@@ -2060,6 +2285,84 @@ var _CreateWalletTables1790000000000 = class _CreateWalletTables1790000000000 {
|
|
|
2060
2285
|
__name(_CreateWalletTables1790000000000, "CreateWalletTables1790000000000");
|
|
2061
2286
|
var CreateWalletTables1790000000000 = _CreateWalletTables1790000000000;
|
|
2062
2287
|
|
|
2288
|
+
// src/typeorm/migrations/AddOrderCustomerDebitUnique.ts
|
|
2289
|
+
var _AddOrderCustomerDebitUnique1790000001000 = class _AddOrderCustomerDebitUnique1790000001000 {
|
|
2290
|
+
async up(queryRunner) {
|
|
2291
|
+
const opsTables = await queryRunner.query(`SELECT COUNT(*) AS c
|
|
2292
|
+
FROM information_schema.tables
|
|
2293
|
+
WHERE table_schema = DATABASE()
|
|
2294
|
+
AND table_name = ?`, [
|
|
2295
|
+
WALLET_OPS_TABLE
|
|
2296
|
+
]);
|
|
2297
|
+
if (Number(opsTables[0]?.c ?? 0) === 0) {
|
|
2298
|
+
throw new Error(`Wallet unique-index gate: ${WALLET_OPS_TABLE} is missing. Run npm run wallet:credit-duplicate-order-debits`);
|
|
2299
|
+
}
|
|
2300
|
+
const sentinel = await queryRunner.query(`SELECT status FROM \`${WALLET_OPS_TABLE}\` WHERE ops_key = ? LIMIT 1`, [
|
|
2301
|
+
BACKFILL_SENTINEL_KEY
|
|
2302
|
+
]);
|
|
2303
|
+
if (!sentinel[0] || sentinel[0].status !== "complete") {
|
|
2304
|
+
throw new Error(`Wallet unique-index gate: sentinel ${BACKFILL_SENTINEL_KEY} is missing. Run npm run wallet:credit-duplicate-order-debits`);
|
|
2305
|
+
}
|
|
2306
|
+
const twins = await queryRunner.query(UNREIMBURSED_TWIN_COUNT_SQL);
|
|
2307
|
+
const twinCount = Number(twins[0]?.c ?? 0);
|
|
2308
|
+
if (twinCount > 0) {
|
|
2309
|
+
throw new Error(`Wallet unique-index gate: unreimbursed twin COUNT is ${twinCount}. Run npm run wallet:credit-duplicate-order-debits`);
|
|
2310
|
+
}
|
|
2311
|
+
const columns = await queryRunner.query(`SELECT COUNT(*) AS c
|
|
2312
|
+
FROM information_schema.columns
|
|
2313
|
+
WHERE table_schema = DATABASE()
|
|
2314
|
+
AND table_name = 'wallet_ledger_entry'
|
|
2315
|
+
AND column_name = 'order_customer_debit_key'`);
|
|
2316
|
+
if (Number(columns[0]?.c ?? 0) === 0) {
|
|
2317
|
+
await queryRunner.query(`
|
|
2318
|
+
ALTER TABLE \`wallet_ledger_entry\`
|
|
2319
|
+
ADD COLUMN \`order_customer_debit_key\` VARCHAR(191)
|
|
2320
|
+
GENERATED ALWAYS AS (
|
|
2321
|
+
CASE
|
|
2322
|
+
WHEN \`entry_type\` = 'debit'
|
|
2323
|
+
AND \`reference_type\` = 'order'
|
|
2324
|
+
AND \`reference_id\` IS NOT NULL
|
|
2325
|
+
AND JSON_UNQUOTE(JSON_EXTRACT(\`metadata\`, '$.purpose')) = 'customer_checkout_debit'
|
|
2326
|
+
THEN CONCAT(\`account_id\`, ':', \`reference_id\`)
|
|
2327
|
+
ELSE NULL
|
|
2328
|
+
END
|
|
2329
|
+
) STORED
|
|
2330
|
+
`);
|
|
2331
|
+
}
|
|
2332
|
+
const indexes = await queryRunner.query(`SELECT COUNT(*) AS c
|
|
2333
|
+
FROM information_schema.statistics
|
|
2334
|
+
WHERE table_schema = DATABASE()
|
|
2335
|
+
AND table_name = 'wallet_ledger_entry'
|
|
2336
|
+
AND index_name = 'UQ_wallet_order_customer_debit'`);
|
|
2337
|
+
if (Number(indexes[0]?.c ?? 0) === 0) {
|
|
2338
|
+
await queryRunner.query(`
|
|
2339
|
+
CREATE UNIQUE INDEX \`UQ_wallet_order_customer_debit\`
|
|
2340
|
+
ON \`wallet_ledger_entry\` (\`order_customer_debit_key\`)
|
|
2341
|
+
`);
|
|
2342
|
+
}
|
|
2343
|
+
}
|
|
2344
|
+
async down(queryRunner) {
|
|
2345
|
+
const indexes = await queryRunner.query(`SELECT COUNT(*) AS c
|
|
2346
|
+
FROM information_schema.statistics
|
|
2347
|
+
WHERE table_schema = DATABASE()
|
|
2348
|
+
AND table_name = 'wallet_ledger_entry'
|
|
2349
|
+
AND index_name = 'UQ_wallet_order_customer_debit'`);
|
|
2350
|
+
if (Number(indexes[0]?.c ?? 0) > 0) {
|
|
2351
|
+
await queryRunner.query(`DROP INDEX \`UQ_wallet_order_customer_debit\` ON \`wallet_ledger_entry\``);
|
|
2352
|
+
}
|
|
2353
|
+
const columns = await queryRunner.query(`SELECT COUNT(*) AS c
|
|
2354
|
+
FROM information_schema.columns
|
|
2355
|
+
WHERE table_schema = DATABASE()
|
|
2356
|
+
AND table_name = 'wallet_ledger_entry'
|
|
2357
|
+
AND column_name = 'order_customer_debit_key'`);
|
|
2358
|
+
if (Number(columns[0]?.c ?? 0) > 0) {
|
|
2359
|
+
await queryRunner.query(`ALTER TABLE \`wallet_ledger_entry\` DROP COLUMN \`order_customer_debit_key\``);
|
|
2360
|
+
}
|
|
2361
|
+
}
|
|
2362
|
+
};
|
|
2363
|
+
__name(_AddOrderCustomerDebitUnique1790000001000, "AddOrderCustomerDebitUnique1790000001000");
|
|
2364
|
+
var AddOrderCustomerDebitUnique1790000001000 = _AddOrderCustomerDebitUnique1790000001000;
|
|
2365
|
+
|
|
2063
2366
|
// src/typeorm/metadata.ts
|
|
2064
2367
|
function getWalletOrmMetadata() {
|
|
2065
2368
|
return {
|
|
@@ -2069,7 +2372,8 @@ function getWalletOrmMetadata() {
|
|
|
2069
2372
|
WalletHoldEntity
|
|
2070
2373
|
],
|
|
2071
2374
|
migrations: [
|
|
2072
|
-
CreateWalletTables1790000000000
|
|
2375
|
+
CreateWalletTables1790000000000,
|
|
2376
|
+
AddOrderCustomerDebitUnique1790000001000
|
|
2073
2377
|
]
|
|
2074
2378
|
};
|
|
2075
2379
|
}
|
|
@@ -2116,7 +2420,8 @@ var WalletPluginImpl = (_a3 = class {
|
|
|
2116
2420
|
this.resolveOrderCustomerId = config.resolveOrderCustomerId;
|
|
2117
2421
|
this.client = new WalletLedgerClient(store, {
|
|
2118
2422
|
defaultCurrency: config.defaultCurrency ?? "INR",
|
|
2119
|
-
platformOwnerId: config.platformOwnerId
|
|
2423
|
+
platformOwnerId: config.platformOwnerId,
|
|
2424
|
+
onDuplicateOrderDebit: config.onDuplicateOrderDebit
|
|
2120
2425
|
});
|
|
2121
2426
|
this.hooks = createLifecycleHooks({
|
|
2122
2427
|
client: this.client,
|
|
@@ -2168,6 +2473,6 @@ function registerWalletPlugin(config) {
|
|
|
2168
2473
|
}
|
|
2169
2474
|
__name(registerWalletPlugin, "registerWalletPlugin");
|
|
2170
2475
|
|
|
2171
|
-
export { AdminWalletController, CreateWalletTables1790000000000, CustomerWalletController, DuplicateOperationError, HoldNotFoundError, HoldStatus, InsufficientBalanceError, InvalidAmountError, LedgerEntryType, PaymentProviderWallet, TypeOrmWalletStore, VendorWalletController, WALLET_PLUGIN_TOKEN, WalletAccountEntity, WalletAccountType, WalletConfigError, WalletError, WalletHoldEntity, WalletLedgerClient, WalletLedgerEntryEntity, createExpressWalletRouter, createWalletPaymentAdapter, fromMinorUnit, getWalletOrmMetadata, registerWalletPlugin, toMinorUnit };
|
|
2476
|
+
export { AddOrderCustomerDebitUnique1790000001000, AdminWalletController, BACKFILL_SENTINEL_KEY, CUSTOMER_CHECKOUT_DEBIT_PURPOSE, CUSTOMER_CHECKOUT_DEBIT_REVERSAL_PURPOSE, CreateWalletTables1790000000000, CustomerWalletController, DuplicateOperationError, HoldNotFoundError, HoldStatus, InsufficientBalanceError, InvalidAmountError, LEGACY_ORDER_DEBIT_SUNSET_SQL, LedgerEntryType, PaymentProviderWallet, TypeOrmWalletStore, UNREIMBURSED_TWIN_COUNT_SQL, UNREIMBURSED_TWIN_DETAIL_SQL, VendorWalletController, WALLET_OPS_TABLE, WALLET_PLUGIN_TOKEN, WalletAccountEntity, WalletAccountType, WalletConfigError, WalletError, WalletHoldEntity, WalletLedgerClient, WalletLedgerEntryEntity, createExpressWalletRouter, createWalletPaymentAdapter, fromMinorUnit, getWalletOrmMetadata, isCustomerCheckoutDebit, isLegacyCustomerCheckoutDebitKey, nowTimestamp, orderCustomerDebitIdempotencyKey, parseLedgerDate, paymentNumberFromWalletPaymentKey, paymentReversalIdempotencyKey, registerWalletPlugin, toMinorUnit };
|
|
2172
2477
|
//# sourceMappingURL=index.js.map
|
|
2173
2478
|
//# sourceMappingURL=index.js.map
|