@spare-technologies/spare-link 0.1.0-beta.1 → 1.0.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 (568) hide show
  1. package/README.md +119 -63
  2. package/lib/commonjs/core/models/payment-return-params.js +245 -20
  3. package/lib/commonjs/core/models/payment-return-params.js.map +1 -1
  4. package/lib/commonjs/core/models/pending-session-record.js +2 -0
  5. package/lib/commonjs/core/models/pending-session-record.js.map +1 -0
  6. package/lib/commonjs/core/services/hosted-flow-controller.js +333 -0
  7. package/lib/commonjs/core/services/hosted-flow-controller.js.map +1 -0
  8. package/lib/commonjs/core/services/hosted-flow-state.js +96 -0
  9. package/lib/commonjs/core/services/hosted-flow-state.js.map +1 -0
  10. package/lib/commonjs/index.js +42 -164
  11. package/lib/commonjs/index.js.map +1 -1
  12. package/lib/commonjs/internal/bank-redirect.js +20 -9
  13. package/lib/commonjs/internal/bank-redirect.js.map +1 -1
  14. package/lib/commonjs/internal/hosted/bridge-message.js +107 -0
  15. package/lib/commonjs/internal/hosted/bridge-message.js.map +1 -0
  16. package/lib/commonjs/internal/hosted/hosted-url.js +41 -0
  17. package/lib/commonjs/internal/hosted/hosted-url.js.map +1 -0
  18. package/lib/commonjs/internal/index.js +0 -7
  19. package/lib/commonjs/internal/index.js.map +1 -1
  20. package/lib/commonjs/internal/redact-uri.js +59 -15
  21. package/lib/commonjs/internal/redact-uri.js.map +1 -1
  22. package/lib/commonjs/internal/secure-store-pending-session-store.js +20 -25
  23. package/lib/commonjs/internal/secure-store-pending-session-store.js.map +1 -1
  24. package/lib/commonjs/internal/url-parts.js +145 -0
  25. package/lib/commonjs/internal/url-parts.js.map +1 -0
  26. package/lib/commonjs/public/index.js +0 -37
  27. package/lib/commonjs/public/index.js.map +1 -1
  28. package/lib/commonjs/public/payment-result.js +16 -4
  29. package/lib/commonjs/public/payment-result.js.map +1 -1
  30. package/lib/commonjs/public/recovery-result.js +7 -18
  31. package/lib/commonjs/public/recovery-result.js.map +1 -1
  32. package/lib/commonjs/public/spare-link-config.js +41 -16
  33. package/lib/commonjs/public/spare-link-config.js.map +1 -1
  34. package/lib/commonjs/public/spare-link-event.js +27 -33
  35. package/lib/commonjs/public/spare-link-event.js.map +1 -1
  36. package/lib/commonjs/public/spare-link-instance.js +67 -77
  37. package/lib/commonjs/public/spare-link-instance.js.map +1 -1
  38. package/lib/commonjs/public/spare-link-session.js +2 -9
  39. package/lib/commonjs/public/spare-link-session.js.map +1 -1
  40. package/lib/commonjs/public/spare-link.js +0 -12
  41. package/lib/commonjs/public/spare-link.js.map +1 -1
  42. package/lib/commonjs/ui/hooks/{use-payment-flow-state.js → use-hosted-flow-state.js} +4 -4
  43. package/lib/commonjs/ui/hooks/use-hosted-flow-state.js.map +1 -0
  44. package/lib/commonjs/ui/hosted/hosted-payment-page.js +177 -0
  45. package/lib/commonjs/ui/hosted/hosted-payment-page.js.map +1 -0
  46. package/lib/commonjs/ui/hosted/hosted-payment-webview.js +168 -0
  47. package/lib/commonjs/ui/hosted/hosted-payment-webview.js.map +1 -0
  48. package/lib/commonjs/ui/screens/index.js +3 -17
  49. package/lib/commonjs/ui/screens/index.js.map +1 -1
  50. package/lib/commonjs/ui/screens/page-unavailable-screen.js +101 -0
  51. package/lib/commonjs/ui/screens/page-unavailable-screen.js.map +1 -0
  52. package/lib/commonjs/ui/spare-link-host.js +220 -234
  53. package/lib/commonjs/ui/spare-link-host.js.map +1 -1
  54. package/lib/commonjs/ui/widgets/index.js +3 -10
  55. package/lib/commonjs/ui/widgets/index.js.map +1 -1
  56. package/lib/commonjs/version.js +1 -1
  57. package/lib/commonjs/version.js.map +1 -1
  58. package/lib/module/core/models/payment-return-params.js +235 -20
  59. package/lib/module/core/models/payment-return-params.js.map +1 -1
  60. package/lib/module/core/models/pending-session-record.js +2 -0
  61. package/lib/module/core/models/pending-session-record.js.map +1 -0
  62. package/lib/module/core/services/hosted-flow-controller.js +328 -0
  63. package/lib/module/core/services/hosted-flow-controller.js.map +1 -0
  64. package/lib/module/core/services/hosted-flow-state.js +91 -0
  65. package/lib/module/core/services/hosted-flow-state.js.map +1 -0
  66. package/lib/module/index.js +8 -22
  67. package/lib/module/index.js.map +1 -1
  68. package/lib/module/internal/bank-redirect.js +20 -9
  69. package/lib/module/internal/bank-redirect.js.map +1 -1
  70. package/lib/module/internal/hosted/bridge-message.js +104 -0
  71. package/lib/module/internal/hosted/bridge-message.js.map +1 -0
  72. package/lib/module/internal/hosted/hosted-url.js +36 -0
  73. package/lib/module/internal/hosted/hosted-url.js.map +1 -0
  74. package/lib/module/internal/index.js +0 -1
  75. package/lib/module/internal/index.js.map +1 -1
  76. package/lib/module/internal/redact-uri.js +59 -15
  77. package/lib/module/internal/redact-uri.js.map +1 -1
  78. package/lib/module/internal/secure-store-pending-session-store.js +20 -25
  79. package/lib/module/internal/secure-store-pending-session-store.js.map +1 -1
  80. package/lib/module/internal/url-parts.js +139 -0
  81. package/lib/module/internal/url-parts.js.map +1 -0
  82. package/lib/module/public/index.js +2 -3
  83. package/lib/module/public/index.js.map +1 -1
  84. package/lib/module/public/payment-result.js +16 -4
  85. package/lib/module/public/payment-result.js.map +1 -1
  86. package/lib/module/public/recovery-result.js +7 -17
  87. package/lib/module/public/recovery-result.js.map +1 -1
  88. package/lib/module/public/spare-link-config.js +42 -15
  89. package/lib/module/public/spare-link-config.js.map +1 -1
  90. package/lib/module/public/spare-link-event.js +27 -33
  91. package/lib/module/public/spare-link-event.js.map +1 -1
  92. package/lib/module/public/spare-link-instance.js +68 -72
  93. package/lib/module/public/spare-link-instance.js.map +1 -1
  94. package/lib/module/public/spare-link-session.js +2 -9
  95. package/lib/module/public/spare-link-session.js.map +1 -1
  96. package/lib/module/public/spare-link.js +1 -1
  97. package/lib/module/public/spare-link.js.map +1 -1
  98. package/lib/module/ui/hooks/{use-payment-flow-state.js → use-hosted-flow-state.js} +3 -3
  99. package/lib/module/ui/hooks/use-hosted-flow-state.js.map +1 -0
  100. package/lib/module/ui/hosted/hosted-payment-page.js +175 -0
  101. package/lib/module/ui/hosted/hosted-payment-page.js.map +1 -0
  102. package/lib/module/ui/hosted/hosted-payment-webview.js +163 -0
  103. package/lib/module/ui/hosted/hosted-payment-webview.js.map +1 -0
  104. package/lib/module/ui/screens/index.js +1 -3
  105. package/lib/module/ui/screens/index.js.map +1 -1
  106. package/lib/module/ui/screens/page-unavailable-screen.js +97 -0
  107. package/lib/module/ui/screens/page-unavailable-screen.js.map +1 -0
  108. package/lib/module/ui/spare-link-host.js +221 -236
  109. package/lib/module/ui/spare-link-host.js.map +1 -1
  110. package/lib/module/ui/widgets/index.js +1 -2
  111. package/lib/module/ui/widgets/index.js.map +1 -1
  112. package/lib/module/version.js +1 -1
  113. package/lib/module/version.js.map +1 -1
  114. package/lib/typescript/commonjs/core/models/index.d.ts +1 -123
  115. package/lib/typescript/commonjs/core/models/index.d.ts.map +1 -1
  116. package/lib/typescript/commonjs/core/models/payment-return-params.d.ts +91 -8
  117. package/lib/typescript/commonjs/core/models/payment-return-params.d.ts.map +1 -1
  118. package/lib/typescript/commonjs/core/models/pending-session-record.d.ts +11 -0
  119. package/lib/typescript/commonjs/core/models/pending-session-record.d.ts.map +1 -0
  120. package/lib/typescript/commonjs/core/services/hosted-flow-controller.d.ts +119 -0
  121. package/lib/typescript/commonjs/core/services/hosted-flow-controller.d.ts.map +1 -0
  122. package/lib/typescript/commonjs/core/services/hosted-flow-state.d.ts +75 -0
  123. package/lib/typescript/commonjs/core/services/hosted-flow-state.d.ts.map +1 -0
  124. package/lib/typescript/commonjs/index.d.ts +5 -14
  125. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  126. package/lib/typescript/commonjs/internal/bank-redirect.d.ts.map +1 -1
  127. package/lib/typescript/commonjs/internal/hosted/bridge-message.d.ts +44 -0
  128. package/lib/typescript/commonjs/internal/hosted/bridge-message.d.ts.map +1 -0
  129. package/lib/typescript/commonjs/internal/hosted/hosted-url.d.ts +30 -0
  130. package/lib/typescript/commonjs/internal/hosted/hosted-url.d.ts.map +1 -0
  131. package/lib/typescript/commonjs/internal/index.d.ts +0 -1
  132. package/lib/typescript/commonjs/internal/index.d.ts.map +1 -1
  133. package/lib/typescript/commonjs/internal/redact-uri.d.ts +21 -1
  134. package/lib/typescript/commonjs/internal/redact-uri.d.ts.map +1 -1
  135. package/lib/typescript/commonjs/internal/secure-store-pending-session-store.d.ts +3 -2
  136. package/lib/typescript/commonjs/internal/secure-store-pending-session-store.d.ts.map +1 -1
  137. package/lib/typescript/commonjs/internal/url-parts.d.ts +46 -0
  138. package/lib/typescript/commonjs/internal/url-parts.d.ts.map +1 -0
  139. package/lib/typescript/commonjs/public/index.d.ts +4 -6
  140. package/lib/typescript/commonjs/public/index.d.ts.map +1 -1
  141. package/lib/typescript/commonjs/public/payment-result.d.ts +50 -12
  142. package/lib/typescript/commonjs/public/payment-result.d.ts.map +1 -1
  143. package/lib/typescript/commonjs/public/recovery-result.d.ts +11 -20
  144. package/lib/typescript/commonjs/public/recovery-result.d.ts.map +1 -1
  145. package/lib/typescript/commonjs/public/spare-link-config.d.ts +13 -31
  146. package/lib/typescript/commonjs/public/spare-link-config.d.ts.map +1 -1
  147. package/lib/typescript/commonjs/public/spare-link-event.d.ts +29 -31
  148. package/lib/typescript/commonjs/public/spare-link-event.d.ts.map +1 -1
  149. package/lib/typescript/commonjs/public/spare-link-host-api.d.ts +1 -12
  150. package/lib/typescript/commonjs/public/spare-link-host-api.d.ts.map +1 -1
  151. package/lib/typescript/commonjs/public/spare-link-instance.d.ts +26 -20
  152. package/lib/typescript/commonjs/public/spare-link-instance.d.ts.map +1 -1
  153. package/lib/typescript/commonjs/public/spare-link-session.d.ts +3 -8
  154. package/lib/typescript/commonjs/public/spare-link-session.d.ts.map +1 -1
  155. package/lib/typescript/commonjs/public/spare-link.d.ts +1 -1
  156. package/lib/typescript/commonjs/public/spare-link.d.ts.map +1 -1
  157. package/lib/typescript/commonjs/ui/hooks/use-hosted-flow-state.d.ts +9 -0
  158. package/lib/typescript/commonjs/ui/hooks/use-hosted-flow-state.d.ts.map +1 -0
  159. package/lib/typescript/commonjs/ui/hosted/hosted-payment-page.d.ts +17 -0
  160. package/lib/typescript/commonjs/ui/hosted/hosted-payment-page.d.ts.map +1 -0
  161. package/lib/typescript/commonjs/ui/hosted/hosted-payment-webview.d.ts +43 -0
  162. package/lib/typescript/commonjs/ui/hosted/hosted-payment-webview.d.ts.map +1 -0
  163. package/lib/typescript/commonjs/ui/screens/index.d.ts +1 -3
  164. package/lib/typescript/commonjs/ui/screens/index.d.ts.map +1 -1
  165. package/lib/typescript/commonjs/ui/screens/page-unavailable-screen.d.ts +18 -0
  166. package/lib/typescript/commonjs/ui/screens/page-unavailable-screen.d.ts.map +1 -0
  167. package/lib/typescript/commonjs/ui/spare-link-host.d.ts +4 -5
  168. package/lib/typescript/commonjs/ui/spare-link-host.d.ts.map +1 -1
  169. package/lib/typescript/commonjs/ui/widgets/index.d.ts +1 -2
  170. package/lib/typescript/commonjs/ui/widgets/index.d.ts.map +1 -1
  171. package/lib/typescript/commonjs/version.d.ts +1 -1
  172. package/lib/typescript/commonjs/version.d.ts.map +1 -1
  173. package/lib/typescript/module/core/models/index.d.ts +1 -123
  174. package/lib/typescript/module/core/models/index.d.ts.map +1 -1
  175. package/lib/typescript/module/core/models/payment-return-params.d.ts +91 -8
  176. package/lib/typescript/module/core/models/payment-return-params.d.ts.map +1 -1
  177. package/lib/typescript/module/core/models/pending-session-record.d.ts +11 -0
  178. package/lib/typescript/module/core/models/pending-session-record.d.ts.map +1 -0
  179. package/lib/typescript/module/core/services/hosted-flow-controller.d.ts +119 -0
  180. package/lib/typescript/module/core/services/hosted-flow-controller.d.ts.map +1 -0
  181. package/lib/typescript/module/core/services/hosted-flow-state.d.ts +75 -0
  182. package/lib/typescript/module/core/services/hosted-flow-state.d.ts.map +1 -0
  183. package/lib/typescript/module/index.d.ts +5 -14
  184. package/lib/typescript/module/index.d.ts.map +1 -1
  185. package/lib/typescript/module/internal/bank-redirect.d.ts.map +1 -1
  186. package/lib/typescript/module/internal/hosted/bridge-message.d.ts +44 -0
  187. package/lib/typescript/module/internal/hosted/bridge-message.d.ts.map +1 -0
  188. package/lib/typescript/module/internal/hosted/hosted-url.d.ts +30 -0
  189. package/lib/typescript/module/internal/hosted/hosted-url.d.ts.map +1 -0
  190. package/lib/typescript/module/internal/index.d.ts +0 -1
  191. package/lib/typescript/module/internal/index.d.ts.map +1 -1
  192. package/lib/typescript/module/internal/redact-uri.d.ts +21 -1
  193. package/lib/typescript/module/internal/redact-uri.d.ts.map +1 -1
  194. package/lib/typescript/module/internal/secure-store-pending-session-store.d.ts +3 -2
  195. package/lib/typescript/module/internal/secure-store-pending-session-store.d.ts.map +1 -1
  196. package/lib/typescript/module/internal/url-parts.d.ts +46 -0
  197. package/lib/typescript/module/internal/url-parts.d.ts.map +1 -0
  198. package/lib/typescript/module/public/index.d.ts +4 -6
  199. package/lib/typescript/module/public/index.d.ts.map +1 -1
  200. package/lib/typescript/module/public/payment-result.d.ts +50 -12
  201. package/lib/typescript/module/public/payment-result.d.ts.map +1 -1
  202. package/lib/typescript/module/public/recovery-result.d.ts +11 -20
  203. package/lib/typescript/module/public/recovery-result.d.ts.map +1 -1
  204. package/lib/typescript/module/public/spare-link-config.d.ts +13 -31
  205. package/lib/typescript/module/public/spare-link-config.d.ts.map +1 -1
  206. package/lib/typescript/module/public/spare-link-event.d.ts +29 -31
  207. package/lib/typescript/module/public/spare-link-event.d.ts.map +1 -1
  208. package/lib/typescript/module/public/spare-link-host-api.d.ts +1 -12
  209. package/lib/typescript/module/public/spare-link-host-api.d.ts.map +1 -1
  210. package/lib/typescript/module/public/spare-link-instance.d.ts +26 -20
  211. package/lib/typescript/module/public/spare-link-instance.d.ts.map +1 -1
  212. package/lib/typescript/module/public/spare-link-session.d.ts +3 -8
  213. package/lib/typescript/module/public/spare-link-session.d.ts.map +1 -1
  214. package/lib/typescript/module/public/spare-link.d.ts +1 -1
  215. package/lib/typescript/module/public/spare-link.d.ts.map +1 -1
  216. package/lib/typescript/module/ui/hooks/use-hosted-flow-state.d.ts +9 -0
  217. package/lib/typescript/module/ui/hooks/use-hosted-flow-state.d.ts.map +1 -0
  218. package/lib/typescript/module/ui/hosted/hosted-payment-page.d.ts +17 -0
  219. package/lib/typescript/module/ui/hosted/hosted-payment-page.d.ts.map +1 -0
  220. package/lib/typescript/module/ui/hosted/hosted-payment-webview.d.ts +43 -0
  221. package/lib/typescript/module/ui/hosted/hosted-payment-webview.d.ts.map +1 -0
  222. package/lib/typescript/module/ui/screens/index.d.ts +1 -3
  223. package/lib/typescript/module/ui/screens/index.d.ts.map +1 -1
  224. package/lib/typescript/module/ui/screens/page-unavailable-screen.d.ts +18 -0
  225. package/lib/typescript/module/ui/screens/page-unavailable-screen.d.ts.map +1 -0
  226. package/lib/typescript/module/ui/spare-link-host.d.ts +4 -5
  227. package/lib/typescript/module/ui/spare-link-host.d.ts.map +1 -1
  228. package/lib/typescript/module/ui/widgets/index.d.ts +1 -2
  229. package/lib/typescript/module/ui/widgets/index.d.ts.map +1 -1
  230. package/lib/typescript/module/version.d.ts +1 -1
  231. package/lib/typescript/module/version.d.ts.map +1 -1
  232. package/package.json +24 -22
  233. package/plugins/with-spare-link.js +6 -26
  234. package/src/core/models/index.ts +1 -139
  235. package/src/core/models/payment-return-params.ts +269 -21
  236. package/src/core/models/pending-session-record.ts +10 -0
  237. package/src/core/services/hosted-flow-controller.ts +374 -0
  238. package/src/core/services/hosted-flow-state.ts +123 -0
  239. package/src/index.ts +20 -89
  240. package/src/internal/bank-redirect.ts +23 -9
  241. package/src/internal/hosted/bridge-message.ts +106 -0
  242. package/src/internal/hosted/hosted-url.ts +33 -0
  243. package/src/internal/index.ts +0 -1
  244. package/src/internal/redact-uri.ts +69 -15
  245. package/src/internal/secure-store-pending-session-store.ts +28 -49
  246. package/src/internal/url-parts.ts +134 -0
  247. package/src/public/index.ts +2 -24
  248. package/src/public/payment-result.ts +50 -12
  249. package/src/public/recovery-result.ts +16 -25
  250. package/src/public/spare-link-config.ts +56 -43
  251. package/src/public/spare-link-event.ts +33 -42
  252. package/src/public/spare-link-host-api.ts +1 -14
  253. package/src/public/spare-link-instance.ts +57 -65
  254. package/src/public/spare-link-session.ts +4 -16
  255. package/src/public/spare-link.ts +1 -1
  256. package/src/ui/hooks/use-hosted-flow-state.ts +16 -0
  257. package/src/ui/hosted/hosted-payment-page.tsx +178 -0
  258. package/src/ui/hosted/hosted-payment-webview.tsx +164 -0
  259. package/src/ui/screens/index.ts +4 -6
  260. package/src/ui/screens/page-unavailable-screen.tsx +94 -0
  261. package/src/ui/spare-link-host.tsx +227 -247
  262. package/src/ui/widgets/index.ts +1 -2
  263. package/src/version.ts +1 -1
  264. package/CHANGELOG.md +0 -25
  265. package/lib/commonjs/core/client/link-api-client.js +0 -297
  266. package/lib/commonjs/core/client/link-api-client.js.map +0 -1
  267. package/lib/commonjs/core/errors/payment-api-error.js +0 -35
  268. package/lib/commonjs/core/errors/payment-api-error.js.map +0 -1
  269. package/lib/commonjs/core/models/link-session-status.js +0 -14
  270. package/lib/commonjs/core/models/link-session-status.js.map +0 -1
  271. package/lib/commonjs/core/models/payment-type.js +0 -45
  272. package/lib/commonjs/core/models/payment-type.js.map +0 -1
  273. package/lib/commonjs/core/models/wire-mappers.js +0 -277
  274. package/lib/commonjs/core/models/wire-mappers.js.map +0 -1
  275. package/lib/commonjs/core/services/consent-presenter.js +0 -150
  276. package/lib/commonjs/core/services/consent-presenter.js.map +0 -1
  277. package/lib/commonjs/core/services/execute-resume-if-needed.js +0 -216
  278. package/lib/commonjs/core/services/execute-resume-if-needed.js.map +0 -1
  279. package/lib/commonjs/core/services/multi-payment-rules-presenter.js +0 -151
  280. package/lib/commonjs/core/services/multi-payment-rules-presenter.js.map +0 -1
  281. package/lib/commonjs/core/services/payment-flow-controller.js +0 -547
  282. package/lib/commonjs/core/services/payment-flow-controller.js.map +0 -1
  283. package/lib/commonjs/core/services/payment-flow-state.js +0 -110
  284. package/lib/commonjs/core/services/payment-flow-state.js.map +0 -1
  285. package/lib/commonjs/core/services/payment-result-mapper.js +0 -49
  286. package/lib/commonjs/core/services/payment-result-mapper.js.map +0 -1
  287. package/lib/commonjs/core/services/presentation-utils.js +0 -11
  288. package/lib/commonjs/core/services/presentation-utils.js.map +0 -1
  289. package/lib/commonjs/core/services/redirect-buffer.js +0 -40
  290. package/lib/commonjs/core/services/redirect-buffer.js.map +0 -1
  291. package/lib/commonjs/core/services/user-friendly-messages.js +0 -46
  292. package/lib/commonjs/core/services/user-friendly-messages.js.map +0 -1
  293. package/lib/commonjs/internal/telemetry-collector.js +0 -80
  294. package/lib/commonjs/internal/telemetry-collector.js.map +0 -1
  295. package/lib/commonjs/public/constants.js +0 -21
  296. package/lib/commonjs/public/constants.js.map +0 -1
  297. package/lib/commonjs/public/spare-link-callbacks.js +0 -6
  298. package/lib/commonjs/public/spare-link-callbacks.js.map +0 -1
  299. package/lib/commonjs/ui/consent/charge-bearer-display.js +0 -99
  300. package/lib/commonjs/ui/consent/charge-bearer-display.js.map +0 -1
  301. package/lib/commonjs/ui/consent/consent-accordion.js +0 -94
  302. package/lib/commonjs/ui/consent/consent-accordion.js.map +0 -1
  303. package/lib/commonjs/ui/consent/consent-summary-section.js +0 -27
  304. package/lib/commonjs/ui/consent/consent-summary-section.js.map +0 -1
  305. package/lib/commonjs/ui/consent/cop-information.js +0 -168
  306. package/lib/commonjs/ui/consent/cop-information.js.map +0 -1
  307. package/lib/commonjs/ui/consent/international-payment-summary.js +0 -98
  308. package/lib/commonjs/ui/consent/international-payment-summary.js.map +0 -1
  309. package/lib/commonjs/ui/consent/label-value-rows.js +0 -59
  310. package/lib/commonjs/ui/consent/label-value-rows.js.map +0 -1
  311. package/lib/commonjs/ui/consent/multi-payment-rules-list.js +0 -130
  312. package/lib/commonjs/ui/consent/multi-payment-rules-list.js.map +0 -1
  313. package/lib/commonjs/ui/consent/multi-payment-summary.js +0 -99
  314. package/lib/commonjs/ui/consent/multi-payment-summary.js.map +0 -1
  315. package/lib/commonjs/ui/consent/single-payment-summary.js +0 -158
  316. package/lib/commonjs/ui/consent/single-payment-summary.js.map +0 -1
  317. package/lib/commonjs/ui/consent/terms-link.js +0 -35
  318. package/lib/commonjs/ui/consent/terms-link.js.map +0 -1
  319. package/lib/commonjs/ui/hooks/use-payment-flow-state.js.map +0 -1
  320. package/lib/commonjs/ui/payment-flow-page.js +0 -235
  321. package/lib/commonjs/ui/payment-flow-page.js.map +0 -1
  322. package/lib/commonjs/ui/screens/bank-selection-screen.js +0 -215
  323. package/lib/commonjs/ui/screens/bank-selection-screen.js.map +0 -1
  324. package/lib/commonjs/ui/screens/consent-details-screen.js +0 -124
  325. package/lib/commonjs/ui/screens/consent-details-screen.js.map +0 -1
  326. package/lib/commonjs/ui/screens/mandate-setup-success-screen.js +0 -79
  327. package/lib/commonjs/ui/screens/mandate-setup-success-screen.js.map +0 -1
  328. package/lib/commonjs/ui/widgets/layout-w-header.js +0 -106
  329. package/lib/commonjs/ui/widgets/layout-w-header.js.map +0 -1
  330. package/lib/commonjs/ui/widgets/stepper.js +0 -124
  331. package/lib/commonjs/ui/widgets/stepper.js.map +0 -1
  332. package/lib/module/core/client/link-api-client.js +0 -292
  333. package/lib/module/core/client/link-api-client.js.map +0 -1
  334. package/lib/module/core/errors/payment-api-error.js +0 -29
  335. package/lib/module/core/errors/payment-api-error.js.map +0 -1
  336. package/lib/module/core/models/link-session-status.js +0 -10
  337. package/lib/module/core/models/link-session-status.js.map +0 -1
  338. package/lib/module/core/models/payment-type.js +0 -36
  339. package/lib/module/core/models/payment-type.js.map +0 -1
  340. package/lib/module/core/models/wire-mappers.js +0 -263
  341. package/lib/module/core/models/wire-mappers.js.map +0 -1
  342. package/lib/module/core/services/consent-presenter.js +0 -140
  343. package/lib/module/core/services/consent-presenter.js.map +0 -1
  344. package/lib/module/core/services/execute-resume-if-needed.js +0 -211
  345. package/lib/module/core/services/execute-resume-if-needed.js.map +0 -1
  346. package/lib/module/core/services/multi-payment-rules-presenter.js +0 -146
  347. package/lib/module/core/services/multi-payment-rules-presenter.js.map +0 -1
  348. package/lib/module/core/services/payment-flow-controller.js +0 -544
  349. package/lib/module/core/services/payment-flow-controller.js.map +0 -1
  350. package/lib/module/core/services/payment-flow-state.js +0 -106
  351. package/lib/module/core/services/payment-flow-state.js.map +0 -1
  352. package/lib/module/core/services/payment-result-mapper.js +0 -45
  353. package/lib/module/core/services/payment-result-mapper.js.map +0 -1
  354. package/lib/module/core/services/presentation-utils.js +0 -7
  355. package/lib/module/core/services/presentation-utils.js.map +0 -1
  356. package/lib/module/core/services/redirect-buffer.js +0 -33
  357. package/lib/module/core/services/redirect-buffer.js.map +0 -1
  358. package/lib/module/core/services/user-friendly-messages.js +0 -42
  359. package/lib/module/core/services/user-friendly-messages.js.map +0 -1
  360. package/lib/module/internal/telemetry-collector.js +0 -75
  361. package/lib/module/internal/telemetry-collector.js.map +0 -1
  362. package/lib/module/public/constants.js +0 -17
  363. package/lib/module/public/constants.js.map +0 -1
  364. package/lib/module/public/spare-link-callbacks.js +0 -4
  365. package/lib/module/public/spare-link-callbacks.js.map +0 -1
  366. package/lib/module/ui/consent/charge-bearer-display.js +0 -95
  367. package/lib/module/ui/consent/charge-bearer-display.js.map +0 -1
  368. package/lib/module/ui/consent/consent-accordion.js +0 -90
  369. package/lib/module/ui/consent/consent-accordion.js.map +0 -1
  370. package/lib/module/ui/consent/consent-summary-section.js +0 -23
  371. package/lib/module/ui/consent/consent-summary-section.js.map +0 -1
  372. package/lib/module/ui/consent/cop-information.js +0 -165
  373. package/lib/module/ui/consent/cop-information.js.map +0 -1
  374. package/lib/module/ui/consent/international-payment-summary.js +0 -94
  375. package/lib/module/ui/consent/international-payment-summary.js.map +0 -1
  376. package/lib/module/ui/consent/label-value-rows.js +0 -55
  377. package/lib/module/ui/consent/label-value-rows.js.map +0 -1
  378. package/lib/module/ui/consent/multi-payment-rules-list.js +0 -125
  379. package/lib/module/ui/consent/multi-payment-rules-list.js.map +0 -1
  380. package/lib/module/ui/consent/multi-payment-summary.js +0 -95
  381. package/lib/module/ui/consent/multi-payment-summary.js.map +0 -1
  382. package/lib/module/ui/consent/single-payment-summary.js +0 -154
  383. package/lib/module/ui/consent/single-payment-summary.js.map +0 -1
  384. package/lib/module/ui/consent/terms-link.js +0 -31
  385. package/lib/module/ui/consent/terms-link.js.map +0 -1
  386. package/lib/module/ui/hooks/use-payment-flow-state.js.map +0 -1
  387. package/lib/module/ui/payment-flow-page.js +0 -232
  388. package/lib/module/ui/payment-flow-page.js.map +0 -1
  389. package/lib/module/ui/screens/bank-selection-screen.js +0 -211
  390. package/lib/module/ui/screens/bank-selection-screen.js.map +0 -1
  391. package/lib/module/ui/screens/consent-details-screen.js +0 -120
  392. package/lib/module/ui/screens/consent-details-screen.js.map +0 -1
  393. package/lib/module/ui/screens/mandate-setup-success-screen.js +0 -75
  394. package/lib/module/ui/screens/mandate-setup-success-screen.js.map +0 -1
  395. package/lib/module/ui/widgets/layout-w-header.js +0 -102
  396. package/lib/module/ui/widgets/layout-w-header.js.map +0 -1
  397. package/lib/module/ui/widgets/stepper.js +0 -120
  398. package/lib/module/ui/widgets/stepper.js.map +0 -1
  399. package/lib/typescript/commonjs/core/client/link-api-client.d.ts +0 -70
  400. package/lib/typescript/commonjs/core/client/link-api-client.d.ts.map +0 -1
  401. package/lib/typescript/commonjs/core/errors/payment-api-error.d.ts +0 -15
  402. package/lib/typescript/commonjs/core/errors/payment-api-error.d.ts.map +0 -1
  403. package/lib/typescript/commonjs/core/models/link-session-status.d.ts +0 -6
  404. package/lib/typescript/commonjs/core/models/link-session-status.d.ts.map +0 -1
  405. package/lib/typescript/commonjs/core/models/payment-type.d.ts +0 -18
  406. package/lib/typescript/commonjs/core/models/payment-type.d.ts.map +0 -1
  407. package/lib/typescript/commonjs/core/models/wire-mappers.d.ts +0 -19
  408. package/lib/typescript/commonjs/core/models/wire-mappers.d.ts.map +0 -1
  409. package/lib/typescript/commonjs/core/services/consent-presenter.d.ts +0 -67
  410. package/lib/typescript/commonjs/core/services/consent-presenter.d.ts.map +0 -1
  411. package/lib/typescript/commonjs/core/services/execute-resume-if-needed.d.ts +0 -32
  412. package/lib/typescript/commonjs/core/services/execute-resume-if-needed.d.ts.map +0 -1
  413. package/lib/typescript/commonjs/core/services/multi-payment-rules-presenter.d.ts +0 -9
  414. package/lib/typescript/commonjs/core/services/multi-payment-rules-presenter.d.ts.map +0 -1
  415. package/lib/typescript/commonjs/core/services/payment-flow-controller.d.ts +0 -146
  416. package/lib/typescript/commonjs/core/services/payment-flow-controller.d.ts.map +0 -1
  417. package/lib/typescript/commonjs/core/services/payment-flow-state.d.ts +0 -64
  418. package/lib/typescript/commonjs/core/services/payment-flow-state.d.ts.map +0 -1
  419. package/lib/typescript/commonjs/core/services/payment-result-mapper.d.ts +0 -5
  420. package/lib/typescript/commonjs/core/services/payment-result-mapper.d.ts.map +0 -1
  421. package/lib/typescript/commonjs/core/services/presentation-utils.d.ts +0 -5
  422. package/lib/typescript/commonjs/core/services/presentation-utils.d.ts.map +0 -1
  423. package/lib/typescript/commonjs/core/services/redirect-buffer.d.ts +0 -6
  424. package/lib/typescript/commonjs/core/services/redirect-buffer.d.ts.map +0 -1
  425. package/lib/typescript/commonjs/core/services/user-friendly-messages.d.ts +0 -6
  426. package/lib/typescript/commonjs/core/services/user-friendly-messages.d.ts.map +0 -1
  427. package/lib/typescript/commonjs/internal/telemetry-collector.d.ts +0 -2
  428. package/lib/typescript/commonjs/internal/telemetry-collector.d.ts.map +0 -1
  429. package/lib/typescript/commonjs/public/constants.d.ts +0 -12
  430. package/lib/typescript/commonjs/public/constants.d.ts.map +0 -1
  431. package/lib/typescript/commonjs/public/spare-link-callbacks.d.ts +0 -14
  432. package/lib/typescript/commonjs/public/spare-link-callbacks.d.ts.map +0 -1
  433. package/lib/typescript/commonjs/ui/consent/charge-bearer-display.d.ts +0 -5
  434. package/lib/typescript/commonjs/ui/consent/charge-bearer-display.d.ts.map +0 -1
  435. package/lib/typescript/commonjs/ui/consent/consent-accordion.d.ts +0 -10
  436. package/lib/typescript/commonjs/ui/consent/consent-accordion.d.ts.map +0 -1
  437. package/lib/typescript/commonjs/ui/consent/consent-summary-section.d.ts +0 -6
  438. package/lib/typescript/commonjs/ui/consent/consent-summary-section.d.ts.map +0 -1
  439. package/lib/typescript/commonjs/ui/consent/cop-information.d.ts +0 -6
  440. package/lib/typescript/commonjs/ui/consent/cop-information.d.ts.map +0 -1
  441. package/lib/typescript/commonjs/ui/consent/international-payment-summary.d.ts +0 -6
  442. package/lib/typescript/commonjs/ui/consent/international-payment-summary.d.ts.map +0 -1
  443. package/lib/typescript/commonjs/ui/consent/label-value-rows.d.ts +0 -10
  444. package/lib/typescript/commonjs/ui/consent/label-value-rows.d.ts.map +0 -1
  445. package/lib/typescript/commonjs/ui/consent/multi-payment-rules-list.d.ts +0 -15
  446. package/lib/typescript/commonjs/ui/consent/multi-payment-rules-list.d.ts.map +0 -1
  447. package/lib/typescript/commonjs/ui/consent/multi-payment-summary.d.ts +0 -6
  448. package/lib/typescript/commonjs/ui/consent/multi-payment-summary.d.ts.map +0 -1
  449. package/lib/typescript/commonjs/ui/consent/single-payment-summary.d.ts +0 -6
  450. package/lib/typescript/commonjs/ui/consent/single-payment-summary.d.ts.map +0 -1
  451. package/lib/typescript/commonjs/ui/consent/terms-link.d.ts +0 -2
  452. package/lib/typescript/commonjs/ui/consent/terms-link.d.ts.map +0 -1
  453. package/lib/typescript/commonjs/ui/hooks/use-payment-flow-state.d.ts +0 -9
  454. package/lib/typescript/commonjs/ui/hooks/use-payment-flow-state.d.ts.map +0 -1
  455. package/lib/typescript/commonjs/ui/payment-flow-page.d.ts +0 -20
  456. package/lib/typescript/commonjs/ui/payment-flow-page.d.ts.map +0 -1
  457. package/lib/typescript/commonjs/ui/screens/bank-selection-screen.d.ts +0 -15
  458. package/lib/typescript/commonjs/ui/screens/bank-selection-screen.d.ts.map +0 -1
  459. package/lib/typescript/commonjs/ui/screens/consent-details-screen.d.ts +0 -13
  460. package/lib/typescript/commonjs/ui/screens/consent-details-screen.d.ts.map +0 -1
  461. package/lib/typescript/commonjs/ui/screens/mandate-setup-success-screen.d.ts +0 -10
  462. package/lib/typescript/commonjs/ui/screens/mandate-setup-success-screen.d.ts.map +0 -1
  463. package/lib/typescript/commonjs/ui/widgets/layout-w-header.d.ts +0 -20
  464. package/lib/typescript/commonjs/ui/widgets/layout-w-header.d.ts.map +0 -1
  465. package/lib/typescript/commonjs/ui/widgets/stepper.d.ts +0 -15
  466. package/lib/typescript/commonjs/ui/widgets/stepper.d.ts.map +0 -1
  467. package/lib/typescript/module/core/client/link-api-client.d.ts +0 -70
  468. package/lib/typescript/module/core/client/link-api-client.d.ts.map +0 -1
  469. package/lib/typescript/module/core/errors/payment-api-error.d.ts +0 -15
  470. package/lib/typescript/module/core/errors/payment-api-error.d.ts.map +0 -1
  471. package/lib/typescript/module/core/models/link-session-status.d.ts +0 -6
  472. package/lib/typescript/module/core/models/link-session-status.d.ts.map +0 -1
  473. package/lib/typescript/module/core/models/payment-type.d.ts +0 -18
  474. package/lib/typescript/module/core/models/payment-type.d.ts.map +0 -1
  475. package/lib/typescript/module/core/models/wire-mappers.d.ts +0 -19
  476. package/lib/typescript/module/core/models/wire-mappers.d.ts.map +0 -1
  477. package/lib/typescript/module/core/services/consent-presenter.d.ts +0 -67
  478. package/lib/typescript/module/core/services/consent-presenter.d.ts.map +0 -1
  479. package/lib/typescript/module/core/services/execute-resume-if-needed.d.ts +0 -32
  480. package/lib/typescript/module/core/services/execute-resume-if-needed.d.ts.map +0 -1
  481. package/lib/typescript/module/core/services/multi-payment-rules-presenter.d.ts +0 -9
  482. package/lib/typescript/module/core/services/multi-payment-rules-presenter.d.ts.map +0 -1
  483. package/lib/typescript/module/core/services/payment-flow-controller.d.ts +0 -146
  484. package/lib/typescript/module/core/services/payment-flow-controller.d.ts.map +0 -1
  485. package/lib/typescript/module/core/services/payment-flow-state.d.ts +0 -64
  486. package/lib/typescript/module/core/services/payment-flow-state.d.ts.map +0 -1
  487. package/lib/typescript/module/core/services/payment-result-mapper.d.ts +0 -5
  488. package/lib/typescript/module/core/services/payment-result-mapper.d.ts.map +0 -1
  489. package/lib/typescript/module/core/services/presentation-utils.d.ts +0 -5
  490. package/lib/typescript/module/core/services/presentation-utils.d.ts.map +0 -1
  491. package/lib/typescript/module/core/services/redirect-buffer.d.ts +0 -6
  492. package/lib/typescript/module/core/services/redirect-buffer.d.ts.map +0 -1
  493. package/lib/typescript/module/core/services/user-friendly-messages.d.ts +0 -6
  494. package/lib/typescript/module/core/services/user-friendly-messages.d.ts.map +0 -1
  495. package/lib/typescript/module/internal/telemetry-collector.d.ts +0 -2
  496. package/lib/typescript/module/internal/telemetry-collector.d.ts.map +0 -1
  497. package/lib/typescript/module/public/constants.d.ts +0 -12
  498. package/lib/typescript/module/public/constants.d.ts.map +0 -1
  499. package/lib/typescript/module/public/spare-link-callbacks.d.ts +0 -14
  500. package/lib/typescript/module/public/spare-link-callbacks.d.ts.map +0 -1
  501. package/lib/typescript/module/ui/consent/charge-bearer-display.d.ts +0 -5
  502. package/lib/typescript/module/ui/consent/charge-bearer-display.d.ts.map +0 -1
  503. package/lib/typescript/module/ui/consent/consent-accordion.d.ts +0 -10
  504. package/lib/typescript/module/ui/consent/consent-accordion.d.ts.map +0 -1
  505. package/lib/typescript/module/ui/consent/consent-summary-section.d.ts +0 -6
  506. package/lib/typescript/module/ui/consent/consent-summary-section.d.ts.map +0 -1
  507. package/lib/typescript/module/ui/consent/cop-information.d.ts +0 -6
  508. package/lib/typescript/module/ui/consent/cop-information.d.ts.map +0 -1
  509. package/lib/typescript/module/ui/consent/international-payment-summary.d.ts +0 -6
  510. package/lib/typescript/module/ui/consent/international-payment-summary.d.ts.map +0 -1
  511. package/lib/typescript/module/ui/consent/label-value-rows.d.ts +0 -10
  512. package/lib/typescript/module/ui/consent/label-value-rows.d.ts.map +0 -1
  513. package/lib/typescript/module/ui/consent/multi-payment-rules-list.d.ts +0 -15
  514. package/lib/typescript/module/ui/consent/multi-payment-rules-list.d.ts.map +0 -1
  515. package/lib/typescript/module/ui/consent/multi-payment-summary.d.ts +0 -6
  516. package/lib/typescript/module/ui/consent/multi-payment-summary.d.ts.map +0 -1
  517. package/lib/typescript/module/ui/consent/single-payment-summary.d.ts +0 -6
  518. package/lib/typescript/module/ui/consent/single-payment-summary.d.ts.map +0 -1
  519. package/lib/typescript/module/ui/consent/terms-link.d.ts +0 -2
  520. package/lib/typescript/module/ui/consent/terms-link.d.ts.map +0 -1
  521. package/lib/typescript/module/ui/hooks/use-payment-flow-state.d.ts +0 -9
  522. package/lib/typescript/module/ui/hooks/use-payment-flow-state.d.ts.map +0 -1
  523. package/lib/typescript/module/ui/payment-flow-page.d.ts +0 -20
  524. package/lib/typescript/module/ui/payment-flow-page.d.ts.map +0 -1
  525. package/lib/typescript/module/ui/screens/bank-selection-screen.d.ts +0 -15
  526. package/lib/typescript/module/ui/screens/bank-selection-screen.d.ts.map +0 -1
  527. package/lib/typescript/module/ui/screens/consent-details-screen.d.ts +0 -13
  528. package/lib/typescript/module/ui/screens/consent-details-screen.d.ts.map +0 -1
  529. package/lib/typescript/module/ui/screens/mandate-setup-success-screen.d.ts +0 -10
  530. package/lib/typescript/module/ui/screens/mandate-setup-success-screen.d.ts.map +0 -1
  531. package/lib/typescript/module/ui/widgets/layout-w-header.d.ts +0 -20
  532. package/lib/typescript/module/ui/widgets/layout-w-header.d.ts.map +0 -1
  533. package/lib/typescript/module/ui/widgets/stepper.d.ts +0 -15
  534. package/lib/typescript/module/ui/widgets/stepper.d.ts.map +0 -1
  535. package/src/core/client/link-api-client.ts +0 -414
  536. package/src/core/errors/payment-api-error.ts +0 -35
  537. package/src/core/models/link-session-status.ts +0 -7
  538. package/src/core/models/payment-type.ts +0 -54
  539. package/src/core/models/wire-mappers.ts +0 -315
  540. package/src/core/services/consent-presenter.ts +0 -213
  541. package/src/core/services/execute-resume-if-needed.ts +0 -243
  542. package/src/core/services/multi-payment-rules-presenter.ts +0 -158
  543. package/src/core/services/payment-flow-controller.ts +0 -607
  544. package/src/core/services/payment-flow-state.ts +0 -124
  545. package/src/core/services/payment-result-mapper.ts +0 -41
  546. package/src/core/services/presentation-utils.ts +0 -4
  547. package/src/core/services/redirect-buffer.ts +0 -34
  548. package/src/core/services/user-friendly-messages.ts +0 -39
  549. package/src/internal/telemetry-collector.ts +0 -90
  550. package/src/public/constants.ts +0 -14
  551. package/src/public/spare-link-callbacks.ts +0 -20
  552. package/src/ui/consent/charge-bearer-display.tsx +0 -68
  553. package/src/ui/consent/consent-accordion.tsx +0 -89
  554. package/src/ui/consent/consent-summary-section.tsx +0 -19
  555. package/src/ui/consent/cop-information.tsx +0 -121
  556. package/src/ui/consent/international-payment-summary.tsx +0 -83
  557. package/src/ui/consent/label-value-rows.tsx +0 -50
  558. package/src/ui/consent/multi-payment-rules-list.tsx +0 -138
  559. package/src/ui/consent/multi-payment-summary.tsx +0 -82
  560. package/src/ui/consent/single-payment-summary.tsx +0 -123
  561. package/src/ui/consent/terms-link.tsx +0 -27
  562. package/src/ui/hooks/use-payment-flow-state.ts +0 -16
  563. package/src/ui/payment-flow-page.tsx +0 -254
  564. package/src/ui/screens/bank-selection-screen.tsx +0 -209
  565. package/src/ui/screens/consent-details-screen.tsx +0 -106
  566. package/src/ui/screens/mandate-setup-success-screen.tsx +0 -72
  567. package/src/ui/widgets/layout-w-header.tsx +0 -89
  568. package/src/ui/widgets/stepper.tsx +0 -126
