@sakeetech/viva-payments-core 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 (203) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +413 -0
  3. package/dist/auth/http.d.ts +44 -0
  4. package/dist/auth/http.d.ts.map +1 -0
  5. package/dist/auth/http.js +80 -0
  6. package/dist/auth/http.js.map +1 -0
  7. package/dist/auth/index.d.ts +19 -0
  8. package/dist/auth/index.d.ts.map +1 -0
  9. package/dist/auth/index.js +18 -0
  10. package/dist/auth/index.js.map +1 -0
  11. package/dist/auth/oauth2-strategy.d.ts +117 -0
  12. package/dist/auth/oauth2-strategy.d.ts.map +1 -0
  13. package/dist/auth/oauth2-strategy.js +217 -0
  14. package/dist/auth/oauth2-strategy.js.map +1 -0
  15. package/dist/auth/reseller-strategy.d.ts +65 -0
  16. package/dist/auth/reseller-strategy.d.ts.map +1 -0
  17. package/dist/auth/reseller-strategy.js +68 -0
  18. package/dist/auth/reseller-strategy.js.map +1 -0
  19. package/dist/auth/single-flight.d.ts +81 -0
  20. package/dist/auth/single-flight.d.ts.map +1 -0
  21. package/dist/auth/single-flight.js +160 -0
  22. package/dist/auth/single-flight.js.map +1 -0
  23. package/dist/auth/token-cache.d.ts +50 -0
  24. package/dist/auth/token-cache.d.ts.map +1 -0
  25. package/dist/auth/token-cache.js +59 -0
  26. package/dist/auth/token-cache.js.map +1 -0
  27. package/dist/errors/api-error.d.ts +15 -0
  28. package/dist/errors/api-error.d.ts.map +1 -0
  29. package/dist/errors/api-error.js +18 -0
  30. package/dist/errors/api-error.js.map +1 -0
  31. package/dist/errors/auth-error.d.ts +14 -0
  32. package/dist/errors/auth-error.d.ts.map +1 -0
  33. package/dist/errors/auth-error.js +17 -0
  34. package/dist/errors/auth-error.js.map +1 -0
  35. package/dist/errors/base.d.ts +59 -0
  36. package/dist/errors/base.d.ts.map +1 -0
  37. package/dist/errors/base.js +51 -0
  38. package/dist/errors/base.js.map +1 -0
  39. package/dist/errors/index.d.ts +18 -0
  40. package/dist/errors/index.d.ts.map +1 -0
  41. package/dist/errors/index.js +16 -0
  42. package/dist/errors/index.js.map +1 -0
  43. package/dist/errors/mode-mismatch-error.d.ts +19 -0
  44. package/dist/errors/mode-mismatch-error.d.ts.map +1 -0
  45. package/dist/errors/mode-mismatch-error.js +22 -0
  46. package/dist/errors/mode-mismatch-error.js.map +1 -0
  47. package/dist/errors/rate-limit-error.d.ts +20 -0
  48. package/dist/errors/rate-limit-error.d.ts.map +1 -0
  49. package/dist/errors/rate-limit-error.js +20 -0
  50. package/dist/errors/rate-limit-error.js.map +1 -0
  51. package/dist/errors/validation-error.d.ts +14 -0
  52. package/dist/errors/validation-error.d.ts.map +1 -0
  53. package/dist/errors/validation-error.js +17 -0
  54. package/dist/errors/validation-error.js.map +1 -0
  55. package/dist/errors/webhook-error.d.ts +14 -0
  56. package/dist/errors/webhook-error.d.ts.map +1 -0
  57. package/dist/errors/webhook-error.js +17 -0
  58. package/dist/errors/webhook-error.js.map +1 -0
  59. package/dist/index.d.ts +15 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +15 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/isv/accounts.d.ts +38 -0
  64. package/dist/isv/accounts.d.ts.map +1 -0
  65. package/dist/isv/accounts.js +60 -0
  66. package/dist/isv/accounts.js.map +1 -0
  67. package/dist/isv/client.d.ts +187 -0
  68. package/dist/isv/client.d.ts.map +1 -0
  69. package/dist/isv/client.js +465 -0
  70. package/dist/isv/client.js.map +1 -0
  71. package/dist/isv/index.d.ts +52 -0
  72. package/dist/isv/index.d.ts.map +1 -0
  73. package/dist/isv/index.js +53 -0
  74. package/dist/isv/index.js.map +1 -0
  75. package/dist/isv/legacy-basic-client.d.ts +122 -0
  76. package/dist/isv/legacy-basic-client.d.ts.map +1 -0
  77. package/dist/isv/legacy-basic-client.js +281 -0
  78. package/dist/isv/legacy-basic-client.js.map +1 -0
  79. package/dist/isv/payments.d.ts +199 -0
  80. package/dist/isv/payments.d.ts.map +1 -0
  81. package/dist/isv/payments.js +385 -0
  82. package/dist/isv/payments.js.map +1 -0
  83. package/dist/isv/sources.d.ts +80 -0
  84. package/dist/isv/sources.d.ts.map +1 -0
  85. package/dist/isv/sources.js +112 -0
  86. package/dist/isv/sources.js.map +1 -0
  87. package/dist/isv/webhooks-api.d.ts +48 -0
  88. package/dist/isv/webhooks-api.d.ts.map +1 -0
  89. package/dist/isv/webhooks-api.js +66 -0
  90. package/dist/isv/webhooks-api.js.map +1 -0
  91. package/dist/legacy/client.d.ts +199 -0
  92. package/dist/legacy/client.d.ts.map +1 -0
  93. package/dist/legacy/client.js +351 -0
  94. package/dist/legacy/client.js.map +1 -0
  95. package/dist/legacy/index.d.ts +15 -0
  96. package/dist/legacy/index.d.ts.map +1 -0
  97. package/dist/legacy/index.js +14 -0
  98. package/dist/legacy/index.js.map +1 -0
  99. package/dist/observability/context.d.ts +30 -0
  100. package/dist/observability/context.d.ts.map +1 -0
  101. package/dist/observability/context.js +40 -0
  102. package/dist/observability/context.js.map +1 -0
  103. package/dist/observability/index.d.ts +15 -0
  104. package/dist/observability/index.d.ts.map +1 -0
  105. package/dist/observability/index.js +11 -0
  106. package/dist/observability/index.js.map +1 -0
  107. package/dist/observability/logger.d.ts +81 -0
  108. package/dist/observability/logger.d.ts.map +1 -0
  109. package/dist/observability/logger.js +127 -0
  110. package/dist/observability/logger.js.map +1 -0
  111. package/dist/observability/metrics.d.ts +37 -0
  112. package/dist/observability/metrics.d.ts.map +1 -0
  113. package/dist/observability/metrics.js +40 -0
  114. package/dist/observability/metrics.js.map +1 -0
  115. package/dist/observability/redact.d.ts +21 -0
  116. package/dist/observability/redact.d.ts.map +1 -0
  117. package/dist/observability/redact.js +72 -0
  118. package/dist/observability/redact.js.map +1 -0
  119. package/dist/observability/tracer.d.ts +25 -0
  120. package/dist/observability/tracer.d.ts.map +1 -0
  121. package/dist/observability/tracer.js +18 -0
  122. package/dist/observability/tracer.js.map +1 -0
  123. package/dist/payments/client.d.ts +247 -0
  124. package/dist/payments/client.d.ts.map +1 -0
  125. package/dist/payments/client.js +488 -0
  126. package/dist/payments/client.js.map +1 -0
  127. package/dist/payments/index.d.ts +14 -0
  128. package/dist/payments/index.d.ts.map +1 -0
  129. package/dist/payments/index.js +13 -0
  130. package/dist/payments/index.js.map +1 -0
  131. package/dist/refunds/fast-refund-client.d.ts +128 -0
  132. package/dist/refunds/fast-refund-client.d.ts.map +1 -0
  133. package/dist/refunds/fast-refund-client.js +138 -0
  134. package/dist/refunds/fast-refund-client.js.map +1 -0
  135. package/dist/refunds/index.d.ts +19 -0
  136. package/dist/refunds/index.d.ts.map +1 -0
  137. package/dist/refunds/index.js +17 -0
  138. package/dist/refunds/index.js.map +1 -0
  139. package/dist/refunds/strategy.d.ts +78 -0
  140. package/dist/refunds/strategy.d.ts.map +1 -0
  141. package/dist/refunds/strategy.js +75 -0
  142. package/dist/refunds/strategy.js.map +1 -0
  143. package/dist/types/auth.d.ts +80 -0
  144. package/dist/types/auth.d.ts.map +1 -0
  145. package/dist/types/auth.js +12 -0
  146. package/dist/types/auth.js.map +1 -0
  147. package/dist/types/card-types.d.ts +48 -0
  148. package/dist/types/card-types.d.ts.map +1 -0
  149. package/dist/types/card-types.js +62 -0
  150. package/dist/types/card-types.js.map +1 -0
  151. package/dist/types/common.d.ts +160 -0
  152. package/dist/types/common.d.ts.map +1 -0
  153. package/dist/types/common.js +70 -0
  154. package/dist/types/common.js.map +1 -0
  155. package/dist/types/index.d.ts +21 -0
  156. package/dist/types/index.d.ts.map +1 -0
  157. package/dist/types/index.js +21 -0
  158. package/dist/types/index.js.map +1 -0
  159. package/dist/types/isv-accounts.d.ts +109 -0
  160. package/dist/types/isv-accounts.d.ts.map +1 -0
  161. package/dist/types/isv-accounts.js +22 -0
  162. package/dist/types/isv-accounts.js.map +1 -0
  163. package/dist/types/isv-payments.d.ts +262 -0
  164. package/dist/types/isv-payments.d.ts.map +1 -0
  165. package/dist/types/isv-payments.js +19 -0
  166. package/dist/types/isv-payments.js.map +1 -0
  167. package/dist/types/status.d.ts +125 -0
  168. package/dist/types/status.d.ts.map +1 -0
  169. package/dist/types/status.js +19 -0
  170. package/dist/types/status.js.map +1 -0
  171. package/dist/types/webhook-events.d.ts +447 -0
  172. package/dist/types/webhook-events.d.ts.map +1 -0
  173. package/dist/types/webhook-events.js +76 -0
  174. package/dist/types/webhook-events.js.map +1 -0
  175. package/dist/webhooks/challenge-response.d.ts +28 -0
  176. package/dist/webhooks/challenge-response.d.ts.map +1 -0
  177. package/dist/webhooks/challenge-response.js +35 -0
  178. package/dist/webhooks/challenge-response.js.map +1 -0
  179. package/dist/webhooks/event-types.d.ts +44 -0
  180. package/dist/webhooks/event-types.d.ts.map +1 -0
  181. package/dist/webhooks/event-types.js +50 -0
  182. package/dist/webhooks/event-types.js.map +1 -0
  183. package/dist/webhooks/extract-client-ip.d.ts +40 -0
  184. package/dist/webhooks/extract-client-ip.d.ts.map +1 -0
  185. package/dist/webhooks/extract-client-ip.js +72 -0
  186. package/dist/webhooks/extract-client-ip.js.map +1 -0
  187. package/dist/webhooks/hmac-verify.d.ts +38 -0
  188. package/dist/webhooks/hmac-verify.d.ts.map +1 -0
  189. package/dist/webhooks/hmac-verify.js +92 -0
  190. package/dist/webhooks/hmac-verify.js.map +1 -0
  191. package/dist/webhooks/index.d.ts +19 -0
  192. package/dist/webhooks/index.d.ts.map +1 -0
  193. package/dist/webhooks/index.js +19 -0
  194. package/dist/webhooks/index.js.map +1 -0
  195. package/dist/webhooks/ip-allowlist.d.ts +59 -0
  196. package/dist/webhooks/ip-allowlist.d.ts.map +1 -0
  197. package/dist/webhooks/ip-allowlist.js +147 -0
  198. package/dist/webhooks/ip-allowlist.js.map +1 -0
  199. package/dist/webhooks/status-lattice.d.ts +72 -0
  200. package/dist/webhooks/status-lattice.d.ts.map +1 -0
  201. package/dist/webhooks/status-lattice.js +208 -0
  202. package/dist/webhooks/status-lattice.js.map +1 -0
  203. package/package.json +85 -0
