@develit-services/bank 0.8.7 → 0.8.9
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/dist/database/schema.cjs +1 -1
- package/dist/database/schema.d.cts +1 -1
- package/dist/database/schema.d.mts +1 -1
- package/dist/database/schema.d.ts +1 -1
- package/dist/database/schema.mjs +1 -1
- package/dist/export/worker.cjs +237 -277
- package/dist/export/worker.d.cts +25 -20
- package/dist/export/worker.d.mts +25 -20
- package/dist/export/worker.d.ts +25 -20
- package/dist/export/worker.mjs +238 -278
- package/dist/export/workflows.cjs +58 -96
- package/dist/export/workflows.mjs +59 -97
- package/dist/export/wrangler.d.cts +2 -1
- package/dist/export/wrangler.d.mts +2 -1
- package/dist/export/wrangler.d.ts +2 -1
- package/dist/shared/{bank.DEmzZGZW.mjs → bank.B5bZRvgq.mjs} +2 -5
- package/dist/shared/{bank.CQBfbG8u.d.cts → bank.BP_3WMIF.d.cts} +1 -0
- package/dist/shared/{bank.CQBfbG8u.d.mts → bank.BP_3WMIF.d.mts} +1 -0
- package/dist/shared/{bank.CQBfbG8u.d.ts → bank.BP_3WMIF.d.ts} +1 -0
- package/dist/shared/{bank.CA5ytXxp.mjs → bank.BoZtXQpG.mjs} +1 -1
- package/dist/shared/{bank.D1jqaHaF.mjs → bank.BtszLapg.mjs} +128 -20
- package/dist/shared/{bank.C0UN6luZ.mjs → bank.C6jjS1Pl.mjs} +0 -2
- package/dist/shared/{bank.BYRq3yJf.d.ts → bank.CHQ3VSEh.d.ts} +1 -1
- package/dist/shared/{bank.DwyCCyd0.cjs → bank.CtnsGHM8.cjs} +128 -20
- package/dist/shared/{bank.CO89tR9U.d.cts → bank.CwuH4spB.d.mts} +1 -1
- package/dist/shared/{bank.62VzK9Aj.cjs → bank.DJnDSYqE.cjs} +1 -1
- package/dist/shared/{bank.Dm8GHThw.cjs → bank.DT6bg8k5.cjs} +2 -5
- package/dist/shared/{bank.BS7fFjGA.cjs → bank.JVlyPAAb.cjs} +0 -2
- package/dist/shared/{bank.Cns5ss41.d.cts → bank.pgyk4j94.d.cts} +12 -25
- package/dist/shared/{bank.Cns5ss41.d.mts → bank.pgyk4j94.d.mts} +12 -25
- package/dist/shared/{bank.Cns5ss41.d.ts → bank.pgyk4j94.d.ts} +12 -25
- package/dist/shared/{bank.CreoSb2d.d.mts → bank.vPWD7Ce4.d.cts} +1 -1
- package/dist/types.cjs +3 -3
- package/dist/types.d.cts +10 -6
- package/dist/types.d.mts +10 -6
- package/dist/types.d.ts +10 -6
- package/dist/types.mjs +3 -3
- package/package.json +1 -1
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const backendSdk = require('@develit-io/backend-sdk');
|
|
4
|
-
const drizzle = require('../shared/bank.
|
|
4
|
+
const drizzle = require('../shared/bank.DT6bg8k5.cjs');
|
|
5
5
|
const batchLifecycle = require('../shared/bank.Bg3Pdwm4.cjs');
|
|
6
|
-
const mock_connector = require('../shared/bank.
|
|
6
|
+
const mock_connector = require('../shared/bank.CtnsGHM8.cjs');
|
|
7
7
|
const drizzleOrm = require('drizzle-orm');
|
|
8
|
-
require('drizzle-orm/sqlite-core');
|
|
9
8
|
const cloudflare_workers = require('cloudflare:workers');
|
|
10
9
|
const cloudflare_workflows = require('cloudflare:workflows');
|
|
11
10
|
const d1 = require('drizzle-orm/d1');
|
|
12
11
|
require('node:crypto');
|
|
13
|
-
require('../shared/bank.
|
|
12
|
+
require('../shared/bank.JVlyPAAb.cjs');
|
|
14
13
|
require('drizzle-orm/relations');
|
|
14
|
+
require('drizzle-orm/sqlite-core');
|
|
15
15
|
require('date-fns');
|
|
16
16
|
require('jose');
|
|
17
17
|
require('@develit-io/general-codes');
|
|
18
18
|
require('drizzle-zod');
|
|
19
|
-
require('../shared/bank.
|
|
19
|
+
require('../shared/bank.DJnDSYqE.cjs');
|
|
20
20
|
|
|
21
21
|
const updateAccountLastSyncCommand = (db, {
|
|
22
22
|
lastSyncAt,
|
|
@@ -41,6 +41,23 @@ function pushToQueue$1(queue, message) {
|
|
|
41
41
|
}))
|
|
42
42
|
);
|
|
43
43
|
}
|
|
44
|
+
async function failBatchAndPayments(db, batch, paymentRequests, reason) {
|
|
45
|
+
const prCmds = paymentRequests.filter((p) => p.status !== "FAILED").map(
|
|
46
|
+
(p) => drizzle.updatePaymentRequestStatusCommand(db, {
|
|
47
|
+
id: p.id,
|
|
48
|
+
status: "FAILED",
|
|
49
|
+
statusReason: reason,
|
|
50
|
+
processedAt: /* @__PURE__ */ new Date()
|
|
51
|
+
}).command
|
|
52
|
+
);
|
|
53
|
+
const batchCmd = drizzle.upsertBatchCommand(db, {
|
|
54
|
+
batch: { ...batch, status: "FAILED" }
|
|
55
|
+
}).command;
|
|
56
|
+
const allCmds = [batchCmd, ...prCmds];
|
|
57
|
+
if (allCmds.length > 0) {
|
|
58
|
+
await db.batch(allCmds);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
44
61
|
class BankProcessBatch extends cloudflare_workers.WorkflowEntrypoint {
|
|
45
62
|
async run(event, step) {
|
|
46
63
|
const { batchId } = event.payload;
|
|
@@ -110,7 +127,9 @@ class BankProcessBatch extends cloudflare_workers.WorkflowEntrypoint {
|
|
|
110
127
|
accountId: batch.accountId
|
|
111
128
|
});
|
|
112
129
|
if (!account) {
|
|
113
|
-
|
|
130
|
+
const msg = `Account not found: ${batch.accountId}`;
|
|
131
|
+
await failBatchAndPayments(db, batch, paymentRequests, msg);
|
|
132
|
+
throw new cloudflare_workflows.NonRetryableError(msg);
|
|
114
133
|
}
|
|
115
134
|
const resolveCredentials = await drizzle.createCredentialsResolver(db, this.env);
|
|
116
135
|
const connector = await mock_connector.initiateConnector({
|
|
@@ -143,17 +162,7 @@ class BankProcessBatch extends cloudflare_workers.WorkflowEntrypoint {
|
|
|
143
162
|
const message = err instanceof Error ? err.message : typeof err === "object" && err !== null && "message" in err ? String(err.message) : String(err);
|
|
144
163
|
const status = typeof err === "object" && err !== null && "status" in err ? Number(err.status) : 0;
|
|
145
164
|
if (status >= 400 && status < 500) {
|
|
146
|
-
|
|
147
|
-
(p) => drizzle.updatePaymentRequestStatusCommand(db, {
|
|
148
|
-
id: p.id,
|
|
149
|
-
status: "FAILED",
|
|
150
|
-
statusReason: message,
|
|
151
|
-
processedAt: /* @__PURE__ */ new Date()
|
|
152
|
-
}).command
|
|
153
|
-
);
|
|
154
|
-
if (updateCommands.length > 0) {
|
|
155
|
-
await db.batch(updateCommands);
|
|
156
|
-
}
|
|
165
|
+
await failBatchAndPayments(db, batch, paymentRequests, message);
|
|
157
166
|
throw new cloudflare_workflows.NonRetryableError(message);
|
|
158
167
|
}
|
|
159
168
|
throw new Error(message);
|
|
@@ -164,7 +173,9 @@ class BankProcessBatch extends cloudflare_workers.WorkflowEntrypoint {
|
|
|
164
173
|
metadata
|
|
165
174
|
} = result;
|
|
166
175
|
if (!authorizationUrls || authorizationUrls.length === 0) {
|
|
167
|
-
|
|
176
|
+
const msg = "Failed to retrieve authorization URLs";
|
|
177
|
+
await failBatchAndPayments(db, batch, paymentRequests, msg);
|
|
178
|
+
throw new cloudflare_workflows.NonRetryableError(msg);
|
|
168
179
|
}
|
|
169
180
|
return {
|
|
170
181
|
authorizationUrls,
|
|
@@ -217,14 +228,13 @@ class BankProcessBatch extends cloudflare_workers.WorkflowEntrypoint {
|
|
|
217
228
|
id: p.id,
|
|
218
229
|
status: "COMPLETED",
|
|
219
230
|
bankRefId: `MOCK-${backendSdk.uuidv4()}`,
|
|
220
|
-
processedAt
|
|
221
|
-
deletedAt: /* @__PURE__ */ new Date()
|
|
231
|
+
processedAt
|
|
222
232
|
}).command
|
|
223
233
|
);
|
|
224
234
|
const updateBatchCommand = drizzle.upsertBatchCommand(db, {
|
|
225
235
|
batch: {
|
|
226
236
|
...batch,
|
|
227
|
-
status: "
|
|
237
|
+
status: "COMPLETED",
|
|
228
238
|
authorizationUrls: batchResult.authorizationUrls,
|
|
229
239
|
metadata: batchResult.metadata,
|
|
230
240
|
batchPaymentInitiatedAt: /* @__PURE__ */ new Date()
|
|
@@ -347,84 +357,57 @@ class BankSyncAccountPayments extends cloudflare_workers.WorkflowEntrypoint {
|
|
|
347
357
|
"process new payments and update lastSyncAt",
|
|
348
358
|
async () => {
|
|
349
359
|
const eventsToEmit = [];
|
|
350
|
-
const
|
|
351
|
-
const
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
drizzleOrm.
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
drizzleOrm.eq(
|
|
359
|
-
drizzle.tables.paymentRequest.connectorKey,
|
|
360
|
-
account.connectorKey
|
|
361
|
-
),
|
|
362
|
-
drizzleOrm.isNull(drizzle.tables.paymentRequest.deletedAt)
|
|
360
|
+
const bankRefIds = paymentsToInsert.map((p) => p.parsed.bankRefId).filter((id) => id != null);
|
|
361
|
+
const matchingRequests = bankRefIds.length > 0 ? await db.select().from(drizzle.tables.paymentRequest).where(
|
|
362
|
+
drizzleOrm.and(
|
|
363
|
+
drizzleOrm.inArray(drizzle.tables.paymentRequest.bankRefId, bankRefIds),
|
|
364
|
+
drizzleOrm.eq(drizzle.tables.paymentRequest.accountId, account.id),
|
|
365
|
+
drizzleOrm.eq(
|
|
366
|
+
drizzle.tables.paymentRequest.connectorKey,
|
|
367
|
+
account.connectorKey
|
|
363
368
|
)
|
|
364
|
-
)
|
|
365
|
-
]
|
|
366
|
-
const requestById = Object.fromEntries(
|
|
367
|
-
matchingByPrId.map((r) => [r.id, r])
|
|
368
|
-
);
|
|
369
|
+
)
|
|
370
|
+
) : [];
|
|
369
371
|
const requestByBankRefId = Object.fromEntries(
|
|
370
|
-
|
|
372
|
+
matchingRequests.map((r) => [r.bankRefId, r])
|
|
371
373
|
);
|
|
372
374
|
const enrichedPayments = paymentsToInsert.map((p) => {
|
|
373
|
-
const req = p.parsed.
|
|
375
|
+
const req = p.parsed.bankRefId && requestByBankRefId[p.parsed.bankRefId] || null;
|
|
374
376
|
if (!req) return p;
|
|
375
377
|
return {
|
|
376
378
|
...p,
|
|
377
379
|
parsed: {
|
|
378
380
|
...p.parsed,
|
|
379
|
-
//
|
|
380
|
-
paymentRequestId: p.parsed.paymentRequestId ?? req.id,
|
|
381
|
-
createdAt: req.createdAt ?? p.parsed.createdAt,
|
|
382
|
-
batchId: p.parsed.batchId ?? req.batchId,
|
|
383
|
-
refId: p.parsed.refId ?? req.refId,
|
|
384
|
-
chargeBearer: p.parsed.chargeBearer ?? req.chargeBearer,
|
|
385
|
-
instructionPriority: p.parsed.instructionPriority ?? req.instructionPriority,
|
|
386
|
-
message: p.parsed.message ?? req.message,
|
|
381
|
+
// queue-bus: transaction matching (DBU doesn't echo these in statements)
|
|
387
382
|
vs: p.parsed.vs ?? req.vs,
|
|
388
383
|
ss: p.parsed.ss ?? req.ss,
|
|
389
384
|
ks: p.parsed.ks ?? req.ks,
|
|
385
|
+
message: p.parsed.message ?? req.message,
|
|
386
|
+
// queue-bus: party creation
|
|
390
387
|
creditor: {
|
|
391
388
|
...p.parsed.creditor,
|
|
392
|
-
holderName: p.parsed.creditor?.holderName ?? req.creditor?.holderName
|
|
393
|
-
address: p.parsed.creditor?.address ?? req.creditor?.address,
|
|
394
|
-
swiftBic: p.parsed.creditor?.swiftBic ?? req.creditor?.swiftBic
|
|
389
|
+
holderName: p.parsed.creditor?.holderName ?? req.creditor?.holderName
|
|
395
390
|
},
|
|
396
391
|
debtor: {
|
|
397
392
|
...p.parsed.debtor,
|
|
398
393
|
holderName: p.parsed.debtor?.holderName ?? req.debtor?.holderName
|
|
399
394
|
}
|
|
395
|
+
// NOT enriched: chargeBearer, instructionPriority, refId, batchId,
|
|
396
|
+
// createdAt, address, swiftBic — no downstream consumer in payment table
|
|
400
397
|
}
|
|
401
398
|
};
|
|
402
399
|
});
|
|
403
400
|
const createCommands = enrichedPayments.map(
|
|
404
401
|
(p) => drizzle.createPaymentCommand(db, { payment: p.parsed }).command
|
|
405
402
|
);
|
|
406
|
-
const
|
|
407
|
-
(
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
p.parsed.paymentRequestId ? drizzleOrm.eq(drizzle.tables.paymentRequest.id, p.parsed.paymentRequestId) : void 0,
|
|
415
|
-
// Fallback: match via bankRefId (set during processBatch)
|
|
416
|
-
drizzleOrm.and(
|
|
417
|
-
drizzleOrm.isNotNull(drizzle.tables.paymentRequest.bankRefId),
|
|
418
|
-
drizzleOrm.eq(drizzle.tables.paymentRequest.bankRefId, p.parsed.bankRefId),
|
|
419
|
-
drizzleOrm.eq(drizzle.tables.paymentRequest.accountId, account.id),
|
|
420
|
-
drizzleOrm.eq(
|
|
421
|
-
drizzle.tables.paymentRequest.connectorKey,
|
|
422
|
-
account.connectorKey
|
|
423
|
-
),
|
|
424
|
-
drizzleOrm.isNull(drizzle.tables.paymentRequest.deletedAt)
|
|
425
|
-
)
|
|
426
|
-
)
|
|
427
|
-
)
|
|
403
|
+
const prCompleteCommands = matchingRequests.filter(
|
|
404
|
+
(req) => req.status !== "COMPLETED" && req.status !== "FAILED"
|
|
405
|
+
).map(
|
|
406
|
+
(req) => drizzle.updatePaymentRequestStatusCommand(db, {
|
|
407
|
+
id: req.id,
|
|
408
|
+
status: "COMPLETED",
|
|
409
|
+
processedAt: /* @__PURE__ */ new Date()
|
|
410
|
+
}).command
|
|
428
411
|
);
|
|
429
412
|
eventsToEmit.push(
|
|
430
413
|
...enrichedPayments.map((p) => ({
|
|
@@ -456,7 +439,7 @@ class BankSyncAccountPayments extends cloudflare_workers.WorkflowEntrypoint {
|
|
|
456
439
|
backendSdk.asNonEmpty([
|
|
457
440
|
updateLastSyncCommand,
|
|
458
441
|
...createCommands,
|
|
459
|
-
...
|
|
442
|
+
...prCompleteCommands
|
|
460
443
|
])
|
|
461
444
|
);
|
|
462
445
|
await pushToQueue(
|
|
@@ -464,27 +447,6 @@ class BankSyncAccountPayments extends cloudflare_workers.WorkflowEntrypoint {
|
|
|
464
447
|
eventsToEmit
|
|
465
448
|
);
|
|
466
449
|
}
|
|
467
|
-
const paymentRequestIds = enrichedPayments.map((p) => p.parsed.paymentRequestId).filter((id) => id != null);
|
|
468
|
-
if (paymentRequestIds.length > 0) {
|
|
469
|
-
const processedPRs = await db.select({ batchId: drizzle.tables.paymentRequest.batchId }).from(drizzle.tables.paymentRequest).where(drizzleOrm.inArray(drizzle.tables.paymentRequest.id, paymentRequestIds));
|
|
470
|
-
const batchIds = [
|
|
471
|
-
...new Set(
|
|
472
|
-
processedPRs.map((pr) => pr.batchId).filter((id) => id != null)
|
|
473
|
-
)
|
|
474
|
-
];
|
|
475
|
-
for (const batchId of batchIds) {
|
|
476
|
-
const allPRsInBatch = await db.select({ deletedAt: drizzle.tables.paymentRequest.deletedAt }).from(drizzle.tables.paymentRequest).where(drizzleOrm.eq(drizzle.tables.paymentRequest.batchId, batchId));
|
|
477
|
-
const allDone = allPRsInBatch.length > 0 && allPRsInBatch.every((pr) => pr.deletedAt != null);
|
|
478
|
-
if (allDone) {
|
|
479
|
-
const batch = await drizzle.getBatchByIdQuery(db, { batchId });
|
|
480
|
-
if (batch && batch.status !== "COMPLETED" && batch.status !== "FAILED") {
|
|
481
|
-
await drizzle.upsertBatchCommand(db, {
|
|
482
|
-
batch: { ...batch, status: "COMPLETED" }
|
|
483
|
-
}).command.execute();
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
450
|
return {
|
|
489
451
|
...lastSyncMetadata,
|
|
490
452
|
newLastSyncAt: now
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { first, uuidv4, asNonEmpty } from '@develit-io/backend-sdk';
|
|
2
|
-
import { t as tables, g as getBatchByIdQuery, a as getPaymentRequestsByBatchIdQuery, c as checksum, u as upsertBatchCommand, b as getAccountByIdQuery, d as createCredentialsResolver, e as updatePaymentRequestStatusCommand, f as createPaymentCommand } from '../shared/bank.
|
|
2
|
+
import { t as tables, g as getBatchByIdQuery, a as getPaymentRequestsByBatchIdQuery, c as checksum, u as upsertBatchCommand, b as getAccountByIdQuery, d as createCredentialsResolver, e as updatePaymentRequestStatusCommand, f as createPaymentCommand } from '../shared/bank.B5bZRvgq.mjs';
|
|
3
3
|
import { f as isBatchSigned, a as isBatchFailed, c as isBatchOpen, g as isPaymentCompleted } from '../shared/bank.CbAwwIhZ.mjs';
|
|
4
|
-
import { e as toBatchedPaymentFromPaymentRequest, i as toPreparedPayment, j as initiateConnector } from '../shared/bank.
|
|
5
|
-
import { eq,
|
|
6
|
-
import 'drizzle-orm/sqlite-core';
|
|
4
|
+
import { e as toBatchedPaymentFromPaymentRequest, i as toPreparedPayment, j as initiateConnector } from '../shared/bank.BtszLapg.mjs';
|
|
5
|
+
import { eq, and, inArray } from 'drizzle-orm';
|
|
7
6
|
import { WorkflowEntrypoint } from 'cloudflare:workers';
|
|
8
7
|
import { NonRetryableError } from 'cloudflare:workflows';
|
|
9
8
|
import { drizzle } from 'drizzle-orm/d1';
|
|
10
9
|
import 'node:crypto';
|
|
11
|
-
import '../shared/bank.
|
|
10
|
+
import '../shared/bank.C6jjS1Pl.mjs';
|
|
12
11
|
import 'drizzle-orm/relations';
|
|
12
|
+
import 'drizzle-orm/sqlite-core';
|
|
13
13
|
import 'date-fns';
|
|
14
14
|
import 'jose';
|
|
15
15
|
import '@develit-io/general-codes';
|
|
16
16
|
import 'drizzle-zod';
|
|
17
|
-
import '../shared/bank.
|
|
17
|
+
import '../shared/bank.BoZtXQpG.mjs';
|
|
18
18
|
|
|
19
19
|
const updateAccountLastSyncCommand = (db, {
|
|
20
20
|
lastSyncAt,
|
|
@@ -39,6 +39,23 @@ function pushToQueue$1(queue, message) {
|
|
|
39
39
|
}))
|
|
40
40
|
);
|
|
41
41
|
}
|
|
42
|
+
async function failBatchAndPayments(db, batch, paymentRequests, reason) {
|
|
43
|
+
const prCmds = paymentRequests.filter((p) => p.status !== "FAILED").map(
|
|
44
|
+
(p) => updatePaymentRequestStatusCommand(db, {
|
|
45
|
+
id: p.id,
|
|
46
|
+
status: "FAILED",
|
|
47
|
+
statusReason: reason,
|
|
48
|
+
processedAt: /* @__PURE__ */ new Date()
|
|
49
|
+
}).command
|
|
50
|
+
);
|
|
51
|
+
const batchCmd = upsertBatchCommand(db, {
|
|
52
|
+
batch: { ...batch, status: "FAILED" }
|
|
53
|
+
}).command;
|
|
54
|
+
const allCmds = [batchCmd, ...prCmds];
|
|
55
|
+
if (allCmds.length > 0) {
|
|
56
|
+
await db.batch(allCmds);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
42
59
|
class BankProcessBatch extends WorkflowEntrypoint {
|
|
43
60
|
async run(event, step) {
|
|
44
61
|
const { batchId } = event.payload;
|
|
@@ -108,7 +125,9 @@ class BankProcessBatch extends WorkflowEntrypoint {
|
|
|
108
125
|
accountId: batch.accountId
|
|
109
126
|
});
|
|
110
127
|
if (!account) {
|
|
111
|
-
|
|
128
|
+
const msg = `Account not found: ${batch.accountId}`;
|
|
129
|
+
await failBatchAndPayments(db, batch, paymentRequests, msg);
|
|
130
|
+
throw new NonRetryableError(msg);
|
|
112
131
|
}
|
|
113
132
|
const resolveCredentials = await createCredentialsResolver(db, this.env);
|
|
114
133
|
const connector = await initiateConnector({
|
|
@@ -141,17 +160,7 @@ class BankProcessBatch extends WorkflowEntrypoint {
|
|
|
141
160
|
const message = err instanceof Error ? err.message : typeof err === "object" && err !== null && "message" in err ? String(err.message) : String(err);
|
|
142
161
|
const status = typeof err === "object" && err !== null && "status" in err ? Number(err.status) : 0;
|
|
143
162
|
if (status >= 400 && status < 500) {
|
|
144
|
-
|
|
145
|
-
(p) => updatePaymentRequestStatusCommand(db, {
|
|
146
|
-
id: p.id,
|
|
147
|
-
status: "FAILED",
|
|
148
|
-
statusReason: message,
|
|
149
|
-
processedAt: /* @__PURE__ */ new Date()
|
|
150
|
-
}).command
|
|
151
|
-
);
|
|
152
|
-
if (updateCommands.length > 0) {
|
|
153
|
-
await db.batch(updateCommands);
|
|
154
|
-
}
|
|
163
|
+
await failBatchAndPayments(db, batch, paymentRequests, message);
|
|
155
164
|
throw new NonRetryableError(message);
|
|
156
165
|
}
|
|
157
166
|
throw new Error(message);
|
|
@@ -162,7 +171,9 @@ class BankProcessBatch extends WorkflowEntrypoint {
|
|
|
162
171
|
metadata
|
|
163
172
|
} = result;
|
|
164
173
|
if (!authorizationUrls || authorizationUrls.length === 0) {
|
|
165
|
-
|
|
174
|
+
const msg = "Failed to retrieve authorization URLs";
|
|
175
|
+
await failBatchAndPayments(db, batch, paymentRequests, msg);
|
|
176
|
+
throw new NonRetryableError(msg);
|
|
166
177
|
}
|
|
167
178
|
return {
|
|
168
179
|
authorizationUrls,
|
|
@@ -215,14 +226,13 @@ class BankProcessBatch extends WorkflowEntrypoint {
|
|
|
215
226
|
id: p.id,
|
|
216
227
|
status: "COMPLETED",
|
|
217
228
|
bankRefId: `MOCK-${uuidv4()}`,
|
|
218
|
-
processedAt
|
|
219
|
-
deletedAt: /* @__PURE__ */ new Date()
|
|
229
|
+
processedAt
|
|
220
230
|
}).command
|
|
221
231
|
);
|
|
222
232
|
const updateBatchCommand = upsertBatchCommand(db, {
|
|
223
233
|
batch: {
|
|
224
234
|
...batch,
|
|
225
|
-
status: "
|
|
235
|
+
status: "COMPLETED",
|
|
226
236
|
authorizationUrls: batchResult.authorizationUrls,
|
|
227
237
|
metadata: batchResult.metadata,
|
|
228
238
|
batchPaymentInitiatedAt: /* @__PURE__ */ new Date()
|
|
@@ -345,84 +355,57 @@ class BankSyncAccountPayments extends WorkflowEntrypoint {
|
|
|
345
355
|
"process new payments and update lastSyncAt",
|
|
346
356
|
async () => {
|
|
347
357
|
const eventsToEmit = [];
|
|
348
|
-
const
|
|
349
|
-
const
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
eq(
|
|
357
|
-
tables.paymentRequest.connectorKey,
|
|
358
|
-
account.connectorKey
|
|
359
|
-
),
|
|
360
|
-
isNull(tables.paymentRequest.deletedAt)
|
|
358
|
+
const bankRefIds = paymentsToInsert.map((p) => p.parsed.bankRefId).filter((id) => id != null);
|
|
359
|
+
const matchingRequests = bankRefIds.length > 0 ? await db.select().from(tables.paymentRequest).where(
|
|
360
|
+
and(
|
|
361
|
+
inArray(tables.paymentRequest.bankRefId, bankRefIds),
|
|
362
|
+
eq(tables.paymentRequest.accountId, account.id),
|
|
363
|
+
eq(
|
|
364
|
+
tables.paymentRequest.connectorKey,
|
|
365
|
+
account.connectorKey
|
|
361
366
|
)
|
|
362
|
-
)
|
|
363
|
-
]
|
|
364
|
-
const requestById = Object.fromEntries(
|
|
365
|
-
matchingByPrId.map((r) => [r.id, r])
|
|
366
|
-
);
|
|
367
|
+
)
|
|
368
|
+
) : [];
|
|
367
369
|
const requestByBankRefId = Object.fromEntries(
|
|
368
|
-
|
|
370
|
+
matchingRequests.map((r) => [r.bankRefId, r])
|
|
369
371
|
);
|
|
370
372
|
const enrichedPayments = paymentsToInsert.map((p) => {
|
|
371
|
-
const req = p.parsed.
|
|
373
|
+
const req = p.parsed.bankRefId && requestByBankRefId[p.parsed.bankRefId] || null;
|
|
372
374
|
if (!req) return p;
|
|
373
375
|
return {
|
|
374
376
|
...p,
|
|
375
377
|
parsed: {
|
|
376
378
|
...p.parsed,
|
|
377
|
-
//
|
|
378
|
-
paymentRequestId: p.parsed.paymentRequestId ?? req.id,
|
|
379
|
-
createdAt: req.createdAt ?? p.parsed.createdAt,
|
|
380
|
-
batchId: p.parsed.batchId ?? req.batchId,
|
|
381
|
-
refId: p.parsed.refId ?? req.refId,
|
|
382
|
-
chargeBearer: p.parsed.chargeBearer ?? req.chargeBearer,
|
|
383
|
-
instructionPriority: p.parsed.instructionPriority ?? req.instructionPriority,
|
|
384
|
-
message: p.parsed.message ?? req.message,
|
|
379
|
+
// queue-bus: transaction matching (DBU doesn't echo these in statements)
|
|
385
380
|
vs: p.parsed.vs ?? req.vs,
|
|
386
381
|
ss: p.parsed.ss ?? req.ss,
|
|
387
382
|
ks: p.parsed.ks ?? req.ks,
|
|
383
|
+
message: p.parsed.message ?? req.message,
|
|
384
|
+
// queue-bus: party creation
|
|
388
385
|
creditor: {
|
|
389
386
|
...p.parsed.creditor,
|
|
390
|
-
holderName: p.parsed.creditor?.holderName ?? req.creditor?.holderName
|
|
391
|
-
address: p.parsed.creditor?.address ?? req.creditor?.address,
|
|
392
|
-
swiftBic: p.parsed.creditor?.swiftBic ?? req.creditor?.swiftBic
|
|
387
|
+
holderName: p.parsed.creditor?.holderName ?? req.creditor?.holderName
|
|
393
388
|
},
|
|
394
389
|
debtor: {
|
|
395
390
|
...p.parsed.debtor,
|
|
396
391
|
holderName: p.parsed.debtor?.holderName ?? req.debtor?.holderName
|
|
397
392
|
}
|
|
393
|
+
// NOT enriched: chargeBearer, instructionPriority, refId, batchId,
|
|
394
|
+
// createdAt, address, swiftBic — no downstream consumer in payment table
|
|
398
395
|
}
|
|
399
396
|
};
|
|
400
397
|
});
|
|
401
398
|
const createCommands = enrichedPayments.map(
|
|
402
399
|
(p) => createPaymentCommand(db, { payment: p.parsed }).command
|
|
403
400
|
);
|
|
404
|
-
const
|
|
405
|
-
(
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
p.parsed.paymentRequestId ? eq(tables.paymentRequest.id, p.parsed.paymentRequestId) : void 0,
|
|
413
|
-
// Fallback: match via bankRefId (set during processBatch)
|
|
414
|
-
and(
|
|
415
|
-
isNotNull(tables.paymentRequest.bankRefId),
|
|
416
|
-
eq(tables.paymentRequest.bankRefId, p.parsed.bankRefId),
|
|
417
|
-
eq(tables.paymentRequest.accountId, account.id),
|
|
418
|
-
eq(
|
|
419
|
-
tables.paymentRequest.connectorKey,
|
|
420
|
-
account.connectorKey
|
|
421
|
-
),
|
|
422
|
-
isNull(tables.paymentRequest.deletedAt)
|
|
423
|
-
)
|
|
424
|
-
)
|
|
425
|
-
)
|
|
401
|
+
const prCompleteCommands = matchingRequests.filter(
|
|
402
|
+
(req) => req.status !== "COMPLETED" && req.status !== "FAILED"
|
|
403
|
+
).map(
|
|
404
|
+
(req) => updatePaymentRequestStatusCommand(db, {
|
|
405
|
+
id: req.id,
|
|
406
|
+
status: "COMPLETED",
|
|
407
|
+
processedAt: /* @__PURE__ */ new Date()
|
|
408
|
+
}).command
|
|
426
409
|
);
|
|
427
410
|
eventsToEmit.push(
|
|
428
411
|
...enrichedPayments.map((p) => ({
|
|
@@ -454,7 +437,7 @@ class BankSyncAccountPayments extends WorkflowEntrypoint {
|
|
|
454
437
|
asNonEmpty([
|
|
455
438
|
updateLastSyncCommand,
|
|
456
439
|
...createCommands,
|
|
457
|
-
...
|
|
440
|
+
...prCompleteCommands
|
|
458
441
|
])
|
|
459
442
|
);
|
|
460
443
|
await pushToQueue(
|
|
@@ -462,27 +445,6 @@ class BankSyncAccountPayments extends WorkflowEntrypoint {
|
|
|
462
445
|
eventsToEmit
|
|
463
446
|
);
|
|
464
447
|
}
|
|
465
|
-
const paymentRequestIds = enrichedPayments.map((p) => p.parsed.paymentRequestId).filter((id) => id != null);
|
|
466
|
-
if (paymentRequestIds.length > 0) {
|
|
467
|
-
const processedPRs = await db.select({ batchId: tables.paymentRequest.batchId }).from(tables.paymentRequest).where(inArray(tables.paymentRequest.id, paymentRequestIds));
|
|
468
|
-
const batchIds = [
|
|
469
|
-
...new Set(
|
|
470
|
-
processedPRs.map((pr) => pr.batchId).filter((id) => id != null)
|
|
471
|
-
)
|
|
472
|
-
];
|
|
473
|
-
for (const batchId of batchIds) {
|
|
474
|
-
const allPRsInBatch = await db.select({ deletedAt: tables.paymentRequest.deletedAt }).from(tables.paymentRequest).where(eq(tables.paymentRequest.batchId, batchId));
|
|
475
|
-
const allDone = allPRsInBatch.length > 0 && allPRsInBatch.every((pr) => pr.deletedAt != null);
|
|
476
|
-
if (allDone) {
|
|
477
|
-
const batch = await getBatchByIdQuery(db, { batchId });
|
|
478
|
-
if (batch && batch.status !== "COMPLETED" && batch.status !== "FAILED") {
|
|
479
|
-
await upsertBatchCommand(db, {
|
|
480
|
-
batch: { ...batch, status: "COMPLETED" }
|
|
481
|
-
}).command.execute();
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
448
|
return {
|
|
487
449
|
...lastSyncMetadata,
|
|
488
450
|
newLastSyncAt: now
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as BankServiceWranglerConfig } from '../shared/bank.
|
|
1
|
+
import { B as BankServiceWranglerConfig } from '../shared/bank.BP_3WMIF.cjs';
|
|
2
2
|
|
|
3
3
|
declare function defineBankServiceWrangler(config: BankServiceWranglerConfig): {
|
|
4
4
|
vars: {
|
|
@@ -9,6 +9,7 @@ declare function defineBankServiceWrangler(config: BankServiceWranglerConfig): {
|
|
|
9
9
|
FINBRICKS_BASE_URI: "https://api.sandbox.finbricks.com";
|
|
10
10
|
FINBRICKS_MERCHANT_ID: string;
|
|
11
11
|
CRON_BATCH_STATUSES: string;
|
|
12
|
+
CRON_PAYMENT_STATUSES: string;
|
|
12
13
|
BANK_AUTH_RECIPIENT: string;
|
|
13
14
|
DBUCS_BASE_URI: string;
|
|
14
15
|
DBUCS_USERNAME: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as BankServiceWranglerConfig } from '../shared/bank.
|
|
1
|
+
import { B as BankServiceWranglerConfig } from '../shared/bank.BP_3WMIF.mjs';
|
|
2
2
|
|
|
3
3
|
declare function defineBankServiceWrangler(config: BankServiceWranglerConfig): {
|
|
4
4
|
vars: {
|
|
@@ -9,6 +9,7 @@ declare function defineBankServiceWrangler(config: BankServiceWranglerConfig): {
|
|
|
9
9
|
FINBRICKS_BASE_URI: "https://api.sandbox.finbricks.com";
|
|
10
10
|
FINBRICKS_MERCHANT_ID: string;
|
|
11
11
|
CRON_BATCH_STATUSES: string;
|
|
12
|
+
CRON_PAYMENT_STATUSES: string;
|
|
12
13
|
BANK_AUTH_RECIPIENT: string;
|
|
13
14
|
DBUCS_BASE_URI: string;
|
|
14
15
|
DBUCS_USERNAME: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as BankServiceWranglerConfig } from '../shared/bank.
|
|
1
|
+
import { B as BankServiceWranglerConfig } from '../shared/bank.BP_3WMIF.js';
|
|
2
2
|
|
|
3
3
|
declare function defineBankServiceWrangler(config: BankServiceWranglerConfig): {
|
|
4
4
|
vars: {
|
|
@@ -9,6 +9,7 @@ declare function defineBankServiceWrangler(config: BankServiceWranglerConfig): {
|
|
|
9
9
|
FINBRICKS_BASE_URI: "https://api.sandbox.finbricks.com";
|
|
10
10
|
FINBRICKS_MERCHANT_ID: string;
|
|
11
11
|
CRON_BATCH_STATUSES: string;
|
|
12
|
+
CRON_PAYMENT_STATUSES: string;
|
|
12
13
|
BANK_AUTH_RECIPIENT: string;
|
|
13
14
|
DBUCS_BASE_URI: string;
|
|
14
15
|
DBUCS_USERNAME: string;
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { sql, and, eq, isNull } from 'drizzle-orm';
|
|
2
2
|
import { uuidv4 } from '@develit-io/backend-sdk';
|
|
3
|
-
import './bank.
|
|
3
|
+
import './bank.C6jjS1Pl.mjs';
|
|
4
4
|
import 'date-fns';
|
|
5
5
|
import 'jose';
|
|
6
6
|
import '@develit-io/general-codes';
|
|
7
7
|
import { createHash } from 'node:crypto';
|
|
8
|
-
import { s as schema } from './bank.
|
|
9
|
-
import 'drizzle-orm/sqlite-core';
|
|
8
|
+
import { s as schema } from './bank.BoZtXQpG.mjs';
|
|
10
9
|
|
|
11
10
|
const createPaymentCommand = (db, { payment }) => {
|
|
12
11
|
return {
|
|
@@ -22,8 +21,6 @@ const createPaymentCommand = (db, { payment }) => {
|
|
|
22
21
|
statusReason: sql`excluded.status_reason`,
|
|
23
22
|
processedAt: sql`excluded.processed_at`,
|
|
24
23
|
updatedAt: sql`excluded.updated_at`,
|
|
25
|
-
// Keep existing paymentRequestId if already set, otherwise use new value
|
|
26
|
-
paymentRequestId: sql`coalesce(payment.payment_request_id, excluded.payment_request_id)`,
|
|
27
24
|
// Keep existing refId if already set, otherwise use enriched value
|
|
28
25
|
refId: sql`coalesce(payment.ref_id, excluded.ref_id)`,
|
|
29
26
|
// Keep existing batchId if already set, otherwise use enriched value
|
|
@@ -27,6 +27,7 @@ interface BankServiceEnvironmentConfig {
|
|
|
27
27
|
FINBRICKS_BASE_URI: 'https://api.sandbox.finbricks.com';
|
|
28
28
|
FINBRICKS_MERCHANT_ID: string;
|
|
29
29
|
CRON_BATCH_STATUSES: string;
|
|
30
|
+
CRON_PAYMENT_STATUSES: string;
|
|
30
31
|
BANK_AUTH_RECIPIENT: string;
|
|
31
32
|
DBUCS_BASE_URI: string;
|
|
32
33
|
DBUCS_USERNAME: string;
|
|
@@ -27,6 +27,7 @@ interface BankServiceEnvironmentConfig {
|
|
|
27
27
|
FINBRICKS_BASE_URI: 'https://api.sandbox.finbricks.com';
|
|
28
28
|
FINBRICKS_MERCHANT_ID: string;
|
|
29
29
|
CRON_BATCH_STATUSES: string;
|
|
30
|
+
CRON_PAYMENT_STATUSES: string;
|
|
30
31
|
BANK_AUTH_RECIPIENT: string;
|
|
31
32
|
DBUCS_BASE_URI: string;
|
|
32
33
|
DBUCS_USERNAME: string;
|
|
@@ -27,6 +27,7 @@ interface BankServiceEnvironmentConfig {
|
|
|
27
27
|
FINBRICKS_BASE_URI: 'https://api.sandbox.finbricks.com';
|
|
28
28
|
FINBRICKS_MERCHANT_ID: string;
|
|
29
29
|
CRON_BATCH_STATUSES: string;
|
|
30
|
+
CRON_PAYMENT_STATUSES: string;
|
|
30
31
|
BANK_AUTH_RECIPIENT: string;
|
|
31
32
|
DBUCS_BASE_URI: string;
|
|
32
33
|
DBUCS_USERNAME: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as account, p as accountCredentials, q as batch, r as ott, s as payment, t as paymentRelations, u as paymentRequest, v as paymentRequestRelations } from './bank.
|
|
1
|
+
import { n as account, p as accountCredentials, q as batch, r as ott, s as payment, t as paymentRelations, u as paymentRequest, v as paymentRequestRelations } from './bank.C6jjS1Pl.mjs';
|
|
2
2
|
|
|
3
3
|
const schema = {
|
|
4
4
|
__proto__: null,
|