@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,233 @@
1
+ /**
2
+ * services/state-machine.service.ts — Low-level VivaTransaction row helpers
3
+ * AND Vendure order/payment transition wrappers (V7 extension).
4
+ *
5
+ * Row helpers: INSERT-OR-NOTHING idempotent writes + lookups for VivaTransaction.
6
+ * Transition helpers: wraps OrderService + PaymentService state-machine calls;
7
+ * used exclusively by the webhook worker (V7). Implements the stale-recovery
8
+ * re-walk (AddingItems → ArrangingPayment → PaymentAuthorized → PaymentSettled)
9
+ * with fail-loud semantics per Q4 decision.
10
+ *
11
+ * Repository injection via Vendure's TransactionalConnection.
12
+ *
13
+ * @see docs/plans/vendure-plugin-v0.md §"Build Plan — V5 + V7"
14
+ * @see docs/plans/vendure-plugin-v0.md §D6 (state transitions via OrderService)
15
+ * @see docs/plans/vendure-plugin-v0.md §D11 (idempotency)
16
+ */
17
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
18
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
19
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
20
+ 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;
21
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
22
+ };
23
+ var __metadata = (this && this.__metadata) || function (k, v) {
24
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
25
+ };
26
+ import { Injectable, Logger as NestLogger } from '@nestjs/common';
27
+ import { TransactionalConnection, Logger, OrderService, PaymentService } from '@vendure/core';
28
+ import { QueryFailedError } from 'typeorm';
29
+ import { VivaTransaction } from '../entities/viva-transaction.entity.js';
30
+ import { VIVA_LOG_CONTEXT } from '../constants.js';
31
+ // ---------------------------------------------------------------------------
32
+ // Service
33
+ // ---------------------------------------------------------------------------
34
+ let StateMachineService = class StateMachineService {
35
+ connection;
36
+ orderService;
37
+ paymentService;
38
+ constructor(connection, orderService, paymentService) {
39
+ this.connection = connection;
40
+ this.orderService = orderService;
41
+ this.paymentService = paymentService;
42
+ }
43
+ /**
44
+ * Load a VivaTransaction row by (channelId, paymentId).
45
+ * Returns null if not found.
46
+ */
47
+ async getVivaTransaction(ctx, channelId, paymentId) {
48
+ const repo = this.connection.getRepository(ctx, VivaTransaction);
49
+ return repo.findOne({
50
+ where: { channelId: channelId, paymentId: paymentId },
51
+ });
52
+ }
53
+ /**
54
+ * INSERT-OR-NOTHING write of a pending VivaTransaction row.
55
+ *
56
+ * Idempotency key D11: keyed on (channelId, paymentId).
57
+ * If a row already exists with the same key and a non-null vivaOrderCode,
58
+ * returns that existing row so the handler can skip the Viva API call.
59
+ *
60
+ * Returns: { row, wasInserted }
61
+ * wasInserted=true → freshly inserted; handler must call Viva.
62
+ * wasInserted=false → already existed; check row.vivaOrderCode.
63
+ */
64
+ async upsertPendingTransaction(ctx, input) {
65
+ const repo = this.connection.getRepository(ctx, VivaTransaction);
66
+ // Check if already exists
67
+ const existing = await repo.findOne({
68
+ where: {
69
+ channelId: input.channelId,
70
+ paymentId: input.paymentId,
71
+ },
72
+ });
73
+ if (existing) {
74
+ return { row: existing, wasInserted: false };
75
+ }
76
+ // Try to INSERT; handle race condition via duplicate-key error.
77
+ const row = repo.create({
78
+ channelId: input.channelId,
79
+ paymentId: input.paymentId,
80
+ status: 'pending',
81
+ vivaOrderCode: null,
82
+ vivaTransactionId: null,
83
+ amountMinor: input.amountMinor.toString(),
84
+ currencyCode: input.currencyCode,
85
+ isvAmountMinor: input.isvAmountMinor.toString(),
86
+ metadata: { idempotencyKey: input.idempotencyKey },
87
+ });
88
+ try {
89
+ const saved = await repo.save(row);
90
+ return { row: saved, wasInserted: true };
91
+ }
92
+ catch (err) {
93
+ // Duplicate key: another request beat us to the insert (race).
94
+ if (err instanceof QueryFailedError && this._isDuplicateKeyError(err)) {
95
+ const existing2 = await repo.findOne({
96
+ where: {
97
+ channelId: input.channelId,
98
+ paymentId: input.paymentId,
99
+ },
100
+ });
101
+ if (existing2) {
102
+ return { row: existing2, wasInserted: false };
103
+ }
104
+ }
105
+ throw err;
106
+ }
107
+ }
108
+ /**
109
+ * Update the vivaOrderCode on a pending row after createOrder succeeds.
110
+ */
111
+ async setOrderCode(ctx, rowId, vivaOrderCode, metadata) {
112
+ const repo = this.connection.getRepository(ctx, VivaTransaction);
113
+ // Use query builder to avoid exactOptionalPropertyTypes issues with TypeORM _QueryDeepPartialEntity.
114
+ await repo
115
+ .createQueryBuilder()
116
+ .update(VivaTransaction)
117
+ .set({ vivaOrderCode, metadata: () => ':meta' })
118
+ .where('id = :id', { id: rowId })
119
+ .setParameter('meta', JSON.stringify(metadata))
120
+ .execute();
121
+ }
122
+ /**
123
+ * Update row status (e.g. pending → captured, pending → cancelled).
124
+ */
125
+ async setStatus(ctx, rowId, status, metadata) {
126
+ const repo = this.connection.getRepository(ctx, VivaTransaction);
127
+ if (metadata !== undefined) {
128
+ await repo
129
+ .createQueryBuilder()
130
+ .update(VivaTransaction)
131
+ .set({ status, metadata: () => ':meta' })
132
+ .where('id = :id', { id: rowId })
133
+ .setParameter('meta', JSON.stringify(metadata))
134
+ .execute();
135
+ }
136
+ else {
137
+ await repo
138
+ .createQueryBuilder()
139
+ .update(VivaTransaction)
140
+ .set({ status })
141
+ .where('id = :id', { id: rowId })
142
+ .execute();
143
+ }
144
+ }
145
+ // ---------------------------------------------------------------------------
146
+ // Order / Payment transition helpers (V7)
147
+ // ---------------------------------------------------------------------------
148
+ /**
149
+ * Transition a Payment to `Settled` via `PaymentService.transitionToState`.
150
+ *
151
+ * Vendure's canonical path for webhook-driven settlement.
152
+ * @see docs/plans/vendure-plugin-v0.md §D6, §D5 (1796 settle path)
153
+ */
154
+ async transitionPaymentToSettled(ctx, orderId, paymentId) {
155
+ // Vendure state machine: Created → Authorized → Settled
156
+ // OrderService.settlePayment handles the two-step transition internally.
157
+ const result = await this.orderService.settlePayment(ctx, paymentId);
158
+ if ('errorCode' in result) {
159
+ throw new Error(`[StateMachineService] Failed to settle payment ${String(paymentId)} for order ${String(orderId)}: ${result.message ?? JSON.stringify(result)}`);
160
+ }
161
+ }
162
+ /**
163
+ * Transition a Payment to `Declined` via `PaymentService.transitionToState`.
164
+ *
165
+ * Called on webhook 1798 (Transaction Failed). Order stays in ArrangingPayment.
166
+ * @see docs/plans/vendure-plugin-v0.md §D5 (1798 path)
167
+ */
168
+ async transitionPaymentToDeclined(ctx, paymentId) {
169
+ await this.paymentService.transitionToState(ctx, paymentId, 'Declined');
170
+ }
171
+ /**
172
+ * Transition a Payment to `Cancelled` via `PaymentService.transitionToState`.
173
+ *
174
+ * Called on webhook 4865 user-cancel detection.
175
+ * @see docs/plans/vendure-plugin-v0.md §D5 (4865 path)
176
+ */
177
+ async transitionPaymentToCancelled(ctx, paymentId) {
178
+ await this.paymentService.transitionToState(ctx, paymentId, 'Cancelled');
179
+ }
180
+ /**
181
+ * Stale-order re-walk: AddingItems → ArrangingPayment → PaymentSettled.
182
+ *
183
+ * Implements the Q4 decision: fail-loud on any transition failure — log an
184
+ * ERROR-level message, throw, let the webhook row stay unprocessed. The
185
+ * storefront will surface "basket changed" via the live order state.
186
+ *
187
+ * Sequence:
188
+ * 1. AddingItems → ArrangingPayment (transitionOrderToState)
189
+ * 2. ArrangingPayment → settlePayment (OrderService.settlePayment)
190
+ *
191
+ * @see docs/plans/vendure-plugin-v0.md §"Process flow" step 4e
192
+ * @see docs/plans/vendure-plugin-v0.md §"Architecture Decisions Q4"
193
+ */
194
+ async recoverStaleOrderAndSettle(ctx, orderId, paymentId) {
195
+ Logger.info(`[StateMachineService] Starting stale-order re-walk for order ${String(orderId)}, payment ${String(paymentId)}.`, VIVA_LOG_CONTEXT);
196
+ // Step 1: AddingItems → ArrangingPayment
197
+ const transitionResult = await this.orderService.transitionToState(ctx, orderId, 'ArrangingPayment');
198
+ if ('errorCode' in transitionResult) {
199
+ const msg = `[StateMachineService] Stale re-walk FAILED on AddingItems→ArrangingPayment for order ${String(orderId)}: ${transitionResult.message ?? JSON.stringify(transitionResult)}`;
200
+ Logger.error(msg, VIVA_LOG_CONTEXT);
201
+ throw new Error(msg);
202
+ }
203
+ // Step 2: ArrangingPayment → settle (Created → Authorized → Settled)
204
+ const settleResult = await this.orderService.settlePayment(ctx, paymentId);
205
+ if ('errorCode' in settleResult) {
206
+ const msg = `[StateMachineService] Stale re-walk FAILED on settlePayment for order ${String(orderId)}, payment ${String(paymentId)}: ${settleResult.message ?? JSON.stringify(settleResult)}`;
207
+ Logger.error(msg, VIVA_LOG_CONTEXT);
208
+ throw new Error(msg);
209
+ }
210
+ Logger.info(`[StateMachineService] Stale re-walk complete: order ${String(orderId)} now PaymentSettled.`, VIVA_LOG_CONTEXT);
211
+ }
212
+ // ---------------------------------------------------------------------------
213
+ // Private helpers
214
+ // ---------------------------------------------------------------------------
215
+ _isDuplicateKeyError(err) {
216
+ const msg = err.code ?? '';
217
+ // Postgres unique violation
218
+ if (msg === '23505')
219
+ return true;
220
+ // SQLite UNIQUE constraint
221
+ if (err.message.toLowerCase().includes('unique'))
222
+ return true;
223
+ return false;
224
+ }
225
+ };
226
+ StateMachineService = __decorate([
227
+ Injectable(),
228
+ __metadata("design:paramtypes", [TransactionalConnection,
229
+ OrderService,
230
+ PaymentService])
231
+ ], StateMachineService);
232
+ export { StateMachineService };
233
+ //# sourceMappingURL=state-machine.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-machine.service.js","sourceRoot":"","sources":["../../src/services/state-machine.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,286 @@
1
+ /**
2
+ * types.ts — Public configuration types for VivaPaymentPlugin.
3
+ *
4
+ * v0.2.0: `VivaPaymentPluginOptions` is now a **discriminated union** on `mode`.
5
+ *
6
+ * - `mode: 'isv'` (default until 0.3.0) — multi-merchant ISV partner setup.
7
+ * - `mode: 'merchant'` — single direct Viva merchant, no reseller hierarchy.
8
+ *
9
+ * Field rename (one-minor back-compat):
10
+ * - `isvClientId` → `clientId` (old name accepted with deprecation warning)
11
+ * - `isvClientSecret` → `clientSecret`
12
+ *
13
+ * Plan ref: docs/plans/multi-mode-v0.md §5 (config shape), §10 (Vendure adapter).
14
+ *
15
+ * Vendure types (RequestContext, Order) are imported as peer-dep types only —
16
+ * no runtime Vendure import here so the types module is safe to import in
17
+ * non-Vendure test environments.
18
+ *
19
+ * viva-payments-core types are imported from sub-paths to avoid pulling in
20
+ * implementation code.
21
+ */
22
+ import type { MetricsHook, OTelTracerHook, Logger } from '@sakeetech/viva-payments-core/observability';
23
+ import type { VivaEnvironment } from '@sakeetech/viva-payments-core/types';
24
+ /**
25
+ * Minimal shape of Vendure's RequestContext used in plugin callbacks.
26
+ * Avoids importing @vendure/core in this file so unit tests don't require
27
+ * the full Vendure dependency graph.
28
+ */
29
+ export interface VendureRequestContext {
30
+ readonly channelId: string | number;
31
+ readonly channel: {
32
+ readonly id: string | number;
33
+ readonly code: string;
34
+ readonly customFields: Record<string, any>;
35
+ };
36
+ readonly apiType: string;
37
+ }
38
+ /**
39
+ * Minimal shape of Vendure's Order used in plugin callbacks.
40
+ */
41
+ export interface VendureOrder {
42
+ readonly id: string | number;
43
+ readonly code: string;
44
+ readonly totalWithTax: number;
45
+ readonly currencyCode: string;
46
+ readonly state: string;
47
+ }
48
+ export interface RedlockClient {
49
+ acquire(resources: string[], duration: number): Promise<{
50
+ release(): Promise<void>;
51
+ }>;
52
+ }
53
+ export type VivaMode = 'merchant' | 'isv';
54
+ /**
55
+ * Fields shared by both merchant and ISV mode configurations.
56
+ *
57
+ * Field-name rationale:
58
+ * - `clientId` / `clientSecret` — mode-agnostic OAuth2 client_credentials.
59
+ * Renamed from `isvClientId` / `isvClientSecret` in 0.2.0. Old names still
60
+ * accepted via `init()` with a deprecation warning (removal in 0.3.0).
61
+ * - `legacyMerchantId` / `legacyApiKey` — Basic-auth pair against the legacy
62
+ * host. Required in both modes for Standard refund + IsvSources merchant
63
+ * variant. Probe-verified 2026-04-25 (F1): POST /checkout/v2/transactions/{id}
64
+ * returns 405, only the legacy host works for refunds.
65
+ */
66
+ export interface VivaCommonOptions {
67
+ /** Target environment. Switches Viva API base URL. */
68
+ environment: VivaEnvironment;
69
+ /**
70
+ * OAuth2 client_credentials — mode-agnostic.
71
+ * (The credential pair differs by Self Care location, but the field shape
72
+ * is the same in both modes.)
73
+ *
74
+ * @see references/viva-docs/md/oauth2-authentication.txt:119
75
+ */
76
+ clientId: string;
77
+ /** OAuth2 client_credentials — paired with `clientId`. */
78
+ clientSecret: string;
79
+ /**
80
+ * Viva Merchant ID (UUID) for the legacy Basic-auth API.
81
+ * Required for `createRefund` to work.
82
+ *
83
+ * @see references/viva-docs/md/merchant-id-and-api-key.txt:1
84
+ * @see references/viva-docs/md/tut-create-recurring-payment.txt:288
85
+ */
86
+ legacyMerchantId: string;
87
+ /**
88
+ * Viva API Key for the legacy Basic-auth API.
89
+ * Required for `createRefund` to work. Paired with `legacyMerchantId`.
90
+ *
91
+ * @see references/viva-docs/md/merchant-id-and-api-key.txt:1
92
+ */
93
+ legacyApiKey: string;
94
+ /**
95
+ * URL-verification key returned on Viva's GET probe at registration.
96
+ * NOT a per-request HMAC. Generated by `vendure-viva-register-webhooks` CLI.
97
+ */
98
+ webhookVerificationKey: string;
99
+ /**
100
+ * Storefront success URL after Smart Checkout completes.
101
+ * `{orderCode}` placeholder is substituted server-side after Viva returns the
102
+ * order code. `{channel.origin}` substitution is the SaaS's responsibility.
103
+ */
104
+ successUrl: string | ((ctx: VendureRequestContext) => string);
105
+ /**
106
+ * Storefront failure URL after Smart Checkout is cancelled or fails.
107
+ * Same substitution rules as `successUrl`.
108
+ */
109
+ failureUrl: string | ((ctx: VendureRequestContext) => string);
110
+ /**
111
+ * Refund strategy. Defaults to `'auto'`.
112
+ *
113
+ * 'auto' — pick fast or standard based on transaction state.
114
+ * 'fast' — POST /api/transactions/refund (fast/OAuth2 path).
115
+ * 'standard' — POST /api/transactions/{id} (legacy Basic auth).
116
+ */
117
+ refundStrategy?: 'auto' | 'fast' | 'standard';
118
+ /**
119
+ * Redlock client for multi-worker distributed semaphore.
120
+ * Default: in-process semaphore only (5 permits per merchantId).
121
+ */
122
+ redlock?: RedlockClient;
123
+ /**
124
+ * Structured logger. Default: Vendure's built-in logger (Logger from
125
+ * @sakeetech/viva-payments-core/observability).
126
+ */
127
+ logger?: Logger;
128
+ /**
129
+ * Metrics hook for Prometheus-style counters + histograms.
130
+ * Default: NoopMetricsHook.
131
+ */
132
+ metricsHook?: MetricsHook;
133
+ /**
134
+ * OpenTelemetry tracer hook.
135
+ * Default: NoopTracerHook (no-op).
136
+ */
137
+ tracer?: OTelTracerHook;
138
+ /**
139
+ * IP allowlist for webhook receiver.
140
+ * Default: Viva's published demo + production CIDRs.
141
+ */
142
+ webhookIpAllowlist?: string[];
143
+ /**
144
+ * How many trailing `X-Forwarded-For` hops are set by infrastructure you
145
+ * actually control. The webhook source-IP check walks the X-F-F chain from
146
+ * the **rightmost** end and picks the entry `trustedProxyDepth` from the
147
+ * end. Defaults to `0` — ignore X-F-F entirely and use the socket address,
148
+ * which is safe for direct exposure but rejects every webhook when a real
149
+ * proxy sits in front.
150
+ *
151
+ * Typical values:
152
+ * 0 — no proxy / direct exposure (default)
153
+ * 1 — one reverse proxy (nginx, Caddy, ALB)
154
+ * 2 — CDN in front of LB (e.g. Cloudflare → ALB)
155
+ *
156
+ * CSO Finding #2 (HIGH): leaving this at the implicit "trust leftmost X-F-F"
157
+ * default lets any client claim to be a whitelisted Viva IP.
158
+ *
159
+ * @see docs/TODO-CSO.md "Finding 2"
160
+ */
161
+ trustedProxyDepth?: number;
162
+ }
163
+ /**
164
+ * Merchant-mode config. Used when the plugin acts on behalf of a single
165
+ * direct Viva merchant account (no reseller hierarchy).
166
+ *
167
+ * NOTE (slice A, v0.2.0): runtime entry points (createPayment, settlePayment,
168
+ * cancelPayment, createRefund) currently throw `VIVA_MODE_MISMATCH` —
169
+ * merchant-mode handlers ship in Phase 3 slice B.
170
+ */
171
+ export interface VivaMerchantOptions extends VivaCommonOptions {
172
+ mode: 'merchant';
173
+ /**
174
+ * Optional Smart Checkout sourceCode. Defaults to `'Default'` when unset.
175
+ *
176
+ * @see references/viva-docs/md/payment-source-for-isv.txt:101
177
+ */
178
+ sourceCode?: string;
179
+ /**
180
+ * Optional hex color (no leading `#`) for Smart Checkout theming.
181
+ * Appended as `&color=<value>` to the Smart Checkout redirect URL.
182
+ */
183
+ checkoutColor?: string;
184
+ }
185
+ /**
186
+ * ISV-mode config. Used when the plugin acts on behalf of merchants under
187
+ * an ISV partner agreement. All per-tenant resolvers + onboarding fields
188
+ * live here.
189
+ */
190
+ export interface VivaIsvOptions extends VivaCommonOptions {
191
+ mode: 'isv';
192
+ /**
193
+ * Resolve the Viva merchantId UUID for the current channel.
194
+ * Default: reads `ctx.channel.customFields.vivaMerchantId`.
195
+ */
196
+ resolveMerchantId?: (ctx: VendureRequestContext) => string;
197
+ /**
198
+ * Resolve the Viva source code for the current channel.
199
+ * Default: reads `ctx.channel.customFields.vivaSourceCode ?? 'Default'`.
200
+ */
201
+ resolveSourceCode?: (ctx: VendureRequestContext) => string;
202
+ /**
203
+ * Resolve the ISV platform fee (in minor units) for an order.
204
+ * MUST return a value strictly less than the order total; plugin validates
205
+ * this and throws `VIVA_ISV_AMOUNT_TOO_HIGH` if violated.
206
+ * Default: `() => 0`.
207
+ */
208
+ resolveIsvAmount?: (order: VendureOrder, ctx: VendureRequestContext) => number;
209
+ /**
210
+ * Resolve an optional checkout theme color (hex string, no leading `#`).
211
+ * Appended as `&color=<value>` to the Smart Checkout redirect URL.
212
+ * Default: `() => undefined` (no color param).
213
+ */
214
+ resolveCheckoutColor?: (ctx: VendureRequestContext) => string | undefined;
215
+ /**
216
+ * Required by `POST /isv/v1/accounts` — the URL the merchant is sent back to
217
+ * after completing the Viva-hosted onboarding flow. Probe-verified 2026-05-11:
218
+ * the ISV API rejects the create call when this field is absent.
219
+ *
220
+ * The admin-onboarding controller falls back to the per-request `overrides.returnUrl`
221
+ * if a caller supplies one; otherwise this value is used.
222
+ */
223
+ onboardingReturnUrl: string | ((ctx: VendureRequestContext) => string);
224
+ /**
225
+ * Optional ISV branding shown on Viva's onboarding pages.
226
+ * When supplied, all three of `partnerName`, `logoUrl` (and optionally
227
+ * `primaryColor`) are passed verbatim to `POST /isv/v1/accounts`.
228
+ */
229
+ onboardingBranding?: {
230
+ partnerName: string;
231
+ logoUrl: string;
232
+ /** Hex code, e.g. `#1F2439`. */
233
+ primaryColor?: string;
234
+ };
235
+ /**
236
+ * Reseller Basic-auth — required only when the plugin will call
237
+ * POST /api/sources (IsvSources). All three fields are all-or-nothing.
238
+ *
239
+ * @see references/viva-docs/md/payment-isv-api.txt:1
240
+ */
241
+ reseller?: {
242
+ resellerId: string;
243
+ merchantId: string;
244
+ resellerApiKey: string;
245
+ };
246
+ }
247
+ /**
248
+ * Configuration passed to `VivaPaymentPlugin.init(options)`.
249
+ *
250
+ * Discriminated union on `mode`. See `VivaMerchantOptions` and `VivaIsvOptions`.
251
+ *
252
+ * @see docs/plans/multi-mode-v0.md §5, §10
253
+ */
254
+ export type VivaPaymentPluginOptions = VivaMerchantOptions | VivaIsvOptions;
255
+ /**
256
+ * Loose shape `VivaPaymentPlugin.init()` accepts before normalization.
257
+ *
258
+ * - `mode` is optional — defaults to `'merchant'` with a startup warning (or
259
+ * auto-detected as `'isv'` when ISV-only fields are present).
260
+ * - `clientId` / `clientSecret` may be replaced by their deprecated aliases
261
+ * `isvClientId` / `isvClientSecret` (one-minor back-compat, removal in 0.3.0).
262
+ *
263
+ * Callers may pass any mix of merchant + ISV fields here; `init()` validates +
264
+ * narrows to the strict `VivaPaymentPluginOptions` union.
265
+ */
266
+ export interface VivaPaymentPluginInitInput extends Partial<Omit<VivaCommonOptions, 'clientId' | 'clientSecret'>> {
267
+ mode?: VivaMode;
268
+ /** Preferred name (0.2.0+). */
269
+ clientId?: string;
270
+ /** Preferred name (0.2.0+). */
271
+ clientSecret?: string;
272
+ /** @deprecated Use `clientId`. Accepted for one minor (removal in 0.3.0). */
273
+ isvClientId?: string;
274
+ /** @deprecated Use `clientSecret`. Accepted for one minor (removal in 0.3.0). */
275
+ isvClientSecret?: string;
276
+ sourceCode?: string;
277
+ checkoutColor?: string;
278
+ resolveMerchantId?: (ctx: VendureRequestContext) => string;
279
+ resolveSourceCode?: (ctx: VendureRequestContext) => string;
280
+ resolveIsvAmount?: (order: VendureOrder, ctx: VendureRequestContext) => number;
281
+ resolveCheckoutColor?: (ctx: VendureRequestContext) => string | undefined;
282
+ onboardingReturnUrl?: string | ((ctx: VendureRequestContext) => string);
283
+ onboardingBranding?: VivaIsvOptions['onboardingBranding'];
284
+ reseller?: VivaIsvOptions['reseller'];
285
+ }
286
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,23 @@
1
+ /**
2
+ * types.ts — Public configuration types for VivaPaymentPlugin.
3
+ *
4
+ * v0.2.0: `VivaPaymentPluginOptions` is now a **discriminated union** on `mode`.
5
+ *
6
+ * - `mode: 'isv'` (default until 0.3.0) — multi-merchant ISV partner setup.
7
+ * - `mode: 'merchant'` — single direct Viva merchant, no reseller hierarchy.
8
+ *
9
+ * Field rename (one-minor back-compat):
10
+ * - `isvClientId` → `clientId` (old name accepted with deprecation warning)
11
+ * - `isvClientSecret` → `clientSecret`
12
+ *
13
+ * Plan ref: docs/plans/multi-mode-v0.md §5 (config shape), §10 (Vendure adapter).
14
+ *
15
+ * Vendure types (RequestContext, Order) are imported as peer-dep types only —
16
+ * no runtime Vendure import here so the types module is safe to import in
17
+ * non-Vendure test environments.
18
+ *
19
+ * viva-payments-core types are imported from sub-paths to avoid pulling in
20
+ * implementation code.
21
+ */
22
+ export {};
23
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * currency.ts — ISO 4217 alpha ↔ numeric conversion helpers.
3
+ *
4
+ * Viva's API requires numeric currency codes (e.g. 826 for GBP).
5
+ * Vendure stores alpha codes (e.g. 'GBP').
6
+ *
7
+ * @see references/viva-docs/md/wh-transaction-payment-created.txt:487
8
+ * @see docs/plans/vendure-plugin-v0.md §"Constraints" (Currency: Numeric ISO 4217)
9
+ */
10
+ import type { CurrencyCode } from '@sakeetech/viva-payments-core/types';
11
+ /**
12
+ * Convert ISO 4217 alpha code to branded numeric CurrencyCode.
13
+ * Throws if the alpha code is unknown.
14
+ *
15
+ * @example alphaToNumeric('GBP') // → '826' (branded CurrencyCode)
16
+ */
17
+ export declare function alphaToNumeric(alpha: string): CurrencyCode;
18
+ /**
19
+ * Convert ISO 4217 numeric string to alpha code.
20
+ * Coerces numeric input (string or number) defensively.
21
+ * Throws if the numeric code is unknown.
22
+ *
23
+ * @example numericToAlpha('826') // → 'GBP'
24
+ * @example numericToAlpha(826) // → 'GBP'
25
+ */
26
+ export declare function numericToAlpha(numeric: string | number): string;
27
+ /**
28
+ * Coerce a webhook payload currency value (may be string or number) to the
29
+ * branded CurrencyCode type. Throws on unknown code.
30
+ */
31
+ export declare function coerceCurrencyCode(raw: string | number): CurrencyCode;
32
+ //# sourceMappingURL=currency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"currency.d.ts","sourceRoot":"","sources":["../../src/util/currency.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AA8CxE;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAO1D;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAO/D;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,YAAY,CAMrE"}