@sakeetech/vendure-payment-viva 0.2.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.
Files changed (135) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +952 -0
  3. package/dist/api/admin-internal.controller.d.ts +59 -0
  4. package/dist/api/admin-internal.controller.d.ts.map +1 -0
  5. package/dist/api/admin-internal.controller.js +229 -0
  6. package/dist/api/admin-internal.controller.js.map +1 -0
  7. package/dist/api/admin-onboarding.controller.d.ts +72 -0
  8. package/dist/api/admin-onboarding.controller.d.ts.map +1 -0
  9. package/dist/api/admin-onboarding.controller.js +496 -0
  10. package/dist/api/admin-onboarding.controller.js.map +1 -0
  11. package/dist/api/admin-sources.controller.d.ts +50 -0
  12. package/dist/api/admin-sources.controller.d.ts.map +1 -0
  13. package/dist/api/admin-sources.controller.js +283 -0
  14. package/dist/api/admin-sources.controller.js.map +1 -0
  15. package/dist/api/shop-api.extension.d.ts +15 -0
  16. package/dist/api/shop-api.extension.d.ts.map +1 -0
  17. package/dist/api/shop-api.extension.js +35 -0
  18. package/dist/api/shop-api.extension.js.map +1 -0
  19. package/dist/api/shop-api.resolver.d.ts +42 -0
  20. package/dist/api/shop-api.resolver.d.ts.map +1 -0
  21. package/dist/api/shop-api.resolver.js +256 -0
  22. package/dist/api/shop-api.resolver.js.map +1 -0
  23. package/dist/api/webhook.controller.d.ts +58 -0
  24. package/dist/api/webhook.controller.d.ts.map +1 -0
  25. package/dist/api/webhook.controller.js +204 -0
  26. package/dist/api/webhook.controller.js.map +1 -0
  27. package/dist/cli/bin.d.ts +28 -0
  28. package/dist/cli/bin.d.ts.map +1 -0
  29. package/dist/cli/bin.js +104 -0
  30. package/dist/cli/bin.js.map +1 -0
  31. package/dist/cli/plan.d.ts +41 -0
  32. package/dist/cli/plan.d.ts.map +1 -0
  33. package/dist/cli/plan.js +115 -0
  34. package/dist/cli/plan.js.map +1 -0
  35. package/dist/cli/register-webhooks.d.ts +45 -0
  36. package/dist/cli/register-webhooks.d.ts.map +1 -0
  37. package/dist/cli/register-webhooks.js +400 -0
  38. package/dist/cli/register-webhooks.js.map +1 -0
  39. package/dist/cli/types.d.ts +75 -0
  40. package/dist/cli/types.d.ts.map +1 -0
  41. package/dist/cli/types.js +10 -0
  42. package/dist/cli/types.js.map +1 -0
  43. package/dist/constants.d.ts +35 -0
  44. package/dist/constants.d.ts.map +1 -0
  45. package/dist/constants.js +40 -0
  46. package/dist/constants.js.map +1 -0
  47. package/dist/entities/index.d.ts +4 -0
  48. package/dist/entities/index.d.ts.map +1 -0
  49. package/dist/entities/index.js +3 -0
  50. package/dist/entities/index.js.map +1 -0
  51. package/dist/entities/viva-transaction.entity.d.ts +70 -0
  52. package/dist/entities/viva-transaction.entity.d.ts.map +1 -0
  53. package/dist/entities/viva-transaction.entity.js +133 -0
  54. package/dist/entities/viva-transaction.entity.js.map +1 -0
  55. package/dist/entities/viva-webhook-event.entity.d.ts +71 -0
  56. package/dist/entities/viva-webhook-event.entity.d.ts.map +1 -0
  57. package/dist/entities/viva-webhook-event.entity.js +138 -0
  58. package/dist/entities/viva-webhook-event.entity.js.map +1 -0
  59. package/dist/index.d.ts +27 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +23 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/jobs/process-viva-webhook.handler.d.ts +95 -0
  64. package/dist/jobs/process-viva-webhook.handler.d.ts.map +1 -0
  65. package/dist/jobs/process-viva-webhook.handler.js +530 -0
  66. package/dist/jobs/process-viva-webhook.handler.js.map +1 -0
  67. package/dist/jobs/queue-names.d.ts +18 -0
  68. package/dist/jobs/queue-names.d.ts.map +1 -0
  69. package/dist/jobs/queue-names.js +19 -0
  70. package/dist/jobs/queue-names.js.map +1 -0
  71. package/dist/jobs/retention-cleanup.handler.d.ts +31 -0
  72. package/dist/jobs/retention-cleanup.handler.d.ts.map +1 -0
  73. package/dist/jobs/retention-cleanup.handler.js +94 -0
  74. package/dist/jobs/retention-cleanup.handler.js.map +1 -0
  75. package/dist/loaders/bootstrap.d.ts +28 -0
  76. package/dist/loaders/bootstrap.d.ts.map +1 -0
  77. package/dist/loaders/bootstrap.js +90 -0
  78. package/dist/loaders/bootstrap.js.map +1 -0
  79. package/dist/migrations/1714000000000-create-viva-tables.d.ts +22 -0
  80. package/dist/migrations/1714000000000-create-viva-tables.d.ts.map +1 -0
  81. package/dist/migrations/1714000000000-create-viva-tables.js +105 -0
  82. package/dist/migrations/1714000000000-create-viva-tables.js.map +1 -0
  83. package/dist/observability/metrics-state.service.d.ts +43 -0
  84. package/dist/observability/metrics-state.service.d.ts.map +1 -0
  85. package/dist/observability/metrics-state.service.js +207 -0
  86. package/dist/observability/metrics-state.service.js.map +1 -0
  87. package/dist/payment-method-handler.d.ts +26 -0
  88. package/dist/payment-method-handler.d.ts.map +1 -0
  89. package/dist/payment-method-handler.js +693 -0
  90. package/dist/payment-method-handler.js.map +1 -0
  91. package/dist/plugin.d.ts +95 -0
  92. package/dist/plugin.d.ts.map +1 -0
  93. package/dist/plugin.js +241 -0
  94. package/dist/plugin.js.map +1 -0
  95. package/dist/providers/viva-oauth2-strategy.provider.d.ts +41 -0
  96. package/dist/providers/viva-oauth2-strategy.provider.d.ts.map +1 -0
  97. package/dist/providers/viva-oauth2-strategy.provider.js +60 -0
  98. package/dist/providers/viva-oauth2-strategy.provider.js.map +1 -0
  99. package/dist/services/connected-accounts.service.d.ts +53 -0
  100. package/dist/services/connected-accounts.service.d.ts.map +1 -0
  101. package/dist/services/connected-accounts.service.js +108 -0
  102. package/dist/services/connected-accounts.service.js.map +1 -0
  103. package/dist/services/per-merchant-semaphore.service.d.ts +49 -0
  104. package/dist/services/per-merchant-semaphore.service.d.ts.map +1 -0
  105. package/dist/services/per-merchant-semaphore.service.js +156 -0
  106. package/dist/services/per-merchant-semaphore.service.js.map +1 -0
  107. package/dist/services/state-machine.service.d.ts +100 -0
  108. package/dist/services/state-machine.service.d.ts.map +1 -0
  109. package/dist/services/state-machine.service.js +233 -0
  110. package/dist/services/state-machine.service.js.map +1 -0
  111. package/dist/types.d.ts +286 -0
  112. package/dist/types.d.ts.map +1 -0
  113. package/dist/types.js +23 -0
  114. package/dist/types.js.map +1 -0
  115. package/dist/util/currency.d.ts +32 -0
  116. package/dist/util/currency.d.ts.map +1 -0
  117. package/dist/util/currency.js +90 -0
  118. package/dist/util/currency.js.map +1 -0
  119. package/dist/util/error-envelope.d.ts +51 -0
  120. package/dist/util/error-envelope.d.ts.map +1 -0
  121. package/dist/util/error-envelope.js +157 -0
  122. package/dist/util/error-envelope.js.map +1 -0
  123. package/dist/util/ip-allowlist.d.ts +44 -0
  124. package/dist/util/ip-allowlist.d.ts.map +1 -0
  125. package/dist/util/ip-allowlist.js +139 -0
  126. package/dist/util/ip-allowlist.js.map +1 -0
  127. package/dist/util/normalize-options.d.ts +24 -0
  128. package/dist/util/normalize-options.d.ts.map +1 -0
  129. package/dist/util/normalize-options.js +189 -0
  130. package/dist/util/normalize-options.js.map +1 -0
  131. package/dist/util/url-template.d.ts +18 -0
  132. package/dist/util/url-template.d.ts.map +1 -0
  133. package/dist/util/url-template.js +22 -0
  134. package/dist/util/url-template.js.map +1 -0
  135. package/package.json +75 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shop-api.resolver.js","sourceRoot":"","sources":["../../src/api/shop-api.resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * api/webhook.controller.ts — Viva Wallet webhook receiver.
