@sakeetech/medusa-payment-viva 0.2.2

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 (171) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +816 -0
  3. package/dist/api/index.d.ts +15 -0
  4. package/dist/api/index.d.ts.map +1 -0
  5. package/dist/api/index.js +22 -0
  6. package/dist/api/index.js.map +1 -0
  7. package/dist/api/middlewares.d.ts +27 -0
  8. package/dist/api/middlewares.d.ts.map +1 -0
  9. package/dist/api/middlewares.js +62 -0
  10. package/dist/api/middlewares.js.map +1 -0
  11. package/dist/api/viva/admin/_admin-auth.d.ts +26 -0
  12. package/dist/api/viva/admin/_admin-auth.d.ts.map +1 -0
  13. package/dist/api/viva/admin/_admin-auth.js +49 -0
  14. package/dist/api/viva/admin/_admin-auth.js.map +1 -0
  15. package/dist/api/viva/admin/_mode-gate.d.ts +28 -0
  16. package/dist/api/viva/admin/_mode-gate.d.ts.map +1 -0
  17. package/dist/api/viva/admin/_mode-gate.js +45 -0
  18. package/dist/api/viva/admin/_mode-gate.js.map +1 -0
  19. package/dist/api/viva/admin/connected-accounts/[id]/reconcile/route.d.ts +21 -0
  20. package/dist/api/viva/admin/connected-accounts/[id]/reconcile/route.d.ts.map +1 -0
  21. package/dist/api/viva/admin/connected-accounts/[id]/reconcile/route.js +93 -0
  22. package/dist/api/viva/admin/connected-accounts/[id]/reconcile/route.js.map +1 -0
  23. package/dist/api/viva/admin/connected-accounts/[id]/route.d.ts +18 -0
  24. package/dist/api/viva/admin/connected-accounts/[id]/route.d.ts.map +1 -0
  25. package/dist/api/viva/admin/connected-accounts/[id]/route.js +59 -0
  26. package/dist/api/viva/admin/connected-accounts/[id]/route.js.map +1 -0
  27. package/dist/api/viva/admin/connected-accounts/[id]/sources/route.d.ts +34 -0
  28. package/dist/api/viva/admin/connected-accounts/[id]/sources/route.d.ts.map +1 -0
  29. package/dist/api/viva/admin/connected-accounts/[id]/sources/route.js +234 -0
  30. package/dist/api/viva/admin/connected-accounts/[id]/sources/route.js.map +1 -0
  31. package/dist/api/viva/admin/connected-accounts/route.d.ts +19 -0
  32. package/dist/api/viva/admin/connected-accounts/route.d.ts.map +1 -0
  33. package/dist/api/viva/admin/connected-accounts/route.js +78 -0
  34. package/dist/api/viva/admin/connected-accounts/route.js.map +1 -0
  35. package/dist/api/viva/internal/auth-status/route.d.ts +19 -0
  36. package/dist/api/viva/internal/auth-status/route.d.ts.map +1 -0
  37. package/dist/api/viva/internal/auth-status/route.js +91 -0
  38. package/dist/api/viva/internal/auth-status/route.js.map +1 -0
  39. package/dist/api/viva/internal/metrics/route.d.ts +13 -0
  40. package/dist/api/viva/internal/metrics/route.d.ts.map +1 -0
  41. package/dist/api/viva/internal/metrics/route.js +48 -0
  42. package/dist/api/viva/internal/metrics/route.js.map +1 -0
  43. package/dist/api/viva/webhook/health/route.d.ts +16 -0
  44. package/dist/api/viva/webhook/health/route.d.ts.map +1 -0
  45. package/dist/api/viva/webhook/health/route.js +27 -0
  46. package/dist/api/viva/webhook/health/route.js.map +1 -0
  47. package/dist/api/viva/webhook/route.d.ts +57 -0
  48. package/dist/api/viva/webhook/route.d.ts.map +1 -0
  49. package/dist/api/viva/webhook/route.js +269 -0
  50. package/dist/api/viva/webhook/route.js.map +1 -0
  51. package/dist/cli/bin.d.ts +12 -0
  52. package/dist/cli/bin.d.ts.map +1 -0
  53. package/dist/cli/bin.js +78 -0
  54. package/dist/cli/bin.js.map +1 -0
  55. package/dist/cli/index.d.ts +12 -0
  56. package/dist/cli/index.d.ts.map +1 -0
  57. package/dist/cli/index.js +14 -0
  58. package/dist/cli/index.js.map +1 -0
  59. package/dist/cli/plan.d.ts +51 -0
  60. package/dist/cli/plan.d.ts.map +1 -0
  61. package/dist/cli/plan.js +128 -0
  62. package/dist/cli/plan.js.map +1 -0
  63. package/dist/cli/register-webhooks.d.ts +54 -0
  64. package/dist/cli/register-webhooks.d.ts.map +1 -0
  65. package/dist/cli/register-webhooks.js +366 -0
  66. package/dist/cli/register-webhooks.js.map +1 -0
  67. package/dist/cli/types.d.ts +62 -0
  68. package/dist/cli/types.d.ts.map +1 -0
  69. package/dist/cli/types.js +12 -0
  70. package/dist/cli/types.js.map +1 -0
  71. package/dist/config.d.ts +158 -0
  72. package/dist/config.d.ts.map +1 -0
  73. package/dist/config.js +236 -0
  74. package/dist/config.js.map +1 -0
  75. package/dist/index.d.ts +21 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +29 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/loaders/viva-oauth2-strategy.d.ts +26 -0
  80. package/dist/loaders/viva-oauth2-strategy.d.ts.map +1 -0
  81. package/dist/loaders/viva-oauth2-strategy.js +58 -0
  82. package/dist/loaders/viva-oauth2-strategy.js.map +1 -0
  83. package/dist/migrations/Migration_20260425000001_init_viva_payments.d.ts +19 -0
  84. package/dist/migrations/Migration_20260425000001_init_viva_payments.d.ts.map +1 -0
  85. package/dist/migrations/Migration_20260425000001_init_viva_payments.js +136 -0
  86. package/dist/migrations/Migration_20260425000001_init_viva_payments.js.map +1 -0
  87. package/dist/migrations/Migration_20260425000002_allow_null_order_code.d.ts +31 -0
  88. package/dist/migrations/Migration_20260425000002_allow_null_order_code.d.ts.map +1 -0
  89. package/dist/migrations/Migration_20260425000002_allow_null_order_code.js +71 -0
  90. package/dist/migrations/Migration_20260425000002_allow_null_order_code.js.map +1 -0
  91. package/dist/migrations/Migration_20260425000003_webhook_retry_count.d.ts +18 -0
  92. package/dist/migrations/Migration_20260425000003_webhook_retry_count.d.ts.map +1 -0
  93. package/dist/migrations/Migration_20260425000003_webhook_retry_count.js +42 -0
  94. package/dist/migrations/Migration_20260425000003_webhook_retry_count.js.map +1 -0
  95. package/dist/migrations/Migration_20260425000004_webhook_error_and_nullable_merchant.d.ts +29 -0
  96. package/dist/migrations/Migration_20260425000004_webhook_error_and_nullable_merchant.d.ts.map +1 -0
  97. package/dist/migrations/Migration_20260425000004_webhook_error_and_nullable_merchant.js +74 -0
  98. package/dist/migrations/Migration_20260425000004_webhook_error_and_nullable_merchant.js.map +1 -0
  99. package/dist/models/index.d.ts +7 -0
  100. package/dist/models/index.d.ts.map +1 -0
  101. package/dist/models/index.js +10 -0
  102. package/dist/models/index.js.map +1 -0
  103. package/dist/models/viva-tenant-merchant.d.ts +11 -0
  104. package/dist/models/viva-tenant-merchant.d.ts.map +1 -0
  105. package/dist/models/viva-tenant-merchant.js +54 -0
  106. package/dist/models/viva-tenant-merchant.js.map +1 -0
  107. package/dist/models/viva-transaction.d.ts +34 -0
  108. package/dist/models/viva-transaction.d.ts.map +1 -0
  109. package/dist/models/viva-transaction.js +104 -0
  110. package/dist/models/viva-transaction.js.map +1 -0
  111. package/dist/models/viva-webhook-event.d.ts +32 -0
  112. package/dist/models/viva-webhook-event.d.ts.map +1 -0
  113. package/dist/models/viva-webhook-event.js +88 -0
  114. package/dist/models/viva-webhook-event.js.map +1 -0
  115. package/dist/observability/config.d.ts +34 -0
  116. package/dist/observability/config.d.ts.map +1 -0
  117. package/dist/observability/config.js +57 -0
  118. package/dist/observability/config.js.map +1 -0
  119. package/dist/observability/index.d.ts +8 -0
  120. package/dist/observability/index.d.ts.map +1 -0
  121. package/dist/observability/index.js +15 -0
  122. package/dist/observability/index.js.map +1 -0
  123. package/dist/observability/prom-metrics.d.ts +41 -0
  124. package/dist/observability/prom-metrics.d.ts.map +1 -0
  125. package/dist/observability/prom-metrics.js +219 -0
  126. package/dist/observability/prom-metrics.js.map +1 -0
  127. package/dist/providers/payment-provider.d.ts +19 -0
  128. package/dist/providers/payment-provider.d.ts.map +1 -0
  129. package/dist/providers/payment-provider.js +24 -0
  130. package/dist/providers/payment-provider.js.map +1 -0
  131. package/dist/resolvers/auth-strategy-factory.d.ts +42 -0
  132. package/dist/resolvers/auth-strategy-factory.d.ts.map +1 -0
  133. package/dist/resolvers/auth-strategy-factory.js +60 -0
  134. package/dist/resolvers/auth-strategy-factory.js.map +1 -0
  135. package/dist/resolvers/tenant-resolver.d.ts +104 -0
  136. package/dist/resolvers/tenant-resolver.d.ts.map +1 -0
  137. package/dist/resolvers/tenant-resolver.js +118 -0
  138. package/dist/resolvers/tenant-resolver.js.map +1 -0
  139. package/dist/service.d.ts +200 -0
  140. package/dist/service.d.ts.map +1 -0
  141. package/dist/service.js +1003 -0
  142. package/dist/service.js.map +1 -0
  143. package/dist/subscribers/index.d.ts +5 -0
  144. package/dist/subscribers/index.d.ts.map +1 -0
  145. package/dist/subscribers/index.js +10 -0
  146. package/dist/subscribers/index.js.map +1 -0
  147. package/dist/subscribers/viva-webhook-event.d.ts +38 -0
  148. package/dist/subscribers/viva-webhook-event.d.ts.map +1 -0
  149. package/dist/subscribers/viva-webhook-event.js +133 -0
  150. package/dist/subscribers/viva-webhook-event.js.map +1 -0
  151. package/dist/workflows/cleanup-old-webhook-events.d.ts +39 -0
  152. package/dist/workflows/cleanup-old-webhook-events.d.ts.map +1 -0
  153. package/dist/workflows/cleanup-old-webhook-events.js +68 -0
  154. package/dist/workflows/cleanup-old-webhook-events.js.map +1 -0
  155. package/dist/workflows/index.d.ts +14 -0
  156. package/dist/workflows/index.d.ts.map +1 -0
  157. package/dist/workflows/index.js +19 -0
  158. package/dist/workflows/index.js.map +1 -0
  159. package/dist/workflows/per-tenant-semaphore.d.ts +47 -0
  160. package/dist/workflows/per-tenant-semaphore.d.ts.map +1 -0
  161. package/dist/workflows/per-tenant-semaphore.js +89 -0
  162. package/dist/workflows/per-tenant-semaphore.js.map +1 -0
  163. package/dist/workflows/process-webhook-event.d.ts +80 -0
  164. package/dist/workflows/process-webhook-event.d.ts.map +1 -0
  165. package/dist/workflows/process-webhook-event.js +280 -0
  166. package/dist/workflows/process-webhook-event.js.map +1 -0
  167. package/dist/workflows/reprocess-unresolved-tenants.d.ts +58 -0
  168. package/dist/workflows/reprocess-unresolved-tenants.d.ts.map +1 -0
  169. package/dist/workflows/reprocess-unresolved-tenants.js +121 -0
  170. package/dist/workflows/reprocess-unresolved-tenants.js.map +1 -0
  171. package/package.json +63 -0