@@ -0,0 +1,128 @@
1
+ /**
2
+ * FastRefundClient — Viva Fast Refund API (OAuth2 acquiring scopes).
3
+ *
4
+ * Wraps `POST /acquiring/v1/transactions/{transactionId}:fastrefund` on the
5
+ * v2 API surface. Requires an OAuth2 token with `acquiring` +
6
+ * `acquiring:transactions` scopes (see AUTH.md §3.2). Eligibility is
7
+ * server-enforced by Viva:
8
+ * - Visa / MasterCard / Maestro card schemes
9
+ * - E-commerce (card-not-present) transactions
10
+ * - Merchant must be approved by Viva sales for fast refunds
11
+ *
12
+ * If the merchant is not approved or the original transaction is not eligible,
13
+ * Viva returns HTTP 403. Callers are expected to catch the resulting
14
+ * `VivaApiError` and fall back to the standard (legacy) refund path. See
15
+ * {@link resolveRefundStrategy} for the upstream pure decision helper.
16
+ *
17
+ * Design notes:
18
+ * - Caller-driven fallback: this client never silently retries on a
19
+ * standard refund — caller decides whether to fall back.
20
+ * - Idempotent: `false`. POST is non-idempotent at the transport layer; no
21
+ * 4xx/5xx retries. Connection-level errors retry once (request never acked).
22
+ * - Mirrors the style of {@link BasicAuthClient.request} / Payments.refundPayment
23
+ * for validation, error handling, and JSDoc references.
24
+ *
25
+ * @see docs/ENDPOINTS.md §4 (Fast vs Standard refund matrix)
26
+ * @see docs/AUTH.md §3.2 (OAuth2 acquiring scopes)
27
+ * @see docs/plans/multi-mode-v0.md §8.5a (FastRefundClient class shape)
28
+ * @see docs/STATE-MACHINE.md §3.1 (card-scheme detection)
29
+ * @see references/payment-api.yaml:9255 (POST /acquiring/v1/transactions/{id}:fastrefund)
30
+ * @see references/payment-api.yaml:9268 (eligibility — Visa/MC/Maestro)
31
+ */
32
+ import type { IsvHttpClient } from '../isv/client.js';
33
+ import type { TransactionId, MinorUnits } from '../types/index.js';
34
+ export interface FastRefundClientConfig {
35
+ /**
36
+ * OAuth2 HTTP client whose underlying AuthStrategy yields a token with
37
+ * `acquiring` + `acquiring:transactions` scopes (see AUTH.md §3.2).
38
+ */
39
+ client: IsvHttpClient;
40
+ }
41
+ /**
42
+ * Input for {@link FastRefundClient.refund}.
43
+ *
44
+ * All fields are required — Fast Refund does not support a "full refund by
45
+ * omission" convention (unlike the legacy refund path). Pass the original
46
+ * transaction's full amount in minor units for a full refund.
47
+ */
48
+ export interface FastRefundRequest {
49
+ /** UUID of the ORIGINAL captured transaction to refund. */
50
+ transactionId: TransactionId;
51
+ /** Amount in integer minor units. Must be > 0. */
52
+ amount: MinorUnits;
53
+ /** Payment source code (Viva merchant source). Non-empty string. */
54
+ sourceCode: string;
55
+ /** Merchant-side reference for the refund. Non-empty string. */
56
+ merchantTrns: string;
57
+ /**
58
+ * Idempotency key. Forwarded as the `Idempotency-Key` HTTP header per the
59
+ * shared {@link IsvHttpClient} convention. Non-empty string.
60
+ *
61
+ * NOTE: Viva does not appear to deduplicate server-side (probe F2,
62
+ * 2026-04-25). Local dedup remains the authoritative mechanism. Header is
63
+ * retained for forward-compat.
64
+ */
65
+ idempotencyKey: string;
66
+ }
67
+ /**
68
+ * Response from {@link FastRefundClient.refund}.
69
+ *
70
+ * Field names are normalized to camelCase. Viva responds with a transaction
71
+ * envelope describing the REFUND transaction (a new transaction id, distinct
72
+ * from the original `transactionId` passed in the request).
73
+ *
74
+ * @see references/payment-api.yaml:9255
75
+ */
76
+ export interface FastRefundResponse {
77
+ /** The refund transaction's OWN id (not the original captured transaction). */
78
+ transactionId: TransactionId;
79
+ /** Viva event id correlated with the refund. */
80
+ eventId: number;
81
+ /** Refunded amount in minor units, as JSON number from Viva. */
82
+ amount: number;
83
+ }
84
+ /**
85
+ * Thin POST wrapper for the Viva Fast Refund endpoint.
86
+ *
87
+ * Eligibility (per Viva docs):
88
+ * - Visa / MasterCard / Maestro
89
+ * - E-commerce (card-not-present)
90
+ * - Merchant approved by Viva sales for Fast Refunds
91
+ *
92
+ * On 403 the caller should fall back to the standard refund flow
93
+ * (`Payments.refundPayment` via the legacy `BasicAuthClient`). The decision
94
+ * helper {@link resolveRefundStrategy} returns `auto-ineligible-*` reasons up
95
+ * front so most ineligible cases never reach the wire.
96
+ *
97
+ * @see references/payment-api.yaml:9255
98
+ * @see docs/ENDPOINTS.md §4
99
+ * @see docs/AUTH.md §3.2
100
+ */
101
+ export declare class FastRefundClient {
102
+ private readonly client;
103
+ constructor(config: FastRefundClientConfig);
104
+ /**
105
+ * POST `/acquiring/v1/transactions/{transactionId}:fastrefund`.
106
+ *
107
+ * Body: `{ amount, sourceCode, merchantTrns, idempotencyKey }` — no extra
108
+ * fields. Auth: OAuth2 Bearer (acquiring scopes) handled by the underlying
109
+ * {@link IsvHttpClient}.
110
+ *
111
+ * Local validation (throws VivaValidationError before HTTP call):
112
+ * - `amount` must be > 0 minor units
113
+ * - `sourceCode`, `merchantTrns`, `idempotencyKey` must be non-empty strings
114
+ *
115
+ * Errors:
116
+ * - 403 → VivaApiError. Caller decides whether to fall back to standard refund.
117
+ * - 404 → VivaApiError (transaction not found).
118
+ * - 422 → VivaApiError (invalid BIN / scheme).
119
+ * - 423 → VivaApiError (refund already in progress).
120
+ * - 452 → VivaApiError (insufficient funds for fast refund).
121
+ * - 5xx → VivaApiError (no retry — POST is non-idempotent).
122
+ *
123
+ * @see references/payment-api.yaml:9255
124
+ * @see docs/ERRORS.md §2 (error code matrix)
125
+ */
126
+ refund(input: FastRefundRequest): Promise<FastRefundResponse>;
127
+ }
128
+ //# sourceMappingURL=fast-refund-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fast-refund-client.d.ts","sourceRoot":"","sources":["../../src/refunds/fast-refund-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAOnE,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,MAAM,EAAE,aAAa,CAAC;CACvB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,2DAA2D;IAC3D,aAAa,EAAE,aAAa,CAAC;IAC7B,kDAAkD;IAClD,MAAM,EAAE,UAAU,CAAC;IACnB,oEAAoE;IACpE,UAAU,EAAE,MAAM,CAAC;IACnB,gEAAgE;IAChE,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,kBAAkB;IACjC,+EAA+E;IAC/E,aAAa,EAAE,aAAa,CAAC;IAC7B,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;CAChB;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;gBAE3B,MAAM,EAAE,sBAAsB;IAI1C;;;;;;;;;;;;;;;;;;;;;OAqBG;IACG,MAAM,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;CA0EpE"}
@@ -0,0 +1,138 @@
1
+ /**
2
+ * FastRefundClient — Viva Fast Refund API (OAuth2 acquiring scopes).
3
+ *
4
+ * Wraps `POST /acquiring/v1/transactions/{transactionId}:fastrefund` on the
5
+ * v2 API surface. Requires an OAuth2 token with `acquiring` +
6
+ * `acquiring:transactions` scopes (see AUTH.md §3.2). Eligibility is
7
+ * server-enforced by Viva:
8
+ * - Visa / MasterCard / Maestro card schemes
9
+ * - E-commerce (card-not-present) transactions
10
+ * - Merchant must be approved by Viva sales for fast refunds
11
+ *
12
+ * If the merchant is not approved or the original transaction is not eligible,
13
+ * Viva returns HTTP 403. Callers are expected to catch the resulting
14
+ * `VivaApiError` and fall back to the standard (legacy) refund path. See
15
+ * {@link resolveRefundStrategy} for the upstream pure decision helper.
16
+ *
17
+ * Design notes:
18
+ * - Caller-driven fallback: this client never silently retries on a
19
+ * standard refund — caller decides whether to fall back.
20
+ * - Idempotent: `false`. POST is non-idempotent at the transport layer; no
21
+ * 4xx/5xx retries. Connection-level errors retry once (request never acked).
22
+ * - Mirrors the style of {@link BasicAuthClient.request} / Payments.refundPayment
23
+ * for validation, error handling, and JSDoc references.
24
+ *
25
+ * @see docs/ENDPOINTS.md §4 (Fast vs Standard refund matrix)
26
+ * @see docs/AUTH.md §3.2 (OAuth2 acquiring scopes)
27
+ * @see docs/plans/multi-mode-v0.md §8.5a (FastRefundClient class shape)
28
+ * @see docs/STATE-MACHINE.md §3.1 (card-scheme detection)
29
+ * @see references/payment-api.yaml:9255 (POST /acquiring/v1/transactions/{id}:fastrefund)
30
+ * @see references/payment-api.yaml:9268 (eligibility — Visa/MC/Maestro)
31
+ */
32
+ import { VivaValidationError } from '../errors/index.js';
33
+ // ---------------------------------------------------------------------------
34
+ // FastRefundClient
35
+ // ---------------------------------------------------------------------------
36
+ /**
37
+ * Thin POST wrapper for the Viva Fast Refund endpoint.
38
+ *
39
+ * Eligibility (per Viva docs):
40
+ * - Visa / MasterCard / Maestro
41
+ * - E-commerce (card-not-present)
42
+ * - Merchant approved by Viva sales for Fast Refunds
43
+ *
44
+ * On 403 the caller should fall back to the standard refund flow
45
+ * (`Payments.refundPayment` via the legacy `BasicAuthClient`). The decision
46
+ * helper {@link resolveRefundStrategy} returns `auto-ineligible-*` reasons up
47
+ * front so most ineligible cases never reach the wire.
48
+ *
49
+ * @see references/payment-api.yaml:9255
50
+ * @see docs/ENDPOINTS.md §4
51
+ * @see docs/AUTH.md §3.2
52
+ */
53
+ export class FastRefundClient {
54
+ client;
55
+ constructor(config) {
56
+ this.client = config.client;
57
+ }
58
+ /**
59
+ * POST `/acquiring/v1/transactions/{transactionId}:fastrefund`.
60
+ *
61
+ * Body: `{ amount, sourceCode, merchantTrns, idempotencyKey }` — no extra
62
+ * fields. Auth: OAuth2 Bearer (acquiring scopes) handled by the underlying
63
+ * {@link IsvHttpClient}.
64
+ *
65
+ * Local validation (throws VivaValidationError before HTTP call):
66
+ * - `amount` must be > 0 minor units
67
+ * - `sourceCode`, `merchantTrns`, `idempotencyKey` must be non-empty strings
68
+ *
69
+ * Errors:
70
+ * - 403 → VivaApiError. Caller decides whether to fall back to standard refund.
71
+ * - 404 → VivaApiError (transaction not found).
72
+ * - 422 → VivaApiError (invalid BIN / scheme).
73
+ * - 423 → VivaApiError (refund already in progress).
74
+ * - 452 → VivaApiError (insufficient funds for fast refund).
75
+ * - 5xx → VivaApiError (no retry — POST is non-idempotent).
76
+ *
77
+ * @see references/payment-api.yaml:9255
78
+ * @see docs/ERRORS.md §2 (error code matrix)
79
+ */
80
+ async refund(input) {
81
+ // --- local validation (mirror style of Payments.refundPayment / createOrder) ---
82
+ if (input.amount <= 0n) {
83
+ throw new VivaValidationError({
84
+ message: `FastRefundClient.refund: amount must be > 0 minor units, got ${input.amount}`,
85
+ });
86
+ }
87
+ if (typeof input.sourceCode !== 'string' || input.sourceCode.length === 0) {
88
+ throw new VivaValidationError({
89
+ message: 'FastRefundClient.refund: sourceCode must be a non-empty string',
90
+ });
91
+ }
92
+ if (typeof input.merchantTrns !== 'string' || input.merchantTrns.length === 0) {
93
+ throw new VivaValidationError({
94
+ message: 'FastRefundClient.refund: merchantTrns must be a non-empty string',
95
+ });
96
+ }
97
+ if (typeof input.idempotencyKey !== 'string' || input.idempotencyKey.length === 0) {
98
+ throw new VivaValidationError({
99
+ message: 'FastRefundClient.refund: idempotencyKey must be a non-empty string',
100
+ });
101
+ }
102
+ if (typeof input.transactionId !== 'string' || input.transactionId.length === 0) {
103
+ throw new VivaValidationError({
104
+ message: 'FastRefundClient.refund: transactionId must be a non-empty string',
105
+ });
106
+ }
107
+ // URL-encode the transactionId so the path segment is safe even for ids
108
+ // that contain reserved characters (defensive — Viva UUIDs do not, but
109
+ // the type is a branded string so future ids could).
110
+ const encodedId = encodeURIComponent(input.transactionId);
111
+ const path = `/acquiring/v1/transactions/${encodedId}:fastrefund`;
112
+ // Wire body — exactly the four fields per spec. `amount` is bigint and
113
+ // is handled by the shared bigint-safe stringify in IsvHttpClient.
114
+ const body = {
115
+ amount: input.amount,
116
+ sourceCode: input.sourceCode,
117
+ merchantTrns: input.merchantTrns,
118
+ idempotencyKey: input.idempotencyKey,
119
+ };
120
+ const raw = await this.client.request({
121
+ method: 'POST',
122
+ path,
123
+ body,
124
+ idempotencyKey: input.idempotencyKey,
125
+ idempotent: false,
126
+ endpoint: 'POST /acquiring/v1/transactions/{transactionId}:fastrefund',
127
+ });
128
+ const refundTxId = (raw.transactionId ?? raw.TransactionId ?? '');
129
+ const eventId = (raw.eventId ?? raw.EventId ?? 0);
130
+ const amount = (raw.amount ?? raw.Amount ?? 0);
131
+ return {
132
+ transactionId: refundTxId,
133
+ eventId,
134
+ amount,
135
+ };
136
+ }
137
+ }
138
+ //# sourceMappingURL=fast-refund-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fast-refund-client.js","sourceRoot":"","sources":["../../src/refunds/fast-refund-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAIH,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AA2DzD,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,gBAAgB;IACV,MAAM,CAAgB;IAEvC,YAAY,MAA8B;QACxC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC9B,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,KAAK,CAAC,MAAM,CAAC,KAAwB;QACnC,kFAAkF;QAClF,IAAI,KAAK,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;YACvB,MAAM,IAAI,mBAAmB,CAAC;gBAC5B,OAAO,EAAE,gEAAgE,KAAK,CAAC,MAAM,EAAE;aACxF,CAAC,CAAC;QACL,CAAC;QACD,IAAI,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1E,MAAM,IAAI,mBAAmB,CAAC;gBAC5B,OAAO,EAAE,gEAAgE;aAC1E,CAAC,CAAC;QACL,CAAC;QACD,IAAI,OAAO,KAAK,CAAC,YAAY,KAAK,QAAQ,IAAI,KAAK,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9E,MAAM,IAAI,mBAAmB,CAAC;gBAC5B,OAAO,EAAE,kEAAkE;aAC5E,CAAC,CAAC;QACL,CAAC;QACD,IAAI,OAAO,KAAK,CAAC,cAAc,KAAK,QAAQ,IAAI,KAAK,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClF,MAAM,IAAI,mBAAmB,CAAC;gBAC5B,OAAO,EAAE,oEAAoE;aAC9E,CAAC,CAAC;QACL,CAAC;QACD,IAAI,OAAO,KAAK,CAAC,aAAa,KAAK,QAAQ,IAAI,KAAK,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChF,MAAM,IAAI,mBAAmB,CAAC;gBAC5B,OAAO,EAAE,mEAAmE;aAC7E,CAAC,CAAC;QACL,CAAC;QAED,wEAAwE;QACxE,uEAAuE;QACvE,qDAAqD;QACrD,MAAM,SAAS,GAAG,kBAAkB,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAC1D,MAAM,IAAI,GAAG,8BAA8B,SAAS,aAAa,CAAC;QAElE,uEAAuE;QACvE,mEAAmE;QACnE,MAAM,IAAI,GAAG;YACX,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,cAAc,EAAE,KAAK,CAAC,cAAc;SACrC,CAAC;QAcF,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAgB;YACnD,MAAM,EAAE,MAAM;YACd,IAAI;YACJ,IAAI;YACJ,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,4DAA4D;SACvE,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,aAAa,IAAI,GAAG,CAAC,aAAa,IAAI,EAAE,CAAkB,CAAC;QACnF,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,OAAO,IAAI,CAAC,CAAW,CAAC;QAC5D,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,CAAW,CAAC;QAEzD,OAAO;YACL,aAAa,EAAE,UAAU;YACzB,OAAO;YACP,MAAM;SACP,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * viva-payments-core/refunds — barrel export.
3
+ *
4
+ * Subpath: `@sakeetech/viva-payments-core/refunds`
5
+ *
6
+ * Public surface:
7
+ * - {@link FastRefundClient} — OAuth2 acquiring-scopes wrapper for
8
+ * `POST /acquiring/v1/transactions/{transactionId}:fastrefund`.
9
+ * - {@link resolveRefundStrategy} — pure decision function for the
10
+ * `auto | fast | standard` strategy resolver consumed by adapters.
11
+ *
12
+ * @see docs/plans/multi-mode-v0.md §8.5a
13
+ * @see docs/ENDPOINTS.md §4
14
+ */
15
+ export { FastRefundClient } from './fast-refund-client.js';
16
+ export type { FastRefundClientConfig, FastRefundRequest, FastRefundResponse, } from './fast-refund-client.js';
17
+ export { resolveRefundStrategy } from './strategy.js';
18
+ export type { RefundStrategy, RefundContext, RefundDecision } from './strategy.js';
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/refunds/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EACV,sBAAsB,EACtB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * viva-payments-core/refunds — barrel export.
3
+ *
4
+ * Subpath: `@sakeetech/viva-payments-core/refunds`
5
+ *
6
+ * Public surface:
7
+ * - {@link FastRefundClient} — OAuth2 acquiring-scopes wrapper for
8
+ * `POST /acquiring/v1/transactions/{transactionId}:fastrefund`.
9
+ * - {@link resolveRefundStrategy} — pure decision function for the
10
+ * `auto | fast | standard` strategy resolver consumed by adapters.
11
+ *
12
+ * @see docs/plans/multi-mode-v0.md §8.5a
13
+ * @see docs/ENDPOINTS.md §4
14
+ */
15
+ export { FastRefundClient } from './fast-refund-client.js';
16
+ export { resolveRefundStrategy } from './strategy.js';
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/refunds/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAO3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * resolveRefundStrategy — pure decision function for refund routing.
3
+ *
4
+ * Given a configured strategy (`auto` | `fast` | `standard`) and a refund
5
+ * context (card scheme + card-present flag), returns a {@link RefundDecision}
6
+ * describing which refund path to take and why. The caller (adapter refund
7
+ * handler) is responsible for executing the chosen path and — when the
8
+ * strategy is `auto` and Fast Refund returns 403 — falling back to standard.
9
+ *
10
+ * This is deliberately a pure function with no I/O so it is trivial to unit
11
+ * test and reuse from any adapter.
12
+ *
13
+ * @see docs/ENDPOINTS.md §4 (Fast vs Standard matrix)
14
+ * @see docs/STATE-MACHINE.md §3.1 (card scheme detection from retrieveTransaction)
15
+ * @see docs/plans/multi-mode-v0.md §8.5a
16
+ * @see references/payment-api.yaml:9268 (eligibility: Visa / MC / Maestro)
17
+ */
18
+ export type RefundStrategy = 'auto' | 'fast' | 'standard';
19
+ /**
20
+ * Refund context surfaced from the adapter refund handler.
21
+ *
22
+ * Populated from a prior `retrieveTransaction` call (for `cardType`) plus
23
+ * a flag from the originating payment session indicating whether the
24
+ * transaction was card-not-present (e-commerce / Smart Checkout) — which
25
+ * every plugin-initiated payment is.
26
+ */
27
+ export interface RefundContext {
28
+ /**
29
+ * `cardType` field from {@link RetrieveTransactionResponse}. Viva returns
30
+ * PascalCase scheme names: `'Visa' | 'MasterCard' | 'Maestro' | 'Amex' | ...`.
31
+ * Undefined when Viva omits the field (some non-card payment types).
32
+ *
33
+ * @see docs/STATE-MACHINE.md §3.1
34
+ */
35
+ cardType?: string;
36
+ /**
37
+ * Whether the original transaction was card-not-present (e-commerce).
38
+ * For plugin-initiated payments via Smart Checkout this is always `true`.
39
+ * Kept as an explicit input for future POS / in-store integrations where
40
+ * Fast Refund is not allowed.
41
+ */
42
+ isCardNotPresent: boolean;
43
+ }
44
+ /**
45
+ * Decision returned by {@link resolveRefundStrategy}.
46
+ *
47
+ * `kind` selects the path; `reason` is a stable, machine-readable explanation
48
+ * suitable for structured logging and observability dashboards. The set of
49
+ * reason strings is a closed enum — extend only with explicit plan review.
50
+ */
51
+ export type RefundDecision = {
52
+ kind: 'fast';
53
+ reason: 'configured' | 'auto-eligible';
54
+ } | {
55
+ kind: 'standard';
56
+ reason: 'configured' | 'auto-ineligible-scheme' | 'auto-ineligible-card-present' | 'auto-no-card-info';
57
+ };
58
+ /**
59
+ * Pure decision function. Does not perform any I/O.
60
+ *
61
+ * Behaviour:
62
+ * - `strategy === 'fast'` → always `{ kind: 'fast', reason: 'configured' }`.
63
+ * Caller has explicitly opted in; eligibility is enforced server-side.
64
+ * - `strategy === 'standard'` → always `{ kind: 'standard', reason: 'configured' }`.
65
+ * - `strategy === 'auto'` → decided from {@link RefundContext}:
66
+ * - card-present → standard (`auto-ineligible-card-present`)
67
+ * - undefined cardType → standard (`auto-no-card-info`)
68
+ * - eligible scheme + CNP → fast (`auto-eligible`)
69
+ * - non-eligible scheme + CNP → standard (`auto-ineligible-scheme`)
70
+ *
71
+ * On Fast Refund 403 the caller should still fall back to standard refund —
72
+ * this function only handles the pre-call decision, not server-side rejection.
73
+ *
74
+ * @see docs/ENDPOINTS.md §4
75
+ * @see references/payment-api.yaml:9268
76
+ */
77
+ export declare function resolveRefundStrategy(strategy: RefundStrategy, ctx: RefundContext): RefundDecision;
78
+ //# sourceMappingURL=strategy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategy.d.ts","sourceRoot":"","sources":["../../src/refunds/strategy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;AAmB1D;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,YAAY,GAAG,eAAe,CAAA;CAAE,GACxD;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EACF,YAAY,GACZ,wBAAwB,GACxB,8BAA8B,GAC9B,mBAAmB,CAAC;CACzB,CAAC;AAMN;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,cAAc,EACxB,GAAG,EAAE,aAAa,GACjB,cAAc,CAkBhB"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * resolveRefundStrategy — pure decision function for refund routing.
3
+ *
4
+ * Given a configured strategy (`auto` | `fast` | `standard`) and a refund
5
+ * context (card scheme + card-present flag), returns a {@link RefundDecision}
6
+ * describing which refund path to take and why. The caller (adapter refund
7
+ * handler) is responsible for executing the chosen path and — when the
8
+ * strategy is `auto` and Fast Refund returns 403 — falling back to standard.
9
+ *
10
+ * This is deliberately a pure function with no I/O so it is trivial to unit
11
+ * test and reuse from any adapter.
12
+ *
13
+ * @see docs/ENDPOINTS.md §4 (Fast vs Standard matrix)
14
+ * @see docs/STATE-MACHINE.md §3.1 (card scheme detection from retrieveTransaction)
15
+ * @see docs/plans/multi-mode-v0.md §8.5a
16
+ * @see references/payment-api.yaml:9268 (eligibility: Visa / MC / Maestro)
17
+ */
18
+ /**
19
+ * Card schemes eligible for Fast Refund per Viva docs.
20
+ *
21
+ * Matched case-sensitively against `cardType` from `retrieveTransaction`
22
+ * (PascalCase per Viva convention). If Viva ever returns a differently-cased
23
+ * value, the decision falls through to the `auto-ineligible-scheme` branch
24
+ * and the caller routes to standard refund.
25
+ *
26
+ * @see references/payment-api.yaml:9268
27
+ * @see docs/STATE-MACHINE.md §3.1
28
+ */
29
+ const FAST_REFUND_ELIGIBLE_SCHEMES = new Set([
30
+ 'Visa',
31
+ 'MasterCard',
32
+ 'Maestro',
33
+ ]);
34
+ // ---------------------------------------------------------------------------
35
+ // Decision function
36
+ // ---------------------------------------------------------------------------
37
+ /**
38
+ * Pure decision function. Does not perform any I/O.
39
+ *
40
+ * Behaviour:
41
+ * - `strategy === 'fast'` → always `{ kind: 'fast', reason: 'configured' }`.
42
+ * Caller has explicitly opted in; eligibility is enforced server-side.
43
+ * - `strategy === 'standard'` → always `{ kind: 'standard', reason: 'configured' }`.
44
+ * - `strategy === 'auto'` → decided from {@link RefundContext}:
45
+ * - card-present → standard (`auto-ineligible-card-present`)
46
+ * - undefined cardType → standard (`auto-no-card-info`)
47
+ * - eligible scheme + CNP → fast (`auto-eligible`)
48
+ * - non-eligible scheme + CNP → standard (`auto-ineligible-scheme`)
49
+ *
50
+ * On Fast Refund 403 the caller should still fall back to standard refund —
51
+ * this function only handles the pre-call decision, not server-side rejection.
52
+ *
53
+ * @see docs/ENDPOINTS.md §4
54
+ * @see references/payment-api.yaml:9268
55
+ */
56
+ export function resolveRefundStrategy(strategy, ctx) {
57
+ if (strategy === 'fast') {
58
+ return { kind: 'fast', reason: 'configured' };
59
+ }
60
+ if (strategy === 'standard') {
61
+ return { kind: 'standard', reason: 'configured' };
62
+ }
63
+ // auto
64
+ if (!ctx.isCardNotPresent) {
65
+ return { kind: 'standard', reason: 'auto-ineligible-card-present' };
66
+ }
67
+ if (!ctx.cardType) {
68
+ return { kind: 'standard', reason: 'auto-no-card-info' };
69
+ }
70
+ if (FAST_REFUND_ELIGIBLE_SCHEMES.has(ctx.cardType)) {
71
+ return { kind: 'fast', reason: 'auto-eligible' };
72
+ }
73
+ return { kind: 'standard', reason: 'auto-ineligible-scheme' };
74
+ }
75
+ //# sourceMappingURL=strategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategy.js","sourceRoot":"","sources":["../../src/refunds/strategy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAQH;;;;;;;;;;GAUG;AACH,MAAM,4BAA4B,GAAwB,IAAI,GAAG,CAAC;IAChE,MAAM;IACN,YAAY;IACZ,SAAS;CACV,CAAC,CAAC;AA8CH,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,qBAAqB,CACnC,QAAwB,EACxB,GAAkB;IAElB,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACxB,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;IAChD,CAAC;IACD,IAAI,QAAQ,KAAK,UAAU,EAAE,CAAC;QAC5B,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;IACpD,CAAC;IACD,OAAO;IACP,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAC1B,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,8BAA8B,EAAE,CAAC;IACtE,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAClB,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAC3D,CAAC;IACD,IAAI,4BAA4B,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IACnD,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,wBAAwB,EAAE,CAAC;AAChE,CAAC"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Authentication types for the Viva Wallet ISV OAuth 2.0 and reseller
3
+ * basic-auth flows.
4
+ *
5
+ * Implementations live in S2 (packages/viva-payments-core/src/auth/).
6
+ * This file declares interfaces and response shapes only — no runtime code.
7
+ *
8
+ * @see references/viva-docs/md/oauth2-authentication.txt:179
9
+ * @see references/viva-docs/md/isv-credentials.txt:107
10
+ */
11
+ /**
12
+ * Raw token response from `POST /connect/token` (client_credentials grant).
13
+ *
14
+ * Each token lasts for 3600 seconds (one hour). The `scope` field reflects
15
+ * the scopes granted to the ISV client application.
16
+ *
17
+ * @see references/viva-docs/md/oauth2-authentication.txt:179
18
+ */
19
+ export interface OAuth2TokenResponse {
20
+ /** JWT bearer token. Include as `Authorization: Bearer <access_token>`. */
21
+ readonly access_token: string;
22
+ /** Lifetime in seconds. Typically 3600. */
23
+ readonly expires_in: number;
24
+ /** Always `"Bearer"` for this grant type. */
25
+ readonly token_type: 'Bearer';
26
+ /** Space-delimited scopes granted. */
27
+ readonly scope: string;
28
+ }
29
+ /**
30
+ * Enriched token value stored in the cache after a successful fetch.
31
+ * `expires_at` is `Date.now() + (expires_in * 1000)` at fetch time.
32
+ */
33
+ export interface CachedToken {
34
+ readonly access_token: string;
35
+ /** Unix epoch milliseconds when the token expires. */
36
+ readonly expires_at: number;
37
+ readonly scope: string;
38
+ }
39
+ /**
40
+ * Credentials for the ISV Reseller basic-auth strategy.
41
+ *
42
+ * Some ISV API calls (e.g. cancelOrder) require Reseller-level credentials
43
+ * rather than the OAuth2 bearer token. These are distinct from the
44
+ * Client ID + Client Secret used for client_credentials.
45
+ *
46
+ * @see references/viva-docs/md/isv-credentials.txt:107
47
+ */
48
+ export interface ResellerBasicAuthCredentials {
49
+ /** ISV Partner Reseller ID provided by Viva. */
50
+ readonly resellerId: string;
51
+ /** Target merchant's Merchant ID. */
52
+ readonly merchantId: string;
53
+ /** ISV Partner Reseller API Key provided by Viva. */
54
+ readonly resellerApiKey: string;
55
+ }
56
+ /**
57
+ * Pluggable authentication strategy interface.
58
+ *
59
+ * Implementations (OAuth2ClientCredentialsStrategy, ResellerBasicAuthStrategy)
60
+ * are defined in S2. The HTTP client accepts an `AuthStrategy` and calls
61
+ * `getBearerToken()` before each outbound request.
62
+ *
63
+ * Single-flight token refresh and caching are implementation concerns;
64
+ * callers only invoke `getBearerToken()`.
65
+ *
66
+ * @see references/viva-docs/md/oauth2-authentication.txt:128
67
+ */
68
+ export interface AuthStrategy {
69
+ /**
70
+ * Returns a valid bearer token string (without the `Bearer ` prefix).
71
+ *
72
+ * @param opts.forceRefresh - If true, bypass the cache and fetch a fresh token.
73
+ */
74
+ getBearerToken(opts?: {
75
+ readonly forceRefresh?: boolean;
76
+ }): Promise<string>;
77
+ /** Stable name used in logs and metrics (e.g. `"oauth2"`, `"reseller"`). */
78
+ readonly name: string;
79
+ }
80
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/types/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH;;;;;;;GAOG;AACH,MAAM,WAAW,mBAAmB;IAClC,2EAA2E;IAC3E,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,2CAA2C;IAC3C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,6CAA6C;IAC7C,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC;IAC9B,sCAAsC;IACtC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,sDAAsD;IACtD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAMD;;;;;;;;GAQG;AACH,MAAM,WAAW,4BAA4B;IAC3C,gDAAgD;IAChD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,qCAAqC;IACrC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,qDAAqD;IACrD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAMD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,cAAc,CAAC,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE5E,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Authentication types for the Viva Wallet ISV OAuth 2.0 and reseller
3
+ * basic-auth flows.
4
+ *
5
+ * Implementations live in S2 (packages/viva-payments-core/src/auth/).
6
+ * This file declares interfaces and response shapes only — no runtime code.
7
+ *
8
+ * @see references/viva-docs/md/oauth2-authentication.txt:179
9
+ * @see references/viva-docs/md/isv-credentials.txt:107
10
+ */
11
+ export {};
12
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/types/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Viva's numeric CardTypeId → string scheme name mapping.
3
+ *
4
+ * Used by `Payments.retrieveTransaction` to populate the normalized
5
+ * `cardType: string` field for downstream consumers (e.g.,
6
+ * {@link import('../refunds/strategy.js').resolveRefundStrategy resolveRefundStrategy}).
7
+ *
8
+ * Mapping source: `references/viva-docs/md/wh-transaction-payment-created.txt`
9
+ * (search for `CardTypeId`). Viva documents the following nine values:
10
+ *
11
+ * 0 = Visa
12
+ * 1 = Mastercard
13
+ * 2 = Diners
14
+ * 3 = Amex
15
+ * 4 = Invalid
16
+ * 5 = Unknown
17
+ * 6 = Maestro
18
+ * 7 = Discover
19
+ * 8 = JCB
20
+ *
21
+ * Casing note:
22
+ * `resolveRefundStrategy` matches the Fast-Refund eligible-scheme set
23
+ * case-sensitively against the string emitted here. The strategy's set
24
+ * uses `'MasterCard'` (camelCase). We emit `'MasterCard'` for cardTypeId
25
+ * `1` to match — this is the only difference from the doc's raw casing.
26
+ * Diners is emitted as the doc's `'Diners'` (no "Club") so future
27
+ * eligibility additions key off a single canonical string.
28
+ *
29
+ * The sentinel categories `Invalid` (4) and `Unknown` (5) are intentionally
30
+ * NOT exposed as scheme strings — they indicate "no useful card info" and
31
+ * `resolveCardType` returns `undefined` for them so the auto-refund
32
+ * decision falls through to `auto-no-card-info`.
33
+ *
34
+ * @see references/viva-docs/md/wh-transaction-payment-created.txt — search "CardTypeId"
35
+ * @see ../refunds/strategy.ts (FAST_REFUND_ELIGIBLE_SCHEMES)
36
+ * @see docs/STATE-MACHINE.md §3.1
37
+ */
38
+ export declare const CARD_TYPE_BY_ID: Readonly<Record<number, string>>;
39
+ /**
40
+ * Pure helper — returns the string scheme name for a Viva numeric cardTypeId,
41
+ * or `undefined` if the id is null/undefined, a known sentinel (Invalid /
42
+ * Unknown), or not present in the documented mapping.
43
+ *
44
+ * Pure, no I/O. Safe to call from anywhere — including refund strategy
45
+ * decisions and tests.
46
+ */
47
+ export declare function resolveCardType(cardTypeId: number | null | undefined): string | undefined;
48
+ //# sourceMappingURL=card-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card-types.d.ts","sourceRoot":"","sources":["../../src/types/card-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAU3D,CAAC;AAEH;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACpC,MAAM,GAAG,SAAS,CAGpB"}