3
+ *
4
+ * Handles two routes:
5
+ *
6
+ * GET /viva/webhook — URL-verification handshake (no auth gate).
7
+ * Returns {"key":"<webhookVerificationKey>"} to prove
8
+ * ownership to Viva at registration time.
9
+ *
10
+ * POST /viva/webhook — Receive Viva event.
11
+ * 1. IP allowlist check.
12
+ * 2. Parse + validate envelope.
13
+ * 3. INSERT-OR-IGNORE into viva_webhook_event.
14
+ * 4. Enqueue BullMQ job if newly inserted (dedup).
15
+ * 5. Always return 200 {"ok":true}.
16
+ *
17
+ * Latency target: <100ms server-side — no Viva API call in this path.
18
+ *
19
+ * @see docs/plans/vendure-plugin-v0.md §"Webhook Design — Receive flow"
20
+ * @see docs/plans/vendure-plugin-v0.md §"Build Plan — V6"
21
+ * @see docs/VENDURE-CONTRACT.MD §4 "Webhook receiver"
22
+ */
23
+ import type { OnModuleInit } from '@nestjs/common';
24
+ import type { IncomingMessage, ServerResponse } from 'node:http';
25
+ import { TransactionalConnection, JobQueueService } from '@vendure/core';
26
+ import type { VivaPaymentPluginOptions } from '../types.js';
27
+ export declare class WebhookController implements OnModuleInit {
28
+ private readonly options;
29
+ private readonly connection;
30
+ private readonly jobQueueService;
31
+ /**
32
+ * BullMQ job queue — created once in onModuleInit, reused per-request.
33
+ * The actual processing logic is implemented in V7's job handler.
34
+ */
35
+ private webhookQueue;
36
+ constructor(options: VivaPaymentPluginOptions, connection: TransactionalConnection, jobQueueService: JobQueueService);
37
+ onModuleInit(): Promise<void>;
38
+ /**
39
+ * Viva calls this endpoint anonymously during webhook registration to verify
40
+ * ownership of the URL. We return the verification key from plugin options.
41
+ *
42
+ * No auth gate — Viva calls this without credentials.
43
+ * @see docs/VENDURE-CONTRACT.MD §4 (URL-verification handshake)
44
+ */
45
+ handleVerification(res: ServerResponse): void;
46
+ /**
47
+ * Main receive path:
48
+ * 1. IP allowlist check → 403 if blocked.
49
+ * 2. Envelope parse → 400 if malformed.
50
+ * 3. INSERT-OR-IGNORE into viva_webhook_event.
51
+ * 4. Enqueue job if newly inserted; skip if replay.
52
+ * 5. Always 200 {"ok":true}.
53
+ */
54
+ handleEvent(req: IncomingMessage & {
55
+ body?: unknown;
56
+ }, res: ServerResponse): Promise<void>;
57
+ }
58
+ //# sourceMappingURL=webhook.controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.controller.d.ts","sourceRoot":"","sources":["../../src/api/webhook.controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAUH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,EACL,uBAAuB,EAEvB,eAAe,EAChB,MAAM,eAAe,CAAC;AAIvB,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAwB5D,qBACa,iBAAkB,YAAW,YAAY;IASlD,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAVlC;;;OAGG;IACH,OAAO,CAAC,YAAY,CAAuC;gBAIxC,OAAO,EAAE,wBAAwB,EACjC,UAAU,EAAE,uBAAuB,EACnC,eAAe,EAAE,eAAe;IAG7C,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAgBnC;;;;;;OAMG;IAEH,kBAAkB,CAAQ,GAAG,EAAE,cAAc,GAAG,IAAI;IAqBpD;;;;;;;OAOG;IAEG,WAAW,CACR,GAAG,EAAE,eAAe,GAAG;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,EACzC,GAAG,EAAE,cAAc,GACzB,OAAO,CAAC,IAAI,CAAC;CAsGjB"}
@@ -0,0 +1,204 @@
1
+ /**
2
+ * api/webhook.controller.ts — Viva Wallet webhook receiver.
3
+ *
4
+ * Handles two routes:
5
+ *
6
+ * GET /viva/webhook — URL-verification handshake (no auth gate).
7
+ * Returns {"key":"<webhookVerificationKey>"} to prove
8
+ * ownership to Viva at registration time.
9
+ *
10
+ * POST /viva/webhook — Receive Viva event.
11
+ * 1. IP allowlist check.
12
+ * 2. Parse + validate envelope.
13
+ * 3. INSERT-OR-IGNORE into viva_webhook_event.
14
+ * 4. Enqueue BullMQ job if newly inserted (dedup).
15
+ * 5. Always return 200 {"ok":true}.
16
+ *
17
+ * Latency target: <100ms server-side — no Viva API call in this path.
18
+ *
19
+ * @see docs/plans/vendure-plugin-v0.md §"Webhook Design — Receive flow"
20
+ * @see docs/plans/vendure-plugin-v0.md §"Build Plan — V6"
21
+ * @see docs/VENDURE-CONTRACT.MD §4 "Webhook receiver"
22
+ */
23
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
24
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
25
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
26
+ 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;
27
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
28
+ };
29
+ var __metadata = (this && this.__metadata) || function (k, v) {
30
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
31
+ };
32
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
33
+ return function (target, key) { decorator(target, key, paramIndex); }
34
+ };
35
+ import { Controller, Get, Post, Req, Res, Inject, } from '@nestjs/common';
36
+ import { TransactionalConnection, Logger, JobQueueService, } from '@vendure/core';
37
+ import { VIVA_PLUGIN_OPTIONS, VIVA_LOG_CONTEXT } from '../constants.js';
38
+ import { VivaWebhookEvent } from '../entities/viva-webhook-event.entity.js';
39
+ import { isIpAllowed, getSourceIp } from '../util/ip-allowlist.js';
40
+ import { VIVA_PROCESS_EVENT_JOB, VIVA_WEBHOOK_QUEUE } from '../jobs/queue-names.js';
41
+ // ---------------------------------------------------------------------------
42
+ // Controller
43
+ // ---------------------------------------------------------------------------
44
+ let WebhookController = class WebhookController {
45
+ options;
46
+ connection;
47
+ jobQueueService;
48
+ /**
49
+ * BullMQ job queue — created once in onModuleInit, reused per-request.
50
+ * The actual processing logic is implemented in V7's job handler.
51
+ */
52
+ webhookQueue;
53
+ constructor(options, connection, jobQueueService) {
54
+ this.options = options;
55
+ this.connection = connection;
56
+ this.jobQueueService = jobQueueService;
57
+ }
58
+ async onModuleInit() {
59
+ // Create the queue once at startup. V7 will register the process handler;
60
+ // here we provide a no-op so the queue can be used for add() calls.
61
+ this.webhookQueue = await this.jobQueueService.createQueue({
62
+ name: VIVA_WEBHOOK_QUEUE,
63
+ process: async (_job) => {
64
+ // V7 implements the actual handler (process-viva-webhook.handler.ts).
65
+ // This stub satisfies Vendure's queue registration requirement.
66
+ },
67
+ });
68
+ }
69
+ // -------------------------------------------------------------------------
70
+ // GET /viva/webhook — URL-verification handshake
71
+ // -------------------------------------------------------------------------
72
+ /**
73
+ * Viva calls this endpoint anonymously during webhook registration to verify
74
+ * ownership of the URL. We return the verification key from plugin options.
75
+ *
76
+ * No auth gate — Viva calls this without credentials.
77
+ * @see docs/VENDURE-CONTRACT.MD §4 (URL-verification handshake)
78
+ */
79
+ handleVerification(res) {
80
+ const key = this.options.webhookVerificationKey;
81
+ if (!key) {
82
+ Logger.warn('webhookVerificationKey is not configured — returning 503. Set VIVA_WEBHOOK_VERIFICATION_KEY.', VIVA_LOG_CONTEXT);
83
+ res.writeHead(503, { 'Content-Type': 'application/json' });
84
+ res.end(JSON.stringify({ error: 'webhook key not configured' }));
85
+ return;
86
+ }
87
+ res.writeHead(200, { 'Content-Type': 'application/json' });
88
+ res.end(JSON.stringify({ key }));
89
+ }
90
+ // -------------------------------------------------------------------------
91
+ // POST /viva/webhook — Receive event
92
+ // -------------------------------------------------------------------------
93
+ /**
94
+ * Main receive path:
95
+ * 1. IP allowlist check → 403 if blocked.
96
+ * 2. Envelope parse → 400 if malformed.
97
+ * 3. INSERT-OR-IGNORE into viva_webhook_event.
98
+ * 4. Enqueue job if newly inserted; skip if replay.
99
+ * 5. Always 200 {"ok":true}.
100
+ */
101
+ async handleEvent(req, res) {
102
+ // ------------------------------------------------------------------
103
+ // 1. IP allowlist (CSO Finding #2)
104
+ // ------------------------------------------------------------------
105
+ // trustedProxyDepth tells the helper how many trailing X-Forwarded-For
106
+ // hops are set by operator-controlled proxies; the leftmost (attacker-
107
+ // controllable) entries are ignored.
108
+ const sourceIp = getSourceIp(req, this.options.trustedProxyDepth ?? 0);
109
+ const allowlist = this.options.webhookIpAllowlist;
110
+ if (!isIpAllowed(sourceIp, allowlist)) {
111
+ Logger.warn(`Webhook POST rejected: source IP ${sourceIp} not in allowlist.`, VIVA_LOG_CONTEXT);
112
+ res.writeHead(403, { 'Content-Type': 'application/json' });
113
+ res.end(JSON.stringify({ error: 'forbidden' }));
114
+ return;
115
+ }
116
+ // ------------------------------------------------------------------
117
+ // 2. Parse envelope
118
+ // ------------------------------------------------------------------
119
+ const body = req.body;
120
+ if (!body || typeof body.MessageId !== 'string' || !body.MessageId) {
121
+ Logger.warn('Webhook POST: missing or invalid MessageId.', VIVA_LOG_CONTEXT);
122
+ res.writeHead(400, { 'Content-Type': 'application/json' });
123
+ res.end(JSON.stringify({ error: 'malformed envelope' }));
124
+ return;
125
+ }
126
+ if (typeof body.EventTypeId !== 'number' || !body.EventTypeId) {
127
+ Logger.warn(`Webhook POST: missing or invalid EventTypeId for MessageId=${body.MessageId}.`, VIVA_LOG_CONTEXT);
128
+ res.writeHead(400, { 'Content-Type': 'application/json' });
129
+ res.end(JSON.stringify({ error: 'malformed envelope' }));
130
+ return;
131
+ }
132
+ const messageId = body.MessageId;
133
+ const eventTypeId = body.EventTypeId;
134
+ const eventData = (body.EventData ?? {});
135
+ // ------------------------------------------------------------------
136
+ // 3. INSERT-OR-IGNORE into viva_webhook_event
137
+ // ------------------------------------------------------------------
138
+ const repo = this.connection.rawConnection.getRepository(VivaWebhookEvent);
139
+ const insertResult = await repo
140
+ .createQueryBuilder()
141
+ .insert()
142
+ .into(VivaWebhookEvent)
143
+ .values({
144
+ messageId,
145
+ eventTypeId,
146
+ merchantId: eventData['MerchantId'] ?? null,
147
+ transactionId: eventData['TransactionId'] ?? null,
148
+ accountId: eventData['AccountId'] ?? null,
149
+ correlationId: body.CorrelationId ?? null,
150
+ retryCount: body.RetryCount ?? 0,
151
+ // Cast to any: TypeORM's _QueryDeepPartialEntity doesn't accept
152
+ // plain objects for jsonb columns — the value is serialised correctly
153
+ // at the driver level.
154
+ payload: body,
155
+ })
156
+ .orIgnore()
157
+ .execute();
158
+ const rowsInserted = insertResult.identifiers.length;
159
+ // ------------------------------------------------------------------
160
+ // 4. Deduplicate — already processed replay
161
+ // ------------------------------------------------------------------
162
+ if (rowsInserted === 0) {
163
+ Logger.debug(`Webhook POST: duplicate MessageId=${messageId} (replay) — skipping enqueue.`, VIVA_LOG_CONTEXT);
164
+ res.writeHead(200, { 'Content-Type': 'application/json' });
165
+ res.end(JSON.stringify({ ok: true }));
166
+ return;
167
+ }
168
+ // ------------------------------------------------------------------
169
+ // 5. Enqueue BullMQ job (resilient — 200 even if enqueue fails)
170
+ // ------------------------------------------------------------------
171
+ try {
172
+ await this.webhookQueue.add({ messageId });
173
+ }
174
+ catch (err) {
175
+ // Row is persisted; V7's worker can pick it up via reprocess logic (A6).
176
+ Logger.warn(`Webhook POST: job enqueue failed for MessageId=${messageId}. Row persisted; worker will retry. Error: ${String(err)}`, VIVA_LOG_CONTEXT);
177
+ }
178
+ res.writeHead(200, { 'Content-Type': 'application/json' });
179
+ res.end(JSON.stringify({ ok: true }));
180
+ }
181
+ };
182
+ __decorate([
183
+ Get(),
184
+ __param(0, Res()),
185
+ __metadata("design:type", Function),
186
+ __metadata("design:paramtypes", [Function]),
187
+ __metadata("design:returntype", void 0)
188
+ ], WebhookController.prototype, "handleVerification", null);
189
+ __decorate([
190
+ Post(),
191
+ __param(0, Req()),
192
+ __param(1, Res()),
193
+ __metadata("design:type", Function),
194
+ __metadata("design:paramtypes", [Object, Function]),
195
+ __metadata("design:returntype", Promise)
196
+ ], WebhookController.prototype, "handleEvent", null);
197
+ WebhookController = __decorate([
198
+ Controller('viva/webhook'),
199
+ __param(0, Inject(VIVA_PLUGIN_OPTIONS)),
200
+ __metadata("design:paramtypes", [Object, TransactionalConnection,
201
+ JobQueueService])
202
+ ], WebhookController);
203
+ export { WebhookController };
204
+ //# sourceMappingURL=webhook.controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.controller.js","sourceRoot":"","sources":["../../src/api/webhook.controller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * bin.ts — CLI entrypoint for vendure-viva-register-webhooks.
4
+ *
5
+ * Parses argv with node:util.parseArgs (zero additional npm dependencies).
6
+ * Loads plugin config from env vars and delegates to run() from register-webhooks.ts.
7
+ *
8
+ * Env vars:
9
+ * VIVA_MODE merchant | isv (default: isv)
10
+ * VIVA_CLIENT_ID required (ISV mode) — alias VIVA_ISV_CLIENT_ID deprecated
11
+ * VIVA_CLIENT_SECRET required (ISV mode) — alias VIVA_ISV_CLIENT_SECRET deprecated
12
+ * VIVA_MERCHANT_ID required (merchant --apply)
13
+ * VIVA_API_KEY required (merchant --apply)
14
+ * VIVA_ENVIRONMENT demo | production (default: demo)
15
+ * VIVA_WEBHOOK_URL required for registration (full URL)
16
+ * VIVA_WEBHOOK_VERIFICATION_KEY optional in ISV mode; generated if absent
17
+ *
18
+ * Verification key note:
19
+ * If VIVA_WEBHOOK_VERIFICATION_KEY is not set, the CLI generates a UUIDv4 and
20
+ * prints it. You must set this value in your plugin options and env before Viva
21
+ * can probe the GET /viva/webhook endpoint for URL verification.
22
+ * The key is NOT posted to Viva — Viva fetches it from your endpoint.
23
+ *
24
+ * @see docs/plans/vendure-plugin-v0.md §"CLI vendure-viva-register-webhooks" (V10)
25
+ * @see src/api/webhook.controller.ts (handleVerification)
26
+ */
27
+ export {};
28
+ //# sourceMappingURL=bin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG"}
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * bin.ts — CLI entrypoint for vendure-viva-register-webhooks.
4
+ *
5
+ * Parses argv with node:util.parseArgs (zero additional npm dependencies).
6
+ * Loads plugin config from env vars and delegates to run() from register-webhooks.ts.
7
+ *
8
+ * Env vars:
9
+ * VIVA_MODE merchant | isv (default: isv)
10
+ * VIVA_CLIENT_ID required (ISV mode) — alias VIVA_ISV_CLIENT_ID deprecated
11
+ * VIVA_CLIENT_SECRET required (ISV mode) — alias VIVA_ISV_CLIENT_SECRET deprecated
12
+ * VIVA_MERCHANT_ID required (merchant --apply)
13
+ * VIVA_API_KEY required (merchant --apply)
14
+ * VIVA_ENVIRONMENT demo | production (default: demo)
15
+ * VIVA_WEBHOOK_URL required for registration (full URL)
16
+ * VIVA_WEBHOOK_VERIFICATION_KEY optional in ISV mode; generated if absent
17
+ *
18
+ * Verification key note:
19
+ * If VIVA_WEBHOOK_VERIFICATION_KEY is not set, the CLI generates a UUIDv4 and
20
+ * prints it. You must set this value in your plugin options and env before Viva
21
+ * can probe the GET /viva/webhook endpoint for URL verification.
22
+ * The key is NOT posted to Viva — Viva fetches it from your endpoint.
23
+ *
24
+ * @see docs/plans/vendure-plugin-v0.md §"CLI vendure-viva-register-webhooks" (V10)
25
+ * @see src/api/webhook.controller.ts (handleVerification)
26
+ */
27
+ import { parseArgs } from 'node:util';
28
+ import { run } from './register-webhooks.js';
29
+ const { values } = parseArgs({
30
+ options: {
31
+ 'dry-run': { type: 'boolean', default: false },
32
+ apply: { type: 'boolean', default: false },
33
+ 'webhook-url': { type: 'string' },
34
+ 'reconcile-drift': { type: 'boolean', default: false },
35
+ output: { type: 'string', default: 'text' },
36
+ help: { type: 'boolean', default: false, short: 'h' },
37
+ },
38
+ strict: true,
39
+ });
40
+ if (values.help) {
41
+ console.log(`
42
+ vendure-viva-register-webhooks — Set up V1 webhook URLs for the configured Viva account.
43
+
44
+ Mode is selected by VIVA_MODE (default: isv):
45
+ - ISV mode: idempotently POSTs to /isv/v1/webhooks for every event type
46
+ (1796, 1797, 1798, 4865, 8193, 8194).
47
+ - Merchant mode: prints the four transaction-event URLs (1796/1797/1798/4865)
48
+ to register manually in Viva Self Care → Sales → API Access
49
+ → Webhooks, plus the verification key fetched via
50
+ GET /api/messages/config/token.
51
+
52
+ Usage:
53
+ vendure-viva-register-webhooks --dry-run [--output json]
54
+ vendure-viva-register-webhooks --apply [--reconcile-drift]
55
+ vendure-viva-register-webhooks --apply --webhook-url https://api.example.com/viva/webhook
56
+
57
+ Environment:
58
+ VIVA_MODE merchant | isv (default: isv)
59
+ VIVA_ENVIRONMENT demo | production (default: demo)
60
+ VIVA_CLIENT_ID required for ISV mode (alias: VIVA_ISV_CLIENT_ID, deprecated)
61
+ VIVA_CLIENT_SECRET required for ISV mode (alias: VIVA_ISV_CLIENT_SECRET, deprecated)
62
+ VIVA_MERCHANT_ID required for merchant --apply (legacy Basic-auth)
63
+ VIVA_API_KEY required for merchant --apply (legacy Basic-auth)
64
+ VIVA_WEBHOOK_URL required; full URL to receive webhook POSTs
65
+ VIVA_WEBHOOK_VERIFICATION_KEY optional in ISV mode; UUIDv4 generated if absent
66
+
67
+ Notes:
68
+ --reconcile-drift is non-applicable in merchant mode (manual setup only).
69
+
70
+ Verification key:
71
+ - ISV mode: the CLI generates a UUIDv4 if VIVA_WEBHOOK_VERIFICATION_KEY is
72
+ not set. Set the generated value in your VivaPaymentPlugin.init() options
73
+ AND in .env. Viva sends a GET probe to your webhook URL during
74
+ registration; the WebhookController returns {"key":"<that-uuid>"} to
75
+ prove URL ownership. The key is NOT posted to Viva.
76
+ - Merchant mode: the CLI fetches the key via GET /api/messages/config/token
77
+ on the legacy host. Paste the printed value into the same env var.
78
+
79
+ Exit codes:
80
+ 0 clean / applied successfully / merchant manual setup printed
81
+ 1 plan has actions but --apply was not passed (CI gate use case — ISV mode)
82
+ 2 apply failed (HTTP/Viva error)
83
+ 3 fatal precondition (config invalid, ABORT_LIMIT_HIT)
84
+ `);
85
+ process.exit(0);
86
+ }
87
+ if (!values['dry-run'] && !values.apply) {
88
+ console.error('Specify --dry-run or --apply (or --help).');
89
+ process.exit(3);
90
+ }
91
+ const outputValue = values.output;
92
+ const output = outputValue === 'json' ? 'json' : 'text';
93
+ const runOpts = {
94
+ dryRun: !!values['dry-run'],
95
+ apply: !!values.apply,
96
+ reconcileDrift: !!values['reconcile-drift'],
97
+ output,
98
+ };
99
+ if (values['webhook-url'] !== undefined) {
100
+ runOpts.webhookUrl = values['webhook-url'];
101
+ }
102
+ const exitCode = await run(runOpts);
103
+ process.exit(exitCode);
104
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAG7C,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE;QACP,SAAS,EAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;QACnD,KAAK,EAAW,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;QACnD,aAAa,EAAG,EAAE,IAAI,EAAE,QAAQ,EAAE;QAClC,iBAAiB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;QACtD,MAAM,EAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE;QACnD,IAAI,EAAY,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE;KAChE;IACD,MAAM,EAAE,IAAI;CACb,CAAC,CAAC;AAEH,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2Cb,CAAC,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACxC,OAAO,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,WAAW,GAAG,MAAM,CAAC,MAAgB,CAAC;AAC5C,MAAM,MAAM,GAAyB,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;AAE9E,MAAM,OAAO,GAAe;IAC1B,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC;IAC3B,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK;IACrB,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC;IAC3C,MAAM;CACP,CAAC;AAEF,IAAI,MAAM,CAAC,aAAa,CAAC,KAAK,SAAS,EAAE,CAAC;IACxC,OAAO,CAAC,UAAU,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC;AACpC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * cli/plan.ts — Pure, IO-free webhook plan computation.
3
+ *
4
+ * Computes the diff between desired webhook state (from config) and current
5
+ * registrations (from Viva API), returning a deterministic action list.
6
+ *
7
+ * Per Viva docs, max 10 webhook URLs per event type.
8
+ *
9
+ * Mirrors medusa-payment-viva/src/cli/plan.ts conventions exactly.
10
+ *
11
+ * @see packages/medusa-payment-viva/src/cli/plan.ts
12
+ * @see references/viva-docs/md/webhooks-for-payments.txt:134 (10-URL limit)
13
+ */
14
+ import type { DesiredWebhook, PlanResult, WebhookRegistration } from './types.js';
15
+ export interface ComputePlanInput {
16
+ desired: readonly DesiredWebhook[];
17
+ current: readonly WebhookRegistration[];
18
+ /** Per Viva: 10 URLs per event type. Default 10. */
19
+ perEventTypeLimit?: number;
20
+ /** Warn fraction. Default 0.8 → warn at 8. */
21
+ nearLimitFraction?: number;
22
+ /** Whether to deactivate URLs not in desired set. Default false. */
23
+ reconcileDrift?: boolean;
24
+ /** Hostname pattern for drift reconciliation (avoid touching foreign webhooks). */
25
+ ownedHostnamePattern?: RegExp;
26
+ /** Verification key generated or sourced from env. */
27
+ generatedVerificationKey?: string | undefined;
28
+ }
29
+ /**
30
+ * Deterministic diff between desired and current webhook registrations.
31
+ *
32
+ * Action ordering:
33
+ * 1. REGISTER (sorted by eventTypeId)
34
+ * 2. SKIP_ALREADY_REGISTERED (sorted by eventTypeId)
35
+ * 3. DEACTIVATE_DRIFT (sorted by eventTypeId)
36
+ * 4. WARN_LIMIT_NEAR (sorted by eventTypeId)
37
+ * 5. ABORT_LIMIT_HIT (sorted by eventTypeId)
38
+ */
39
+ export declare function computePlan(input: ComputePlanInput): PlanResult;
40
+ export declare function buildOwnedPattern(webhookUrl: string): RegExp;
41
+ //# sourceMappingURL=plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/cli/plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACV,cAAc,EAEd,UAAU,EACV,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAMpB,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,SAAS,cAAc,EAAE,CAAC;IACnC,OAAO,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACxC,oDAAoD;IACpD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8CAA8C;IAC9C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,oEAAoE;IACpE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,mFAAmF;IACnF,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,sDAAsD;IACtD,wBAAwB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/C;AAMD;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,UAAU,CAmG/D;AAMD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAQ5D"}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * cli/plan.ts — Pure, IO-free webhook plan computation.
3
+ *
4
+ * Computes the diff between desired webhook state (from config) and current
5
+ * registrations (from Viva API), returning a deterministic action list.
6
+ *
7
+ * Per Viva docs, max 10 webhook URLs per event type.
8
+ *
9
+ * Mirrors medusa-payment-viva/src/cli/plan.ts conventions exactly.
10
+ *
11
+ * @see packages/medusa-payment-viva/src/cli/plan.ts
12
+ * @see references/viva-docs/md/webhooks-for-payments.txt:134 (10-URL limit)
13
+ */
14
+ // ---------------------------------------------------------------------------
15
+ // computePlan
16
+ // ---------------------------------------------------------------------------
17
+ /**
18
+ * Deterministic diff between desired and current webhook registrations.
19
+ *
20
+ * Action ordering:
21
+ * 1. REGISTER (sorted by eventTypeId)
22
+ * 2. SKIP_ALREADY_REGISTERED (sorted by eventTypeId)
23
+ * 3. DEACTIVATE_DRIFT (sorted by eventTypeId)
24
+ * 4. WARN_LIMIT_NEAR (sorted by eventTypeId)
25
+ * 5. ABORT_LIMIT_HIT (sorted by eventTypeId)
26
+ */
27
+ export function computePlan(input) {
28
+ const { desired, current, perEventTypeLimit = 10, nearLimitFraction = 0.8, reconcileDrift = false, ownedHostnamePattern, generatedVerificationKey, } = input;
29
+ const nearLimitThreshold = Math.floor(perEventTypeLimit * nearLimitFraction);
30
+ // Index: eventTypeId → url → WebhookRegistration
31
+ const currentByTypeAndUrl = new Map();
32
+ // Index: eventTypeId → all registrations (for limit counting)
33
+ const currentByType = new Map();
34
+ for (const reg of current) {
35
+ if (!currentByType.has(reg.eventTypeId)) {
36
+ currentByType.set(reg.eventTypeId, []);
37
+ }
38
+ currentByType.get(reg.eventTypeId).push(reg);
39
+ if (!currentByTypeAndUrl.has(reg.eventTypeId)) {
40
+ currentByTypeAndUrl.set(reg.eventTypeId, new Map());
41
+ }
42
+ currentByTypeAndUrl.get(reg.eventTypeId).set(reg.url, reg);
43
+ }
44
+ const registerActions = [];
45
+ const skipActions = [];
46
+ const warnActions = [];
47
+ const abortActions = [];
48
+ const sortedDesired = [...desired].sort((a, b) => a.eventTypeId - b.eventTypeId);
49
+ for (const d of sortedDesired) {
50
+ const urlIndex = currentByTypeAndUrl.get(d.eventTypeId);
51
+ const existingForType = currentByType.get(d.eventTypeId) ?? [];
52
+ const registeredCount = existingForType.length;
53
+ if (urlIndex?.has(d.url)) {
54
+ skipActions.push({ kind: 'SKIP_ALREADY_REGISTERED', existing: urlIndex.get(d.url) });
55
+ continue;
56
+ }
57
+ if (registeredCount >= perEventTypeLimit) {
58
+ abortActions.push({
59
+ kind: 'ABORT_LIMIT_HIT',
60
+ eventTypeId: d.eventTypeId,
61
+ current: registeredCount,
62
+ limit: perEventTypeLimit,
63
+ });
64
+ continue;
65
+ }
66
+ if (registeredCount >= nearLimitThreshold) {
67
+ warnActions.push({
68
+ kind: 'WARN_LIMIT_NEAR',
69
+ eventTypeId: d.eventTypeId,
70
+ current: registeredCount,
71
+ limit: perEventTypeLimit,
72
+ });
73
+ }
74
+ registerActions.push({ kind: 'REGISTER', desired: d });
75
+ }
76
+ // Drift reconciliation
77
+ const deactivateActions = [];
78
+ if (reconcileDrift) {
79
+ const desiredUrlSet = new Set(desired.map((d) => d.url));
80
+ const sortedCurrent = [...current].sort((a, b) => a.eventTypeId - b.eventTypeId);
81
+ for (const reg of sortedCurrent) {
82
+ const isOwned = ownedHostnamePattern ? ownedHostnamePattern.test(reg.url) : true;
83
+ if (!desiredUrlSet.has(reg.url) && isOwned) {
84
+ deactivateActions.push({
85
+ kind: 'DEACTIVATE_DRIFT',
86
+ existing: reg,
87
+ reason: 'URL_NOT_IN_DESIRED',
88
+ });
89
+ }
90
+ }
91
+ }
92
+ const actions = [
93
+ ...registerActions,
94
+ ...skipActions,
95
+ ...deactivateActions,
96
+ ...warnActions,
97
+ ...abortActions,
98
+ ];
99
+ const hasFatalError = abortActions.length > 0;
100
+ return { actions, hasFatalError, generatedVerificationKey };
101
+ }
102
+ // ---------------------------------------------------------------------------
103
+ // buildOwnedPattern helper (shared with register-webhooks)
104
+ // ---------------------------------------------------------------------------
105
+ export function buildOwnedPattern(webhookUrl) {
106
+ try {
107
+ const { hostname } = new URL(webhookUrl);
108
+ const escaped = hostname.replace(/\./g, '\\.');
109
+ return new RegExp(escaped);
110
+ }
111
+ catch {
112
+ return /.*/;
113
+ }
114
+ }
115
+ //# sourceMappingURL=plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/cli/plan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * cli/register-webhooks.ts — Main CLI logic for idempotent webhook registration.
3
+ *
4
+ * Mode-aware:
5
+ * - ISV mode: builds the ISV webhook client and POSTs one /isv/v1/webhooks
6
+ * registration per V1 event type (1796, 1797, 1798, 4865, 8193, 8194).
7
+ * All merchants on the platform share the same webhook URL.
8
+ * - Merchant mode: Viva offers no programmatic registration. The CLI fetches
9
+ * the verification key from GET /api/messages/config/token (Basic auth,
10
+ * merchant variant) and prints the URLs the operator must paste into Viva
11
+ * Self Care → Sales → API Access → Webhooks. `--reconcile-drift` is
12
+ * non-applicable in merchant mode.
13
+ *
14
+ * Verification key (ISV mode):
15
+ * CLI generates a UUIDv4 if VIVA_WEBHOOK_VERIFICATION_KEY is not set.
16
+ * The key is surfaced for the operator to paste into plugin options + Viva Self Care.
17
+ * It is NOT posted to Viva — Viva sends a GET probe to /viva/webhook and the
18
+ * WebhookController returns {"key":"<that-uuid>"} from plugin config.
19
+ * @see src/api/webhook.controller.ts#handleVerification
20
+ *
21
+ * Exit codes:
22
+ * 0 — clean (no actions OR all applied successfully OR merchant manual setup printed)
23
+ * 1 — plan has actions but --apply was not passed (CI gate use case — ISV mode only)
24
+ * 2 — apply failed (HTTP/Viva error)
25
+ * 3 — fatal precondition (config invalid, ABORT_LIMIT_HIT)
26
+ *
27
+ * Mirrors medusa-payment-viva/src/cli/register-webhooks.ts conventions.
28
+ *
29
+ * @see docs/plans/vendure-plugin-v0.md §"CLI vendure-viva-register-webhooks" (V10)
30
+ * @see references/viva-docs/md/webhooks-for-payments.txt:134 (10-URL limit)
31
+ * @see docs/plans/multi-mode-v0.md §9.5 (CLI behaviour matrix)
32
+ */
33
+ type Dispatcher = any;
34
+ import type { RunOptions } from './types.js';
35
+ export type { RunOptions };
36
+ /**
37
+ * Programmatic entry — also called by bin.ts for the CLI.
38
+ * Reads VIVA_* env from the provided env object (defaults to process.env).
39
+ *
40
+ * @param opts - CLI run options.
41
+ * @param env - Optional env override (defaults to process.env). Used in tests.
42
+ * @param dispatcher - Optional undici Dispatcher override (MockAgent in tests).
43
+ */
44
+ export declare function run(opts: RunOptions, env?: NodeJS.ProcessEnv, dispatcher?: Dispatcher): Promise<number>;
45
+ //# sourceMappingURL=register-webhooks.d.ts.map