@@ -0,0 +1,19 @@
1
+ /**
2
+ * providers/payment-provider.ts — Medusa v2 module provider definition.
3
+ *
4
+ * Exports the ModuleProvider wiring for the Viva payment provider.
5
+ * Use `ModuleProvider(Modules.PAYMENT, { services })` per Medusa v2 docs.
6
+ *
7
+ * Registration in medusa-config.ts:
8
+ * {
9
+ * resolve: "medusa-payment-viva",
10
+ * id: "viva",
11
+ * options: { config: loadConfigFromEnv() }
12
+ * }
13
+ *
14
+ * @see https://docs.medusajs.com/resources/references/payment/provider#3-create-module-provider-definition-file
15
+ * @see references/viva-docs/md/isv-partner-program.txt:104
16
+ */
17
+ declare const _default: import("@medusajs/types").ModuleProviderExports;
18
+ export default _default;
19
+ //# sourceMappingURL=payment-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payment-provider.d.ts","sourceRoot":"","sources":["../../src/providers/payment-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;;AAKH,wBAEG"}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ /**
3
+ * providers/payment-provider.ts — Medusa v2 module provider definition.
4
+ *
5
+ * Exports the ModuleProvider wiring for the Viva payment provider.
6
+ * Use `ModuleProvider(Modules.PAYMENT, { services })` per Medusa v2 docs.
7
+ *
8
+ * Registration in medusa-config.ts:
9
+ * {
10
+ * resolve: "medusa-payment-viva",
11
+ * id: "viva",
12
+ * options: { config: loadConfigFromEnv() }
13
+ * }
14
+ *
15
+ * @see https://docs.medusajs.com/resources/references/payment/provider#3-create-module-provider-definition-file
16
+ * @see references/viva-docs/md/isv-partner-program.txt:104
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ const utils_1 = require("@medusajs/framework/utils");
20
+ const service_js_1 = require("../service.js");
21
+ exports.default = (0, utils_1.ModuleProvider)(utils_1.Modules.PAYMENT, {
22
+ services: [service_js_1.VivaPaymentProvider],
23
+ });
24
+ //# sourceMappingURL=payment-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"payment-provider.js","sourceRoot":"","sources":["../../src/providers/payment-provider.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;AAEH,qDAAoE;AACpE,8CAAoD;AAEpD,kBAAe,IAAA,sBAAc,EAAC,eAAO,CAAC,OAAO,EAAE;IAC7C,QAAQ,EAAE,CAAC,gCAAmB,CAAC;CAChC,CAAC,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * auth-strategy-factory.ts — builds AuthStrategy instances from VivaPluginConfig.
3
+ *
4
+ * Constructs OAuth2ClientCredentialsStrategy with:
5
+ * - InMemoryTokenCache + AsyncMutex (single-worker default, plan P11)
6
+ * - Redis lock when config.redis is provided (multi-worker, plan P11)
7
+ *
8
+ * Builds ResellerBasicAuthStrategy only when `config.mode === 'isv'` and
9
+ * `config.reseller` is present (Q5 — some endpoints require reseller auth).
10
+ *
11
+ * @see references/viva-docs/md/oauth2-authentication.txt:119 (client_credentials)
12
+ * @see references/viva-docs/md/payment-isv-api.txt:1 (reseller credentials)
13
+ * @see references/viva-docs/md/isv-credentials.txt:107 (credential types)
14
+ */
15
+ import { OAuth2ClientCredentialsStrategy, ResellerBasicAuthStrategy } from '@sakeetech/viva-payments-core/auth';
16
+ import type { VivaPluginConfig } from '../config.js';
17
+ export interface AuthStrategySet {
18
+ /** Primary OAuth2 bearer strategy — used for all standard ISV API calls. */
19
+ primary: OAuth2ClientCredentialsStrategy;
20
+ /**
21
+ * Reseller basic-auth strategy — used for endpoints that require it (Q5).
22
+ * Absent if config.mode !== 'isv' or config.reseller is not configured.
23
+ *
24
+ * @see references/viva-docs/md/payment-isv-api.txt:1 (reseller auth)
25
+ */
26
+ reseller?: ResellerBasicAuthStrategy;
27
+ }
28
+ /**
29
+ * Builds the full AuthStrategySet from the plugin config.
30
+ *
31
+ * Token lifecycle:
32
+ * - InMemoryTokenCache is always created for the in-process cache.
33
+ * - AsyncMutex is always created for single-flight de-duplication.
34
+ * - If config.redis is provided, it is passed as `redisLock` to the
35
+ * OAuth2 strategy which prefers the Redis distributed lock over the
36
+ * in-process mutex (plan P11).
37
+ *
38
+ * @see references/viva-docs/md/oauth2-authentication.txt:128 (token endpoint)
39
+ * @see references/viva-docs/md/isv-credentials.txt:107 (auth strategies)
40
+ */
41
+ export declare function buildAuthStrategies(config: VivaPluginConfig): AuthStrategySet;
42
+ //# sourceMappingURL=auth-strategy-factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-strategy-factory.d.ts","sourceRoot":"","sources":["../../src/resolvers/auth-strategy-factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,+BAA+B,EAC/B,yBAAyB,EAG1B,MAAM,oCAAoC,CAAC;AAC5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAMrD,MAAM,WAAW,eAAe;IAC9B,4EAA4E;IAC5E,OAAO,EAAE,+BAA+B,CAAC;IACzC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,yBAAyB,CAAC;CACtC;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,gBAAgB,GAAG,eAAe,CA6B7E"}
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ /**
3
+ * auth-strategy-factory.ts — builds AuthStrategy instances from VivaPluginConfig.
4
+ *
5
+ * Constructs OAuth2ClientCredentialsStrategy with:
6
+ * - InMemoryTokenCache + AsyncMutex (single-worker default, plan P11)
7
+ * - Redis lock when config.redis is provided (multi-worker, plan P11)
8
+ *
9
+ * Builds ResellerBasicAuthStrategy only when `config.mode === 'isv'` and
10
+ * `config.reseller` is present (Q5 — some endpoints require reseller auth).
11
+ *
12
+ * @see references/viva-docs/md/oauth2-authentication.txt:119 (client_credentials)
13
+ * @see references/viva-docs/md/payment-isv-api.txt:1 (reseller credentials)
14
+ * @see references/viva-docs/md/isv-credentials.txt:107 (credential types)
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.buildAuthStrategies = buildAuthStrategies;
18
+ const auth_1 = require("@sakeetech/viva-payments-core/auth");
19
+ // ---------------------------------------------------------------------------
20
+ // Factory
21
+ // ---------------------------------------------------------------------------
22
+ /**
23
+ * Builds the full AuthStrategySet from the plugin config.
24
+ *
25
+ * Token lifecycle:
26
+ * - InMemoryTokenCache is always created for the in-process cache.
27
+ * - AsyncMutex is always created for single-flight de-duplication.
28
+ * - If config.redis is provided, it is passed as `redisLock` to the
29
+ * OAuth2 strategy which prefers the Redis distributed lock over the
30
+ * in-process mutex (plan P11).
31
+ *
32
+ * @see references/viva-docs/md/oauth2-authentication.txt:128 (token endpoint)
33
+ * @see references/viva-docs/md/isv-credentials.txt:107 (auth strategies)
34
+ */
35
+ function buildAuthStrategies(config) {
36
+ const cache = new auth_1.InMemoryTokenCache();
37
+ const mutex = new auth_1.AsyncMutex();
38
+ const primary = new auth_1.OAuth2ClientCredentialsStrategy({
39
+ environment: config.environment,
40
+ clientId: config.clientId,
41
+ clientSecret: config.clientSecret,
42
+ cache,
43
+ mutex,
44
+ ...(config.redis !== undefined ? { redisLock: config.redis } : {}),
45
+ });
46
+ // Reseller strategy is ISV-only. Type-narrowed via discriminant.
47
+ const resellerConfig = config.mode === 'isv' ? config.reseller : undefined;
48
+ const reseller = resellerConfig !== undefined
49
+ ? new auth_1.ResellerBasicAuthStrategy({
50
+ resellerId: resellerConfig.resellerId,
51
+ merchantId: resellerConfig.merchantId,
52
+ resellerApiKey: resellerConfig.resellerApiKey,
53
+ })
54
+ : undefined;
55
+ return {
56
+ primary,
57
+ ...(reseller !== undefined ? { reseller } : {}),
58
+ };
59
+ }
60
+ //# sourceMappingURL=auth-strategy-factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-strategy-factory.js","sourceRoot":"","sources":["../../src/resolvers/auth-strategy-factory.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;AA2CH,kDA6BC;AAtED,6DAK4C;AAmB5C,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;;;;;;;;;;GAYG;AACH,SAAgB,mBAAmB,CAAC,MAAwB;IAC1D,MAAM,KAAK,GAAG,IAAI,yBAAkB,EAAE,CAAC;IACvC,MAAM,KAAK,GAAG,IAAI,iBAAU,EAAE,CAAC;IAE/B,MAAM,OAAO,GAAG,IAAI,sCAA+B,CAAC;QAClD,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,KAAK;QACL,KAAK;QACL,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACnE,CAAC,CAAC;IAEH,iEAAiE;IACjE,MAAM,cAAc,GAClB,MAAM,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IACtD,MAAM,QAAQ,GACZ,cAAc,KAAK,SAAS;QAC1B,CAAC,CAAC,IAAI,gCAAyB,CAAC;YAC5B,UAAU,EAAE,cAAc,CAAC,UAAU;YACrC,UAAU,EAAE,cAAc,CAAC,UAAU;YACrC,cAAc,EAAE,cAAc,CAAC,cAAc;SAC9C,CAAC;QACJ,CAAC,CAAC,SAAS,CAAC;IAEhB,OAAO;QACL,OAAO;QACP,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * tenant-resolver.ts — Cart-to-tenant resolution for multi-tenant ISV routing.
3
+ *
4
+ * Every payment in the ISV model must be scoped to a single Viva merchant.
5
+ * This module resolves a Medusa cart to its tenant's Viva credentials by:
6
+ * 1. Reading `cart.metadata.tenant_id` (default strategy) or delegating to
7
+ * a custom resolver injected via VivaPluginConfig.
8
+ * 2. Looking up `viva_tenant_merchant` in the plugin DB to get
9
+ * `{connected_account_id, viva_merchant_id}`.
10
+ *
11
+ * P19 invariant: `assertSingleTenantCart` is called before any network I/O
12
+ * to reject multi-tenant carts early (Marketplace mode is deferred, see P3).
13
+ *
14
+ * @see references/viva-docs/md/isv-partner-program.txt:61 (P1 merchant scoping)
15
+ * @see references/viva-docs/md/payment-isv-api.txt:1 (merchantId query param)
16
+ */
17
+ import type { EntityManager } from '@medusajs/framework/mikro-orm/core';
18
+ import type { ConnectedAccountId, MerchantId } from '@sakeetech/viva-payments-core/types';
19
+ export interface CartLike {
20
+ id: string;
21
+ metadata?: Record<string, unknown> | null;
22
+ items?: Array<{
23
+ metadata?: Record<string, unknown> | null;
24
+ }>;
25
+ }
26
+ /**
27
+ * Resolves a Medusa cart to its Viva tenant + account credentials.
28
+ *
29
+ * Custom implementations may inspect cart items, metadata, or an external
30
+ * mapping service. The plugin ships `DefaultTenantResolver` which reads
31
+ * `cart.metadata.tenant_id`.
32
+ *
33
+ * @see references/viva-docs/md/isv-partner-program.txt:61 (P5 tenant→account mapping)
34
+ */
35
+ export interface TenantResolver {
36
+ /**
37
+ * Extract the tenant identifier from a cart.
38
+ * Throws VivaValidationError if the tenant cannot be determined.
39
+ */
40
+ resolveTenantFromCart(cart: CartLike): Promise<{
41
+ tenantId: string;
42
+ }>;
43
+ /**
44
+ * Look up the Viva account credentials for a tenant.
45
+ * Throws VivaValidationError if the tenant is not found.
46
+ */
47
+ resolveVivaAccount(tenantId: string): Promise<{
48
+ connectedAccountId: ConnectedAccountId;
49
+ vivaMerchantId: MerchantId;
50
+ }>;
51
+ }
52
+ /**
53
+ * Validates that a cart contains items from at most one tenant.
54
+ *
55
+ * Inspects each line item's `metadata.tenant_id`. If two distinct values are
56
+ * found, throws VivaValidationError with both tenant IDs in the message.
57
+ *
58
+ * Rationale: Multi-seller (Marketplace) split payments are explicitly out of
59
+ * scope for v1 (plan P3/P19). A payment must be scoped to a single merchant.
60
+ *
61
+ * Items without `metadata.tenant_id` are ignored here — the cart-level
62
+ * metadata is the authoritative tenant source via `resolveTenantFromCart`.
63
+ *
64
+ * @throws VivaValidationError if items contain two distinct tenant_id values.
65
+ *
66
+ * @see references/viva-docs/md/isv-partner-program.txt:61 (P19 invariant)
67
+ */
68
+ export declare function assertSingleTenantCart(cart: {
69
+ items?: Array<{
70
+ metadata?: Record<string, unknown> | null;
71
+ }>;
72
+ }): void;
73
+ /**
74
+ * Default resolver: reads `cart.metadata.tenant_id` (string).
75
+ * Looks up `viva_tenant_merchant` for the Viva account credentials.
76
+ *
77
+ * Inject a custom TenantResolver into VivaPaymentProviderOptions to override
78
+ * (e.g. if tenant_id is stored in an item's metadata or an external service).
79
+ *
80
+ * @see references/viva-docs/md/isv-partner-program.txt:61 (P5)
81
+ */
82
+ export declare class DefaultTenantResolver implements TenantResolver {
83
+ private readonly em;
84
+ constructor(em: EntityManager);
85
+ /**
86
+ * Reads `cart.metadata.tenant_id`. Throws VivaValidationError if absent.
87
+ *
88
+ * @see references/viva-docs/md/isv-partner-program.txt:61 (P5)
89
+ */
90
+ resolveTenantFromCart(cart: CartLike): Promise<{
91
+ tenantId: string;
92
+ }>;
93
+ /**
94
+ * Queries viva_tenant_merchant by tenant_id.
95
+ * Throws VivaValidationError if the tenant is not found.
96
+ *
97
+ * @see references/viva-docs/md/isv-partner-program.txt:61 (P5 tenant→account)
98
+ */
99
+ resolveVivaAccount(tenantId: string): Promise<{
100
+ connectedAccountId: ConnectedAccountId;
101
+ vivaMerchantId: MerchantId;
102
+ }>;
103
+ }
104
+ //# sourceMappingURL=tenant-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant-resolver.d.ts","sourceRoot":"","sources":["../../src/resolvers/tenant-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AAQ1F,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC1C,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;CAC9D;AAMD;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,qBAAqB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAErE;;;OAGG;IACH,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAC5C,kBAAkB,EAAE,kBAAkB,CAAC;QACvC,cAAc,EAAE,UAAU,CAAC;KAC5B,CAAC,CAAC;CACJ;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC3C,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;CAC9D,GAAG,IAAI,CAqBP;AAMD;;;;;;;;GAQG;AACH,qBAAa,qBAAsB,YAAW,cAAc;IAC9C,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,aAAa;IAE9C;;;;OAIG;IACG,qBAAqB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAc1E;;;;;OAKG;IACG,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAClD,kBAAkB,EAAE,kBAAkB,CAAC;QACvC,cAAc,EAAE,UAAU,CAAC;KAC5B,CAAC;CAiBH"}
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ /**
3
+ * tenant-resolver.ts — Cart-to-tenant resolution for multi-tenant ISV routing.
4
+ *
5
+ * Every payment in the ISV model must be scoped to a single Viva merchant.
6
+ * This module resolves a Medusa cart to its tenant's Viva credentials by:
7
+ * 1. Reading `cart.metadata.tenant_id` (default strategy) or delegating to
8
+ * a custom resolver injected via VivaPluginConfig.
9
+ * 2. Looking up `viva_tenant_merchant` in the plugin DB to get
10
+ * `{connected_account_id, viva_merchant_id}`.
11
+ *
12
+ * P19 invariant: `assertSingleTenantCart` is called before any network I/O
13
+ * to reject multi-tenant carts early (Marketplace mode is deferred, see P3).
14
+ *
15
+ * @see references/viva-docs/md/isv-partner-program.txt:61 (P1 merchant scoping)
16
+ * @see references/viva-docs/md/payment-isv-api.txt:1 (merchantId query param)
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.DefaultTenantResolver = void 0;
20
+ exports.assertSingleTenantCart = assertSingleTenantCart;
21
+ const errors_1 = require("@sakeetech/viva-payments-core/errors");
22
+ // ---------------------------------------------------------------------------
23
+ // P19: single-tenant cart invariant
24
+ // ---------------------------------------------------------------------------
25
+ /**
26
+ * Validates that a cart contains items from at most one tenant.
27
+ *
28
+ * Inspects each line item's `metadata.tenant_id`. If two distinct values are
29
+ * found, throws VivaValidationError with both tenant IDs in the message.
30
+ *
31
+ * Rationale: Multi-seller (Marketplace) split payments are explicitly out of
32
+ * scope for v1 (plan P3/P19). A payment must be scoped to a single merchant.
33
+ *
34
+ * Items without `metadata.tenant_id` are ignored here — the cart-level
35
+ * metadata is the authoritative tenant source via `resolveTenantFromCart`.
36
+ *
37
+ * @throws VivaValidationError if items contain two distinct tenant_id values.
38
+ *
39
+ * @see references/viva-docs/md/isv-partner-program.txt:61 (P19 invariant)
40
+ */
41
+ function assertSingleTenantCart(cart) {
42
+ if (!cart.items || cart.items.length === 0)
43
+ return;
44
+ const tenantIds = new Set();
45
+ for (const item of cart.items) {
46
+ const tenantId = item.metadata?.['tenant_id'];
47
+ if (typeof tenantId === 'string' && tenantId.length > 0) {
48
+ tenantIds.add(tenantId);
49
+ }
50
+ if (tenantIds.size >= 2)
51
+ break;
52
+ }
53
+ if (tenantIds.size >= 2) {
54
+ const [first, second] = [...tenantIds];
55
+ throw new errors_1.VivaValidationError({
56
+ message: `Cart contains items from multiple tenants: '${first ?? ''}' and '${second ?? ''}'. ` +
57
+ `Multi-tenant carts are not supported in v1 (plan P19). ` +
58
+ `Each cart must contain items from a single tenant.`,
59
+ });
60
+ }
61
+ }
62
+ // ---------------------------------------------------------------------------
63
+ // DefaultTenantResolver
64
+ // ---------------------------------------------------------------------------
65
+ /**
66
+ * Default resolver: reads `cart.metadata.tenant_id` (string).
67
+ * Looks up `viva_tenant_merchant` for the Viva account credentials.
68
+ *
69
+ * Inject a custom TenantResolver into VivaPaymentProviderOptions to override
70
+ * (e.g. if tenant_id is stored in an item's metadata or an external service).
71
+ *
72
+ * @see references/viva-docs/md/isv-partner-program.txt:61 (P5)
73
+ */
74
+ class DefaultTenantResolver {
75
+ em;
76
+ constructor(em) {
77
+ this.em = em;
78
+ }
79
+ /**
80
+ * Reads `cart.metadata.tenant_id`. Throws VivaValidationError if absent.
81
+ *
82
+ * @see references/viva-docs/md/isv-partner-program.txt:61 (P5)
83
+ */
84
+ async resolveTenantFromCart(cart) {
85
+ const tenantId = cart.metadata?.['tenant_id'];
86
+ if (typeof tenantId !== 'string' || tenantId.trim() === '') {
87
+ throw new errors_1.VivaValidationError({
88
+ message: `Cannot resolve tenant for cart '${cart.id}': ` +
89
+ `cart.metadata.tenant_id is missing or not a string. ` +
90
+ `Set cart.metadata.tenant_id to the tenant identifier, or ` +
91
+ `inject a custom TenantResolver via VivaPaymentProviderOptions.`,
92
+ });
93
+ }
94
+ return { tenantId: tenantId.trim() };
95
+ }
96
+ /**
97
+ * Queries viva_tenant_merchant by tenant_id.
98
+ * Throws VivaValidationError if the tenant is not found.
99
+ *
100
+ * @see references/viva-docs/md/isv-partner-program.txt:61 (P5 tenant→account)
101
+ */
102
+ async resolveVivaAccount(tenantId) {
103
+ const repo = this.em.getRepository('VivaTenantMerchant');
104
+ const record = await repo.findOne({ tenant_id: tenantId });
105
+ if (!record) {
106
+ throw new errors_1.VivaValidationError({
107
+ message: `Tenant '${tenantId}' is not registered in viva_tenant_merchant. ` +
108
+ `Onboard this tenant via the ISV partner flow before accepting payments.`,
109
+ });
110
+ }
111
+ return {
112
+ connectedAccountId: record.connected_account_id,
113
+ vivaMerchantId: record.viva_merchant_id,
114
+ };
115
+ }
116
+ }
117
+ exports.DefaultTenantResolver = DefaultTenantResolver;
118
+ //# sourceMappingURL=tenant-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant-resolver.js","sourceRoot":"","sources":["../../src/resolvers/tenant-resolver.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;;;AAmEH,wDAuBC;AAtFD,iEAA2E;AA2C3E,8EAA8E;AAC9E,oCAAoC;AACpC,8EAA8E;AAE9E;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,sBAAsB,CAAC,IAEtC;IACC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAEnD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IACpC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,CAAC;QAC9C,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxD,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC;QACD,IAAI,SAAS,CAAC,IAAI,IAAI,CAAC;YAAE,MAAM;IACjC,CAAC;IAED,IAAI,SAAS,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC;QACxB,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC;QACvC,MAAM,IAAI,4BAAmB,CAAC;YAC5B,OAAO,EACL,+CAA+C,KAAK,IAAI,EAAE,UAAU,MAAM,IAAI,EAAE,KAAK;gBACrF,yDAAyD;gBACzD,oDAAoD;SACvD,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E;;;;;;;;GAQG;AACH,MAAa,qBAAqB;IACH;IAA7B,YAA6B,EAAiB;QAAjB,OAAE,GAAF,EAAE,CAAe;IAAG,CAAC;IAElD;;;;OAIG;IACH,KAAK,CAAC,qBAAqB,CAAC,IAAc;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,CAAC;QAC9C,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC3D,MAAM,IAAI,4BAAmB,CAAC;gBAC5B,OAAO,EACL,mCAAmC,IAAI,CAAC,EAAE,KAAK;oBAC/C,sDAAsD;oBACtD,2DAA2D;oBAC3D,gEAAgE;aACnE,CAAC,CAAC;QACL,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;IACvC,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,kBAAkB,CAAC,QAAgB;QAIvC,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,aAAa,CAAqB,oBAAoB,CAAC,CAAC;QAC7E,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;QAE3D,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,4BAAmB,CAAC;gBAC5B,OAAO,EACL,WAAW,QAAQ,+CAA+C;oBAClE,yEAAyE;aAC5E,CAAC,CAAC;QACL,CAAC;QAED,OAAO;YACL,kBAAkB,EAAE,MAAM,CAAC,oBAA0C;YACrE,cAAc,EAAE,MAAM,CAAC,gBAA8B;SACtD,CAAC;IACJ,CAAC;CACF;AAhDD,sDAgDC"}
@@ -0,0 +1,200 @@
1
+ /**
2
+ * service.ts — VivaPaymentProvider (Medusa v2 AbstractPaymentProvider)
3
+ *
4
+ * Implements all required Medusa v2 payment provider methods, bridging the
5
+ * Medusa payment lifecycle to the Viva Wallet ISV Smart Checkout flow.
6
+ *
7
+ * Key design choices:
8
+ * - A4 (write-pending-first): INSERT into viva_transaction with status='initiated'
9
+ * and viva_order_code=NULL BEFORE calling Viva's createOrder API.
10
+ * - P14 (idempotency): deduplicate by idempotency_key = medusa_payment_id.
11
+ * - P18 (refund validation): validate amount <= captured - refunded before Viva API.
12
+ * - P19 (single-tenant invariant): assertSingleTenantCart before any DB write.
13
+ * - Error model (plan lines 339–344): wrap all Viva errors into MedusaError types.
14
+ *
15
+ * AbstractPaymentProvider required methods (read from @medusajs/utils dist):
16
+ * capturePayment, authorizePayment, cancelPayment, initiatePayment,
17
+ * deletePayment, getPaymentStatus, refundPayment, retrievePayment,
18
+ * updatePayment, getWebhookActionAndData
19
+ *
20
+ * Smart Checkout redirect URL:
21
+ * - Demo: https://demo.vivapayments.com/web/checkout?ref={OrderCode}
22
+ * - Production: https://www.vivapayments.com/web/checkout?ref={OrderCode}
23
+ *
24
+ * @see references/viva-docs/md/payment-isv-api.txt:1 (ISV API overview)
25
+ * @see references/viva-docs/md/smart-checkout-save-payment.txt:1 (redirect URL)
26
+ * @see references/viva-docs/md/tut-create-recurring-payment.txt:1 (checkout URL format)
27
+ * @see references/viva-docs/md/isv-partner-program.txt:61 (P14, P15, P18, P19, A4)
28
+ * @see references/viva-docs/md/isv-credentials.txt:107 (auth credential types)
29
+ * @see references/viva-docs/md/oauth2-authentication.txt:128 (token endpoint)
30
+ */
31
+ import { AbstractPaymentProvider } from '@medusajs/framework/utils';
32
+ import type { InitiatePaymentInput, InitiatePaymentOutput, AuthorizePaymentInput, AuthorizePaymentOutput, CapturePaymentInput, CapturePaymentOutput, RefundPaymentInput, RefundPaymentOutput, CancelPaymentInput, CancelPaymentOutput, RetrievePaymentInput, RetrievePaymentOutput, GetPaymentStatusInput, GetPaymentStatusOutput, DeletePaymentInput, DeletePaymentOutput, UpdatePaymentInput, UpdatePaymentOutput, ProviderWebhookPayload, WebhookActionResult } from '@medusajs/framework/types';
33
+ import type { EntityManager } from '@medusajs/framework/mikro-orm/core';
34
+ import { Payments } from '@sakeetech/viva-payments-core/payments';
35
+ import { BasicAuthClient } from '@sakeetech/viva-payments-core/legacy';
36
+ import { FastRefundClient } from '@sakeetech/viva-payments-core/refunds';
37
+ import type { MinorUnits, TransactionId } from '@sakeetech/viva-payments-core/types';
38
+ import type { VivaPluginConfig } from './config.js';
39
+ import type { TenantResolver } from './resolvers/tenant-resolver.js';
40
+ export interface VivaPaymentProviderOptions {
41
+ config: VivaPluginConfig;
42
+ /**
43
+ * Injected tenant resolver. Defaults to DefaultTenantResolver which reads
44
+ * `cart.metadata.tenant_id`.
45
+ *
46
+ * @see references/viva-docs/md/isv-partner-program.txt:61 (P5)
47
+ */
48
+ tenantResolver?: TenantResolver;
49
+ }
50
+ /**
51
+ * Medusa v2 payment provider for Viva Wallet Smart Checkout (ISV multi-tenant).
52
+ *
53
+ * Identifier: 'viva'. Payment provider ID format: pp_viva_<id>.
54
+ * The <id> comes from the `id` field in medusa-config.ts providers array.
55
+ *
56
+ * @see references/viva-docs/md/payment-isv-api.txt:1 (ISV payment creation)
57
+ * @see references/viva-docs/md/smart-checkout-save-payment.txt:1 (redirect URL)
58
+ * @see references/viva-docs/md/isv-partner-program.txt:61 (ISV overview)
59
+ */
60
+ export declare class VivaPaymentProvider extends AbstractPaymentProvider<VivaPaymentProviderOptions> {
61
+ static readonly identifier = "viva";
62
+ protected readonly vivaConfig: VivaPluginConfig;
63
+ protected readonly isvPayments: Payments;
64
+ protected readonly legacyClient: BasicAuthClient;
65
+ protected readonly fastRefundClient: FastRefundClient;
66
+ protected readonly tenantResolver: TenantResolver;
67
+ protected readonly em: EntityManager;
68
+ constructor(container: Record<string, unknown>, options: VivaPaymentProviderOptions);
69
+ /**
70
+ * Initiates a payment session (Medusa calls this when customer selects Viva):
71
+ * 1. P19: assert single-tenant cart (from input.context)
72
+ * 2. Resolve tenant → Viva merchant
73
+ * 3. P14 dedup: check for existing transaction by idempotency_key
74
+ * 4. A4 write-pending-first: INSERT transaction row BEFORE Viva API call
75
+ * 5. Call Viva createOrder
76
+ * 6. Update row with viva_order_code
77
+ * 7. Return redirect URL in data (storefront uses this to redirect customer)
78
+ *
79
+ * The medusa_payment_id is derived from input.context.idempotency_key (set by
80
+ * Medusa Payment Module) or generated per call.
81
+ *
82
+ * @see references/viva-docs/md/payment-isv-api.txt:1 (createOrder)
83
+ * @see references/viva-docs/md/smart-checkout-save-payment.txt:1 (redirect URL)
84
+ * @see references/viva-docs/md/isv-partner-program.txt:61 (P14, P19, A4)
85
+ */
86
+ initiatePayment(input: InitiatePaymentInput): Promise<InitiatePaymentOutput>;
87
+ /**
88
+ * Consults the DB for the latest transaction status.
89
+ * For Smart Checkout, authorization is off-band (redirect + webhook).
90
+ * Called during cart-completion; returns current DB status.
91
+ *
92
+ * @see references/viva-docs/md/payment-isv-api.txt:1 (Smart Checkout flow)
93
+ * @see references/viva-docs/md/isv-partner-program.txt:61 (P6 Smart Checkout)
94
+ */
95
+ authorizePayment(input: AuthorizePaymentInput): Promise<AuthorizePaymentOutput>;
96
+ /**
97
+ * Capture is implicit on Smart Checkout completion (1796 webhook).
98
+ * This method is idempotent: if already captured, returns success.
99
+ * If not yet captured, logs a warning and returns current state.
100
+ *
101
+ * NOTE: Do NOT call Viva's capture endpoint. Capture is automatic on
102
+ * Smart Checkout completion per Viva's ISV model.
103
+ *
104
+ * @see references/viva-docs/md/payment-isv-api.txt:1 (implicit capture)
105
+ * @see references/viva-docs/md/isv-partner-program.txt:61 (P6 Smart Checkout)
106
+ */
107
+ capturePayment(input: CapturePaymentInput): Promise<CapturePaymentOutput>;
108
+ /**
109
+ * Issues a full or partial refund via Viva ISV API.
110
+ *
111
+ * P18 validation: refundAmountMinor <= capturedAmount - alreadyRefunded.
112
+ * Auth: primary OAuth2 strategy (Q5 — if Viva rejects with 401/403, reseller
113
+ * auth may be required; log warning and re-raise for now).
114
+ * Partial refund: increments refunded_amount_minor; status stays 'captured'.
115
+ * Full refund: transitions status to 'refunded' via lattice.
116
+ *
117
+ * @see references/viva-docs/md/isv-partner-program.txt:296 (P18 refund, ISV fee reversal)
118
+ * @see references/viva-docs/md/payment-isv-api.txt:1 (refund endpoint)
119
+ */
120
+ refundPayment(input: RefundPaymentInput): Promise<RefundPaymentOutput>;
121
+ /**
122
+ * Merchant-mode refund routing — Fast vs Standard with auto-fallback.
123
+ *
124
+ * Flow:
125
+ * 1. retrieveTransaction → cardType (for refund-strategy decision).
126
+ * 2. resolveRefundStrategy(config.refundStrategy ?? 'auto', { cardType, CNP: true }).
127
+ * 3. If decision.kind === 'fast': call FastRefundClient.refund.
128
+ * - 403 + strategy === 'fast' → throw VivaApiError with vivaCode
129
+ * 'VIVA_FAST_REFUND_INELIGIBLE'.
130
+ * - 403 + strategy === 'auto' → fall through to Standard refund.
131
+ * - any other error → re-throw.
132
+ * 4. Otherwise call BasicAuthClient via Payments.refundPayment (Standard).
133
+ *
134
+ * Smart Checkout is always card-not-present (CNP), so `isCardNotPresent: true`.
135
+ *
136
+ * @see docs/ENDPOINTS.md §4
137
+ * @see docs/plans/multi-mode-v0.md §9
138
+ * @see references/payment-api.yaml:9255 (Fast Refund 403 semantics)
139
+ */
140
+ protected refundPaymentMerchantMode(params: {
141
+ vivaTransactionId: TransactionId;
142
+ refundAmountMinor: MinorUnits;
143
+ refundIdempotencyKey: string;
144
+ medusaRefundId: string;
145
+ }): Promise<void>;
146
+ /**
147
+ * Cancels a Viva order (valid for unpaid orders not yet captured).
148
+ * Idempotent: skip API call if already in terminal cancelled state.
149
+ * Apply lattice: authorized → cancelled (A9 path).
150
+ *
151
+ * @see references/viva-docs/md/payment-isv-api.txt:1 (cancelOrder)
152
+ * @see references/viva-docs/md/isv-partner-program.txt:61 (P18, A9)
153
+ */
154
+ cancelPayment(input: CancelPaymentInput): Promise<CancelPaymentOutput>;
155
+ /**
156
+ * Returns the serialized viva_transaction row for the given payment.
157
+ *
158
+ * @see references/viva-docs/md/isv-partner-program.txt:104
159
+ */
160
+ retrievePayment(input: RetrievePaymentInput): Promise<RetrievePaymentOutput>;
161
+ /**
162
+ * Returns the current Medusa-mapped payment status from the DB.
163
+ *
164
+ * @see references/viva-docs/md/isv-partner-program.txt:104
165
+ */
166
+ getPaymentStatus(input: GetPaymentStatusInput): Promise<GetPaymentStatusOutput>;
167
+ /**
168
+ * Logical-only deletion — does NOT delete the Viva transaction (audit trail).
169
+ * The viva_transaction row is preserved for forensics and idempotency replay.
170
+ *
171
+ * @see references/viva-docs/md/isv-partner-program.txt:104
172
+ */
173
+ deletePayment(input: DeletePaymentInput): Promise<DeletePaymentOutput>;
174
+ /**
175
+ * No-op for Smart Checkout: Viva orders cannot be updated after creation.
176
+ * If amount changes, caller should cancel and re-initiate.
177
+ *
178
+ * @see references/viva-docs/md/payment-isv-api.txt:1 (order immutability)
179
+ */
180
+ updatePayment(input: UpdatePaymentInput): Promise<UpdatePaymentOutput>;
181
+ /**
182
+ * Processes Viva webhook events received via the /viva/webhook route (S8).
183
+ * S8 routes the verified webhook payload here.
184
+ *
185
+ * Viva webhook event types in v1 scope:
186
+ * 1796 - Transaction Payment Created → action: 'captured'
187
+ * 1797 - Transaction Reversal Created → action: 'authorized' (refund)
188
+ * 1798 - Transaction Failed → action: 'failed'
189
+ * 4865 - Order Updated (cancellation) → action: 'canceled'
190
+ *
191
+ * NOTE: This is the minimal implementation for S6. The full webhook processing
192
+ * subscriber (status lattice updates, Retrieve Transaction API call per plan
193
+ * step 4.a) is implemented in S8.
194
+ *
195
+ * @see references/viva-docs/md/isv-partner-program.txt:104 (webhook flow)
196
+ * @see references/viva-docs/md/webhooks-for-payments.txt:248 (retrieve before update)
197
+ */
198
+ getWebhookActionAndData(data: ProviderWebhookPayload['payload']): Promise<WebhookActionResult>;
199
+ }
200
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}