@@ -1,607 +0,0 @@
1
- import { createLogger } from '../../internal/logger';
2
- import { redactPaymentReturnUri } from '../../internal/redact-uri';
3
- import {
4
- DEFAULT_AWAITING_CALLBACK_POLL_MS,
5
- DEFAULT_AWAITING_CALLBACK_TIMEOUT_MS,
6
- } from '../../public/constants';
7
- import type { PaymentEnvironment } from '../../public/spare-link-config';
8
- /** Simple string tag for internal controller callbacks — not the public SpareLinkEvent. */
9
- type PaymentFlowEventTag =
10
- | 'initialized'
11
- | 'sessionLoaded'
12
- | 'consentStarted'
13
- | 'redirectToBank'
14
- | 'bankCallbackReceived'
15
- | 'succeeded'
16
- | 'failed'
17
- | 'cancelled'
18
- | 'abandoned';
19
- import type { LinkApiClient } from '../client/link-api-client';
20
- import { isPaymentApiError } from '../errors/payment-api-error';
21
- import type { ConsentResponse, CopResponse, LinkSessionResponse, ProviderSummary } from '../models';
22
- import { isBankCallbackReceivedStatus } from '../models/link-session-status';
23
- import { extractPaymentReturnErrorCode } from '../models/payment-return-params';
24
- import { supportsConfirmationOfPayee } from '../models/payment-type';
25
- import {
26
- type PaymentFlowPhase,
27
- type PaymentFlowState,
28
- PaymentFlowStates,
29
- } from './payment-flow-state';
30
- import type { PendingSessionStore } from './pending-session-store';
31
-
32
- /** Minimum surface required from a `Clock` injected for testability. */
33
- export interface Clock {
34
- now(): number;
35
- }
36
-
37
- const REAL_CLOCK: Clock = { now: () => Date.now() };
38
-
39
- /**
40
- * Number of consecutive `pollStatus` transport failures we tolerate before
41
- * giving up and transitioning to `failed('network_error')`. Bounds the request
42
- * volume against a flaky network during the 5-minute awaiting-callback window.
43
- */
44
- const POLL_STATUS_MAX_CONSECUTIVE_FAILURES = 5;
45
- const log = createLogger('PaymentFlowController');
46
-
47
- export interface PaymentFlowControllerOptions {
48
- sessionToken: string;
49
- apiClient: LinkApiClient;
50
- pendingSessionStore?: PendingSessionStore;
51
- awaitingCallbackTimeoutMs?: number;
52
- /**
53
- * Deployment environment. In `sandbox`, the controller treats a non-terminal
54
- * `/link/status` response during awaitingCallback as success: the sandbox bank
55
- * authorizes consent but never settles the payment, so the status endpoint
56
- * stays non-terminal forever and the flow could otherwise only ever time out.
57
- * Production keeps strict terminal-only behavior. Defaults to `production`.
58
- */
59
- environment?: PaymentEnvironment;
60
- /**
61
- * Interval for the sandbox awaiting-callback status poll. Ignored outside
62
- * sandbox. Defaults to {@link DEFAULT_AWAITING_CALLBACK_POLL_MS}.
63
- */
64
- awaitingCallbackPollMs?: number;
65
- /** Optional clock injection for deterministic timeout tests. */
66
- clock?: Clock;
67
- /** Telemetry collector — called once before POST /link/consent. */
68
- collectTelemetry?: () => Promise<Record<string, unknown>>;
69
- /** UUID generator used for the consent Idempotency-Key. */
70
- uuid?: () => string;
71
- /** Callback for internal flow event tags. Exceptions are swallowed. */
72
- onEvent?: (event: PaymentFlowEventTag) => void;
73
- }
74
-
75
- type Listener = (state: PaymentFlowState) => void;
76
-
77
- const TERMINAL_PHASES = new Set<PaymentFlowPhase>(['succeeded', 'failed', 'cancelled']);
78
-
79
- function isTerminal(phase: PaymentFlowPhase): boolean {
80
- return TERMINAL_PHASES.has(phase);
81
- }
82
-
83
- /**
84
- * Drives the payment flow state machine. Exposes a `subscribe`/`unsubscribe`
85
- * API so React's `useSyncExternalStore` can bridge to a hook.
86
- *
87
- * `subscribe` fires the listener synchronously with the current state so new
88
- * subscribers don't miss the initial snapshot.
89
- */
90
- export class PaymentFlowController {
91
- readonly sessionToken: string;
92
- readonly apiClient: LinkApiClient;
93
- readonly pendingSessionStore?: PendingSessionStore;
94
-
95
- private readonly awaitingCallbackTimeoutMs: number;
96
- private readonly environment: PaymentEnvironment;
97
- private readonly awaitingCallbackPollMs: number;
98
- private readonly clock: Clock;
99
- private readonly collectTelemetry?: () => Promise<Record<string, unknown>>;
100
- private readonly uuid: () => string;
101
- private readonly onEventCallback?: (event: PaymentFlowEventTag) => void;
102
-
103
- private _state: PaymentFlowState = PaymentFlowStates.idle();
104
- private _listeners = new Set<Listener>();
105
- private _consentIdempotencyKey: string | undefined;
106
- private _callbackTimer: ReturnType<typeof setTimeout> | undefined;
107
- private _awaitingCallbackStartedAtMs: number | undefined;
108
- /** Last provider the user selected — retained so success/awaiting states that
109
- * arrive without it (poll/callback) can still report `bankId`. */
110
- private _selectedProvider: ProviderSummary | undefined;
111
- private _disposed = false;
112
- /** Re-entrance guard — second `hydrate()` returns the in-flight promise. */
113
- private _hydratePromise: Promise<void> | undefined;
114
- /** Consecutive `pollStatus` transport failures since the last successful response. */
115
- private _pollStatusConsecutiveFailures = 0;
116
-
117
- constructor(opts: PaymentFlowControllerOptions) {
118
- this.sessionToken = opts.sessionToken;
119
- this.apiClient = opts.apiClient;
120
- if (opts.pendingSessionStore) this.pendingSessionStore = opts.pendingSessionStore;
121
- this.awaitingCallbackTimeoutMs =
122
- opts.awaitingCallbackTimeoutMs ?? DEFAULT_AWAITING_CALLBACK_TIMEOUT_MS;
123
- this.environment = opts.environment ?? 'production';
124
- this.awaitingCallbackPollMs = opts.awaitingCallbackPollMs ?? DEFAULT_AWAITING_CALLBACK_POLL_MS;
125
- this.clock = opts.clock ?? REAL_CLOCK;
126
- if (opts.collectTelemetry) this.collectTelemetry = opts.collectTelemetry;
127
- this.uuid = opts.uuid ?? fallbackUuid;
128
- if (opts.onEvent) this.onEventCallback = opts.onEvent;
129
- }
130
-
131
- // ---- Subscription API ----------------------------------------------------
132
-
133
- get state(): PaymentFlowState {
134
- return this._state;
135
- }
136
-
137
- get awaitingCallbackStartedAtMs(): number | undefined {
138
- return this._awaitingCallbackStartedAtMs;
139
- }
140
-
141
- /**
142
- * Register a listener. The listener is invoked synchronously with the
143
- * current state so new subscribers have the initial snapshot, then again
144
- * on every subsequent change.
145
- */
146
- subscribe(listener: Listener): () => void {
147
- this._listeners.add(listener);
148
- try {
149
- listener(this._state);
150
- } catch {
151
- // swallow — listener bugs never break the controller
152
- }
153
- return () => {
154
- this._listeners.delete(listener);
155
- };
156
- }
157
-
158
- private setState(next: PaymentFlowState): void {
159
- if (this._disposed) return;
160
- this._state = next;
161
- if (isTerminal(next.phase)) {
162
- this.cancelCallbackTimeout();
163
- this._consentIdempotencyKey = undefined;
164
- }
165
- for (const l of this._listeners) {
166
- try {
167
- l(next);
168
- } catch {
169
- // listener exceptions never break the controller
170
- }
171
- }
172
- }
173
-
174
- fireEvent(event: PaymentFlowEventTag): void {
175
- try {
176
- this.onEventCallback?.(event);
177
- } catch {
178
- // swallow integrator errors
179
- }
180
- }
181
-
182
- // ---- Timers --------------------------------------------------------------
183
-
184
- private cancelCallbackTimeout(): void {
185
- if (this._callbackTimer) {
186
- clearTimeout(this._callbackTimer);
187
- this._callbackTimer = undefined;
188
- }
189
- }
190
-
191
- private startCallbackTimeout(): void {
192
- this.cancelCallbackTimeout();
193
- this._callbackTimer = setTimeout(() => {
194
- if (this._state.phase !== 'awaitingCallback') return;
195
- void this.reportError('session_timeout');
196
- }, this.awaitingCallbackTimeoutMs);
197
- }
198
-
199
- // ---- Phase transitions ---------------------------------------------------
200
-
201
- /**
202
- * `GET /link` + `GET /link/providers`, then transitions to bankSelection.
203
- * Re-entrant: a second concurrent call returns the in-flight promise instead
204
- * of firing duplicate requests.
205
- */
206
- hydrate(): Promise<void> {
207
- if (this._disposed) return Promise.resolve();
208
- if (this._hydratePromise) return this._hydratePromise;
209
- this._hydratePromise = this._doHydrate().finally(() => {
210
- this._hydratePromise = undefined;
211
- });
212
- return this._hydratePromise;
213
- }
214
-
215
- private async _doHydrate(): Promise<void> {
216
- log.info('hydrate: starting session hydration');
217
- this.setState(PaymentFlowStates.hydrating());
218
- try {
219
- const [session, providers] = await Promise.all([
220
- this.apiClient.getSession(this.sessionToken),
221
- this.apiClient.getProviders(this.sessionToken),
222
- ]);
223
- log.info(`hydrate: loaded session with ${providers.length} provider(s)`);
224
- this.setState(PaymentFlowStates.bankSelection({ session, providers }));
225
- this.fireEvent('sessionLoaded');
226
- } catch (err) {
227
- log.severe(`hydrate: failed — ${err instanceof Error ? err.message : String(err)}`);
228
- const code = isPaymentApiError(err) ? err.code : 'hydration_error';
229
- const message = err instanceof Error ? err.message : String(err);
230
- this.setState(PaymentFlowStates.failed({ errorCode: code, errorMessage: message }));
231
- throw err;
232
- }
233
- }
234
-
235
- /** Move bankSelection → consentDetails. */
236
- selectBank(bankId: string): void {
237
- log.info(`selectBank: bankId=${bankId}`);
238
- const current = this._state;
239
- const session = current.session;
240
- if (!session) {
241
- throw new Error('Cannot select bank before session is loaded.');
242
- }
243
- const provider = current.providers.find((p) => p.id === bankId);
244
- if (!provider) {
245
- log.severe(`selectBank: unknown bankId=${bankId}`);
246
- throw new Error(`Unknown bank id: ${bankId}`);
247
- }
248
- // Retained so success states reached via poll/callback (which don't carry
249
- // the provider) still resolve a `bankId` in the PaymentResult.
250
- this._selectedProvider = provider;
251
- const willLoadCop = this.shouldPerformCop(session);
252
- this.setState(
253
- PaymentFlowStates.consentDetails({
254
- session,
255
- selectedProvider: provider,
256
- isCopLoading: willLoadCop,
257
- copApplicable: willLoadCop,
258
- }),
259
- );
260
- if (willLoadCop) {
261
- this.loadCopInBackground(session, provider);
262
- }
263
- }
264
-
265
- /**
266
- * Best-effort Confirmation-of-Payee fetch — never blocks {@link selectBank}
267
- * or fails the flow. Mirrors the Flutter controller: gated to UAE + un-verified
268
- * sessions, and the result is merged into the consentDetails state only if the
269
- * user is still on that screen for the same provider. Ported from
270
- * `payment_flow_controller.dart:_loadCopInBackground`.
271
- */
272
- private loadCopInBackground(session: LinkSessionResponse, provider: ProviderSummary): void {
273
- void (async () => {
274
- const cop = await this.getCoP(provider.id);
275
- if (this._state.phase !== 'consentDetails') return;
276
- if (this._state.selectedProvider?.id !== provider.id) return;
277
- this.setState(
278
- PaymentFlowStates.consentDetails({
279
- session,
280
- selectedProvider: provider,
281
- ...(cop ? { copResponse: cop } : {}),
282
- isCopLoading: false,
283
- copApplicable: true,
284
- }),
285
- );
286
- })();
287
- }
288
-
289
- private shouldPerformCop(session: LinkSessionResponse): boolean {
290
- if (this.apiClient.tenantHeader !== 'UAE') return false;
291
- if (session.request.isCopVerified === true) return false;
292
- if (!supportsConfirmationOfPayee(session.request)) return false;
293
- return true;
294
- }
295
-
296
- /** `POST /link/consent`, persists pending record, transitions to redirecting. */
297
- async confirmConsent(): Promise<void> {
298
- log.info('confirmConsent: posting consent');
299
- const selectedProvider = this._state.selectedProvider;
300
- if (!selectedProvider) {
301
- log.severe('confirmConsent: no provider selected');
302
- throw new Error('Cannot confirm consent without a selected provider.');
303
- }
304
- this.fireEvent('consentStarted');
305
-
306
- if (!this._consentIdempotencyKey) {
307
- this._consentIdempotencyKey = this.uuid();
308
- }
309
-
310
- // Best-effort telemetry before posting consent.
311
- await this.postTelemetryAutomatic();
312
-
313
- let consent: ConsentResponse;
314
- try {
315
- consent = await this.apiClient.postConsent({
316
- linkToken: this.sessionToken,
317
- bankId: selectedProvider.id,
318
- idempotencyKey: this._consentIdempotencyKey,
319
- });
320
- } catch (err) {
321
- // Without this the flow would be stranded in `consentDetails` with no
322
- // terminal state — the caller's catch assumes we already transitioned.
323
- const code = isPaymentApiError(err) ? err.code : 'consent_failed';
324
- const message = err instanceof Error ? err.message : String(err);
325
- this.setState(PaymentFlowStates.failed({ errorCode: code, errorMessage: message }));
326
- void this.patchTokenBestEffort('error', code);
327
- throw err;
328
- }
329
-
330
- if (this.pendingSessionStore) {
331
- try {
332
- const merchantRef = this._state.session?.request?.merchantReference;
333
- await this.pendingSessionStore.save({
334
- sessionId: this.sessionToken,
335
- selectedBankId: selectedProvider.id,
336
- authorizationUrl: consent.redirectUrl,
337
- consentAt: this.clock.now(),
338
- recoveryAttempts: 0,
339
- ...(merchantRef ? { merchantRef } : {}),
340
- });
341
- } catch {
342
- log.warning('confirmConsent: store.save() failed — continuing');
343
- // store failures should not block the flow
344
- }
345
- }
346
-
347
- log.info('confirmConsent: → redirecting');
348
- this.setState(PaymentFlowStates.redirecting({ consent, selectedProvider }));
349
- }
350
-
351
- /**
352
- * Parses a callback URI and transitions to succeeded / failed. Accepts either
353
- * a `URL` instance or a string. A malformed URI resolves to
354
- * `failed('invalid_callback')` instead of throwing.
355
- */
356
- handleCallback(uri: URL | string): void {
357
- log.info(
358
- `handleCallback: received URI=${redactPaymentReturnUri(typeof uri === 'string' ? uri : uri.toString())}`,
359
- );
360
- // Deep-link callbacks are commonly re-delivered (cold start + warm
361
- // foreground). Once the flow is terminal, ignore further callbacks so we
362
- // never re-transition and re-fire terminal callbacks.
363
- if (isTerminal(this._state.phase)) return;
364
- let url: URL;
365
- if (typeof uri === 'string') {
366
- try {
367
- url = new URL(uri);
368
- } catch {
369
- this.setState(
370
- PaymentFlowStates.failed({
371
- errorCode: 'invalid_callback',
372
- errorMessage: 'The callback URI could not be parsed.',
373
- }),
374
- );
375
- return;
376
- }
377
- } else {
378
- url = uri;
379
- }
380
-
381
- this.fireEvent('bankCallbackReceived');
382
- const params = url.searchParams;
383
-
384
- // Prefer the new `error_code` query param over legacy `error`. Also accept
385
- // `status=failure` with no other code as `authorize_failed`.
386
- const error = extractPaymentReturnErrorCode(params);
387
- if (error) {
388
- const description = params.get('error_description') ?? undefined;
389
- this.setState(
390
- PaymentFlowStates.failed({
391
- errorCode: error,
392
- ...(description ? { errorMessage: description } : {}),
393
- }),
394
- );
395
- return;
396
- }
397
-
398
- const exchangeCode = params.get('exchange_code') ?? undefined;
399
- const linkSessionId = params.get('session_id') ?? undefined;
400
- const merchantRef = params.get('merchantRef') ?? undefined;
401
- if (exchangeCode) {
402
- this.setState(
403
- PaymentFlowStates.succeeded({
404
- exchangeCode,
405
- ...(linkSessionId ? { linkSessionId } : {}),
406
- ...(merchantRef ? { merchantRef } : {}),
407
- ...(this._selectedProvider ? { selectedProvider: this._selectedProvider } : {}),
408
- ...(this._state.session ? { session: this._state.session } : {}),
409
- }),
410
- );
411
- return;
412
- }
413
-
414
- this.setState(
415
- PaymentFlowStates.failed({
416
- errorCode: 'invalid_callback',
417
- errorMessage: 'The callback URI is missing required parameters.',
418
- }),
419
- );
420
- }
421
-
422
- /** Best-effort cancel — PATCH /link with action=cancel, then transitions to cancelled. */
423
- async cancel(): Promise<void> {
424
- log.info('cancel: user cancelled the payment flow');
425
- await this.patchTokenBestEffort('cancel');
426
- this.setState(PaymentFlowStates.cancelled());
427
- }
428
-
429
- /** Best-effort error report — sets failed state immediately, PATCH is fire-and-forget. */
430
- async reportError(code: string): Promise<void> {
431
- log.severe(`reportError: reporting error code=${code}`);
432
- this.setState(PaymentFlowStates.failed({ errorCode: code }));
433
- // Fire-and-forget; we already transitioned.
434
- void this.patchTokenBestEffort('error', code);
435
- }
436
-
437
- private async patchTokenBestEffort(
438
- action: 'cancel' | 'error',
439
- errorCode?: string,
440
- ): Promise<void> {
441
- try {
442
- await this.apiClient.patchToken({
443
- linkToken: this.sessionToken,
444
- action,
445
- ...(errorCode ? { errorCode } : {}),
446
- });
447
- } catch {
448
- // swallow — PATCH is best-effort
449
- }
450
- }
451
-
452
- /**
453
- * UI calls this after handing off to the bank — starts the 5-minute timeout
454
- * and pins the awaiting-callback start time.
455
- */
456
- setAwaitingCallbackState(args: { providerName?: string } = {}): void {
457
- this._awaitingCallbackStartedAtMs ??= this.clock.now();
458
- this.setState(
459
- PaymentFlowStates.awaitingCallback({
460
- ...(args.providerName ? { providerName: args.providerName } : {}),
461
- ...(this._state.session ? { session: this._state.session } : {}),
462
- ...(this._selectedProvider ? { selectedProvider: this._selectedProvider } : {}),
463
- }),
464
- );
465
- this.startCallbackTimeout();
466
- }
467
-
468
- /**
469
- * Best-effort status polling. Transitions to a terminal state on
470
- * `completed | failed | cancelled | expired`; otherwise leaves the flow in
471
- * the current phase. After {@link POLL_STATUS_MAX_CONSECUTIVE_FAILURES}
472
- * consecutive transport failures the controller gives up with
473
- * `failed('network_error')` to stop hammering an unreachable backend.
474
- */
475
- async pollStatus(): Promise<void> {
476
- // A status response can land after a bank callback or the timeout has
477
- // already resolved the flow; never overwrite a terminal state.
478
- if (isTerminal(this._state.phase)) return;
479
- try {
480
- const status = await this.apiClient.getStatus(this.sessionToken);
481
- this._pollStatusConsecutiveFailures = 0;
482
- // Re-check: the await above yields, so a terminal callback may have
483
- // arrived while the request was in flight.
484
- if (isTerminal(this._state.phase)) return;
485
- switch (status.status) {
486
- case 'completed':
487
- this.setState(
488
- PaymentFlowStates.succeeded({
489
- ...(status.linkSessionId ? { linkSessionId: status.linkSessionId } : {}),
490
- ...(this._selectedProvider ? { selectedProvider: this._selectedProvider } : {}),
491
- ...(this._state.session ? { session: this._state.session } : {}),
492
- }),
493
- );
494
- return;
495
- case 'failed':
496
- this.setState(
497
- PaymentFlowStates.failed({ errorCode: status.failureCode ?? 'session_failed' }),
498
- );
499
- return;
500
- case 'cancelled':
501
- this.setState(PaymentFlowStates.cancelled());
502
- return;
503
- case 'expired':
504
- this.setState(PaymentFlowStates.failed({ errorCode: 'session_expired' }));
505
- return;
506
- default:
507
- // Non-terminal. In sandbox, only treat `callback_received` as success —
508
- // the bank has actually returned. `redirected` means consent was posted
509
- // but the user may not have authorized yet; auto-success there caused
510
- // false positives on cold-start recovery.
511
- if (
512
- this.environment === 'sandbox' &&
513
- this._state.phase === 'awaitingCallback' &&
514
- isBankCallbackReceivedStatus(status.status)
515
- ) {
516
- this.setState(
517
- PaymentFlowStates.succeeded({
518
- ...(status.linkSessionId ? { linkSessionId: status.linkSessionId } : {}),
519
- ...(this._selectedProvider ? { selectedProvider: this._selectedProvider } : {}),
520
- ...(this._state.session ? { session: this._state.session } : {}),
521
- }),
522
- );
523
- }
524
- return;
525
- }
526
- } catch {
527
- this._pollStatusConsecutiveFailures += 1;
528
- log.warning(
529
- `pollStatus: failed (${this._pollStatusConsecutiveFailures}/${POLL_STATUS_MAX_CONSECUTIVE_FAILURES})`,
530
- );
531
- if (this._pollStatusConsecutiveFailures >= POLL_STATUS_MAX_CONSECUTIVE_FAILURES) {
532
- if (isTerminal(this._state.phase) || this._state.phase !== 'awaitingCallback') return;
533
- this.setState(
534
- PaymentFlowStates.failed({
535
- errorCode: 'network_error',
536
- errorMessage: 'Unable to reach the Spare backend after multiple attempts.',
537
- }),
538
- );
539
- }
540
- }
541
- }
542
-
543
- /** Best-effort telemetry — never throws, never changes state. */
544
- async postTelemetry(payload: Record<string, unknown>): Promise<void> {
545
- try {
546
- await this.apiClient.postTelemetry({ linkToken: this.sessionToken, payload });
547
- } catch (err) {
548
- log.warning(
549
- `postTelemetry: best-effort telemetry failed — ${err instanceof Error ? err.message : String(err)}`,
550
- );
551
- }
552
- }
553
-
554
- /** Best-effort CoP — returns result or null on failure. */
555
- async getCoP(providerId?: string): Promise<CopResponse | null> {
556
- try {
557
- return await this.apiClient.getConfirmPayee(this.sessionToken, providerId);
558
- } catch {
559
- return null;
560
- }
561
- }
562
-
563
- private async postTelemetryAutomatic(): Promise<void> {
564
- if (!this.collectTelemetry) return;
565
- log.fine('postTelemetryAutomatic: collecting and posting device telemetry');
566
- try {
567
- const payload = await this.collectTelemetry();
568
- await this.apiClient.postTelemetry({ linkToken: this.sessionToken, payload });
569
- } catch (err) {
570
- log.warning(
571
- `postTelemetryAutomatic: failed — ${err instanceof Error ? err.message : String(err)}`,
572
- );
573
- }
574
- }
575
-
576
- /** Returns the active providers list — convenience for the UI layer. */
577
- get providers(): ProviderSummary[] {
578
- return this._state.providers;
579
- }
580
-
581
- /** Returns the active session, if any. */
582
- get session(): LinkSessionResponse | undefined {
583
- return this._state.session;
584
- }
585
-
586
- /**
587
- * Releases resources: cancels timers, clears listeners, and aborts the
588
- * underlying API client's in-flight fetches. Idempotent.
589
- */
590
- dispose(): void {
591
- if (this._disposed) return;
592
- log.info('dispose: releasing apiClient');
593
- this._disposed = true;
594
- this.cancelCallbackTimeout();
595
- this._listeners.clear();
596
- this.apiClient.dispose();
597
- }
598
- }
599
-
600
- function fallbackUuid(): string {
601
- const bytes = new Uint8Array(16);
602
- for (let i = 0; i < 16; i += 1) bytes[i] = Math.floor(Math.random() * 256);
603
- bytes[6] = ((bytes[6] ?? 0) & 0x0f) | 0x40;
604
- bytes[8] = ((bytes[8] ?? 0) & 0x3f) | 0x80;
605
- const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');
606
- return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
607
- }