@spare-technologies/spare-link 0.1.0-beta.1 → 1.0.0

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 (561) 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/hosted/bridge-message.js +107 -0
  13. package/lib/commonjs/internal/hosted/bridge-message.js.map +1 -0
  14. package/lib/commonjs/internal/hosted/hosted-url.js +41 -0
  15. package/lib/commonjs/internal/hosted/hosted-url.js.map +1 -0
  16. package/lib/commonjs/internal/index.js +0 -7
  17. package/lib/commonjs/internal/index.js.map +1 -1
  18. package/lib/commonjs/internal/redact-uri.js +59 -15
  19. package/lib/commonjs/internal/redact-uri.js.map +1 -1
  20. package/lib/commonjs/internal/secure-store-pending-session-store.js +20 -25
  21. package/lib/commonjs/internal/secure-store-pending-session-store.js.map +1 -1
  22. package/lib/commonjs/internal/url-parts.js +145 -0
  23. package/lib/commonjs/internal/url-parts.js.map +1 -0
  24. package/lib/commonjs/public/index.js +0 -37
  25. package/lib/commonjs/public/index.js.map +1 -1
  26. package/lib/commonjs/public/payment-result.js +16 -4
  27. package/lib/commonjs/public/payment-result.js.map +1 -1
  28. package/lib/commonjs/public/recovery-result.js +7 -18
  29. package/lib/commonjs/public/recovery-result.js.map +1 -1
  30. package/lib/commonjs/public/spare-link-config.js +41 -16
  31. package/lib/commonjs/public/spare-link-config.js.map +1 -1
  32. package/lib/commonjs/public/spare-link-event.js +27 -33
  33. package/lib/commonjs/public/spare-link-event.js.map +1 -1
  34. package/lib/commonjs/public/spare-link-instance.js +67 -77
  35. package/lib/commonjs/public/spare-link-instance.js.map +1 -1
  36. package/lib/commonjs/public/spare-link-session.js +2 -9
  37. package/lib/commonjs/public/spare-link-session.js.map +1 -1
  38. package/lib/commonjs/public/spare-link.js +0 -12
  39. package/lib/commonjs/public/spare-link.js.map +1 -1
  40. package/lib/commonjs/ui/hooks/{use-payment-flow-state.js → use-hosted-flow-state.js} +4 -4
  41. package/lib/commonjs/ui/hooks/use-hosted-flow-state.js.map +1 -0
  42. package/lib/commonjs/ui/hosted/hosted-payment-page.js +177 -0
  43. package/lib/commonjs/ui/hosted/hosted-payment-page.js.map +1 -0
  44. package/lib/commonjs/ui/hosted/hosted-payment-webview.js +168 -0
  45. package/lib/commonjs/ui/hosted/hosted-payment-webview.js.map +1 -0
  46. package/lib/commonjs/ui/screens/index.js +3 -17
  47. package/lib/commonjs/ui/screens/index.js.map +1 -1
  48. package/lib/commonjs/ui/screens/page-unavailable-screen.js +101 -0
  49. package/lib/commonjs/ui/screens/page-unavailable-screen.js.map +1 -0
  50. package/lib/commonjs/ui/spare-link-host.js +220 -234
  51. package/lib/commonjs/ui/spare-link-host.js.map +1 -1
  52. package/lib/commonjs/ui/widgets/index.js +3 -10
  53. package/lib/commonjs/ui/widgets/index.js.map +1 -1
  54. package/lib/commonjs/version.js +1 -1
  55. package/lib/commonjs/version.js.map +1 -1
  56. package/lib/module/core/models/payment-return-params.js +235 -20
  57. package/lib/module/core/models/payment-return-params.js.map +1 -1
  58. package/lib/module/core/models/pending-session-record.js +2 -0
  59. package/lib/module/core/models/pending-session-record.js.map +1 -0
  60. package/lib/module/core/services/hosted-flow-controller.js +328 -0
  61. package/lib/module/core/services/hosted-flow-controller.js.map +1 -0
  62. package/lib/module/core/services/hosted-flow-state.js +91 -0
  63. package/lib/module/core/services/hosted-flow-state.js.map +1 -0
  64. package/lib/module/index.js +8 -22
  65. package/lib/module/index.js.map +1 -1
  66. package/lib/module/internal/hosted/bridge-message.js +104 -0
  67. package/lib/module/internal/hosted/bridge-message.js.map +1 -0
  68. package/lib/module/internal/hosted/hosted-url.js +36 -0
  69. package/lib/module/internal/hosted/hosted-url.js.map +1 -0
  70. package/lib/module/internal/index.js +0 -1
  71. package/lib/module/internal/index.js.map +1 -1
  72. package/lib/module/internal/redact-uri.js +59 -15
  73. package/lib/module/internal/redact-uri.js.map +1 -1
  74. package/lib/module/internal/secure-store-pending-session-store.js +20 -25
  75. package/lib/module/internal/secure-store-pending-session-store.js.map +1 -1
  76. package/lib/module/internal/url-parts.js +139 -0
  77. package/lib/module/internal/url-parts.js.map +1 -0
  78. package/lib/module/public/index.js +2 -3
  79. package/lib/module/public/index.js.map +1 -1
  80. package/lib/module/public/payment-result.js +16 -4
  81. package/lib/module/public/payment-result.js.map +1 -1
  82. package/lib/module/public/recovery-result.js +7 -17
  83. package/lib/module/public/recovery-result.js.map +1 -1
  84. package/lib/module/public/spare-link-config.js +42 -15
  85. package/lib/module/public/spare-link-config.js.map +1 -1
  86. package/lib/module/public/spare-link-event.js +27 -33
  87. package/lib/module/public/spare-link-event.js.map +1 -1
  88. package/lib/module/public/spare-link-instance.js +68 -72
  89. package/lib/module/public/spare-link-instance.js.map +1 -1
  90. package/lib/module/public/spare-link-session.js +2 -9
  91. package/lib/module/public/spare-link-session.js.map +1 -1
  92. package/lib/module/public/spare-link.js +1 -1
  93. package/lib/module/public/spare-link.js.map +1 -1
  94. package/lib/module/ui/hooks/{use-payment-flow-state.js → use-hosted-flow-state.js} +3 -3
  95. package/lib/module/ui/hooks/use-hosted-flow-state.js.map +1 -0
  96. package/lib/module/ui/hosted/hosted-payment-page.js +175 -0
  97. package/lib/module/ui/hosted/hosted-payment-page.js.map +1 -0
  98. package/lib/module/ui/hosted/hosted-payment-webview.js +163 -0
  99. package/lib/module/ui/hosted/hosted-payment-webview.js.map +1 -0
  100. package/lib/module/ui/screens/index.js +1 -3
  101. package/lib/module/ui/screens/index.js.map +1 -1
  102. package/lib/module/ui/screens/page-unavailable-screen.js +97 -0
  103. package/lib/module/ui/screens/page-unavailable-screen.js.map +1 -0
  104. package/lib/module/ui/spare-link-host.js +221 -236
  105. package/lib/module/ui/spare-link-host.js.map +1 -1
  106. package/lib/module/ui/widgets/index.js +1 -2
  107. package/lib/module/ui/widgets/index.js.map +1 -1
  108. package/lib/module/version.js +1 -1
  109. package/lib/module/version.js.map +1 -1
  110. package/lib/typescript/commonjs/core/models/index.d.ts +1 -123
  111. package/lib/typescript/commonjs/core/models/index.d.ts.map +1 -1
  112. package/lib/typescript/commonjs/core/models/payment-return-params.d.ts +91 -8
  113. package/lib/typescript/commonjs/core/models/payment-return-params.d.ts.map +1 -1
  114. package/lib/typescript/commonjs/core/models/pending-session-record.d.ts +11 -0
  115. package/lib/typescript/commonjs/core/models/pending-session-record.d.ts.map +1 -0
  116. package/lib/typescript/commonjs/core/services/hosted-flow-controller.d.ts +119 -0
  117. package/lib/typescript/commonjs/core/services/hosted-flow-controller.d.ts.map +1 -0
  118. package/lib/typescript/commonjs/core/services/hosted-flow-state.d.ts +75 -0
  119. package/lib/typescript/commonjs/core/services/hosted-flow-state.d.ts.map +1 -0
  120. package/lib/typescript/commonjs/index.d.ts +5 -14
  121. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  122. package/lib/typescript/commonjs/internal/hosted/bridge-message.d.ts +44 -0
  123. package/lib/typescript/commonjs/internal/hosted/bridge-message.d.ts.map +1 -0
  124. package/lib/typescript/commonjs/internal/hosted/hosted-url.d.ts +30 -0
  125. package/lib/typescript/commonjs/internal/hosted/hosted-url.d.ts.map +1 -0
  126. package/lib/typescript/commonjs/internal/index.d.ts +0 -1
  127. package/lib/typescript/commonjs/internal/index.d.ts.map +1 -1
  128. package/lib/typescript/commonjs/internal/redact-uri.d.ts +21 -1
  129. package/lib/typescript/commonjs/internal/redact-uri.d.ts.map +1 -1
  130. package/lib/typescript/commonjs/internal/secure-store-pending-session-store.d.ts +3 -2
  131. package/lib/typescript/commonjs/internal/secure-store-pending-session-store.d.ts.map +1 -1
  132. package/lib/typescript/commonjs/internal/url-parts.d.ts +46 -0
  133. package/lib/typescript/commonjs/internal/url-parts.d.ts.map +1 -0
  134. package/lib/typescript/commonjs/public/index.d.ts +4 -6
  135. package/lib/typescript/commonjs/public/index.d.ts.map +1 -1
  136. package/lib/typescript/commonjs/public/payment-result.d.ts +50 -12
  137. package/lib/typescript/commonjs/public/payment-result.d.ts.map +1 -1
  138. package/lib/typescript/commonjs/public/recovery-result.d.ts +11 -20
  139. package/lib/typescript/commonjs/public/recovery-result.d.ts.map +1 -1
  140. package/lib/typescript/commonjs/public/spare-link-config.d.ts +13 -31
  141. package/lib/typescript/commonjs/public/spare-link-config.d.ts.map +1 -1
  142. package/lib/typescript/commonjs/public/spare-link-event.d.ts +29 -31
  143. package/lib/typescript/commonjs/public/spare-link-event.d.ts.map +1 -1
  144. package/lib/typescript/commonjs/public/spare-link-host-api.d.ts +1 -12
  145. package/lib/typescript/commonjs/public/spare-link-host-api.d.ts.map +1 -1
  146. package/lib/typescript/commonjs/public/spare-link-instance.d.ts +26 -20
  147. package/lib/typescript/commonjs/public/spare-link-instance.d.ts.map +1 -1
  148. package/lib/typescript/commonjs/public/spare-link-session.d.ts +3 -8
  149. package/lib/typescript/commonjs/public/spare-link-session.d.ts.map +1 -1
  150. package/lib/typescript/commonjs/public/spare-link.d.ts +1 -1
  151. package/lib/typescript/commonjs/public/spare-link.d.ts.map +1 -1
  152. package/lib/typescript/commonjs/ui/hooks/use-hosted-flow-state.d.ts +9 -0
  153. package/lib/typescript/commonjs/ui/hooks/use-hosted-flow-state.d.ts.map +1 -0
  154. package/lib/typescript/commonjs/ui/hosted/hosted-payment-page.d.ts +17 -0
  155. package/lib/typescript/commonjs/ui/hosted/hosted-payment-page.d.ts.map +1 -0
  156. package/lib/typescript/commonjs/ui/hosted/hosted-payment-webview.d.ts +43 -0
  157. package/lib/typescript/commonjs/ui/hosted/hosted-payment-webview.d.ts.map +1 -0
  158. package/lib/typescript/commonjs/ui/screens/index.d.ts +1 -3
  159. package/lib/typescript/commonjs/ui/screens/index.d.ts.map +1 -1
  160. package/lib/typescript/commonjs/ui/screens/page-unavailable-screen.d.ts +18 -0
  161. package/lib/typescript/commonjs/ui/screens/page-unavailable-screen.d.ts.map +1 -0
  162. package/lib/typescript/commonjs/ui/spare-link-host.d.ts +4 -5
  163. package/lib/typescript/commonjs/ui/spare-link-host.d.ts.map +1 -1
  164. package/lib/typescript/commonjs/ui/widgets/index.d.ts +1 -2
  165. package/lib/typescript/commonjs/ui/widgets/index.d.ts.map +1 -1
  166. package/lib/typescript/commonjs/version.d.ts +1 -1
  167. package/lib/typescript/commonjs/version.d.ts.map +1 -1
  168. package/lib/typescript/module/core/models/index.d.ts +1 -123
  169. package/lib/typescript/module/core/models/index.d.ts.map +1 -1
  170. package/lib/typescript/module/core/models/payment-return-params.d.ts +91 -8
  171. package/lib/typescript/module/core/models/payment-return-params.d.ts.map +1 -1
  172. package/lib/typescript/module/core/models/pending-session-record.d.ts +11 -0
  173. package/lib/typescript/module/core/models/pending-session-record.d.ts.map +1 -0
  174. package/lib/typescript/module/core/services/hosted-flow-controller.d.ts +119 -0
  175. package/lib/typescript/module/core/services/hosted-flow-controller.d.ts.map +1 -0
  176. package/lib/typescript/module/core/services/hosted-flow-state.d.ts +75 -0
  177. package/lib/typescript/module/core/services/hosted-flow-state.d.ts.map +1 -0
  178. package/lib/typescript/module/index.d.ts +5 -14
  179. package/lib/typescript/module/index.d.ts.map +1 -1
  180. package/lib/typescript/module/internal/hosted/bridge-message.d.ts +44 -0
  181. package/lib/typescript/module/internal/hosted/bridge-message.d.ts.map +1 -0
  182. package/lib/typescript/module/internal/hosted/hosted-url.d.ts +30 -0
  183. package/lib/typescript/module/internal/hosted/hosted-url.d.ts.map +1 -0
  184. package/lib/typescript/module/internal/index.d.ts +0 -1
  185. package/lib/typescript/module/internal/index.d.ts.map +1 -1
  186. package/lib/typescript/module/internal/redact-uri.d.ts +21 -1
  187. package/lib/typescript/module/internal/redact-uri.d.ts.map +1 -1
  188. package/lib/typescript/module/internal/secure-store-pending-session-store.d.ts +3 -2
  189. package/lib/typescript/module/internal/secure-store-pending-session-store.d.ts.map +1 -1
  190. package/lib/typescript/module/internal/url-parts.d.ts +46 -0
  191. package/lib/typescript/module/internal/url-parts.d.ts.map +1 -0
  192. package/lib/typescript/module/public/index.d.ts +4 -6
  193. package/lib/typescript/module/public/index.d.ts.map +1 -1
  194. package/lib/typescript/module/public/payment-result.d.ts +50 -12
  195. package/lib/typescript/module/public/payment-result.d.ts.map +1 -1
  196. package/lib/typescript/module/public/recovery-result.d.ts +11 -20
  197. package/lib/typescript/module/public/recovery-result.d.ts.map +1 -1
  198. package/lib/typescript/module/public/spare-link-config.d.ts +13 -31
  199. package/lib/typescript/module/public/spare-link-config.d.ts.map +1 -1
  200. package/lib/typescript/module/public/spare-link-event.d.ts +29 -31
  201. package/lib/typescript/module/public/spare-link-event.d.ts.map +1 -1
  202. package/lib/typescript/module/public/spare-link-host-api.d.ts +1 -12
  203. package/lib/typescript/module/public/spare-link-host-api.d.ts.map +1 -1
  204. package/lib/typescript/module/public/spare-link-instance.d.ts +26 -20
  205. package/lib/typescript/module/public/spare-link-instance.d.ts.map +1 -1
  206. package/lib/typescript/module/public/spare-link-session.d.ts +3 -8
  207. package/lib/typescript/module/public/spare-link-session.d.ts.map +1 -1
  208. package/lib/typescript/module/public/spare-link.d.ts +1 -1
  209. package/lib/typescript/module/public/spare-link.d.ts.map +1 -1
  210. package/lib/typescript/module/ui/hooks/use-hosted-flow-state.d.ts +9 -0
  211. package/lib/typescript/module/ui/hooks/use-hosted-flow-state.d.ts.map +1 -0
  212. package/lib/typescript/module/ui/hosted/hosted-payment-page.d.ts +17 -0
  213. package/lib/typescript/module/ui/hosted/hosted-payment-page.d.ts.map +1 -0
  214. package/lib/typescript/module/ui/hosted/hosted-payment-webview.d.ts +43 -0
  215. package/lib/typescript/module/ui/hosted/hosted-payment-webview.d.ts.map +1 -0
  216. package/lib/typescript/module/ui/screens/index.d.ts +1 -3
  217. package/lib/typescript/module/ui/screens/index.d.ts.map +1 -1
  218. package/lib/typescript/module/ui/screens/page-unavailable-screen.d.ts +18 -0
  219. package/lib/typescript/module/ui/screens/page-unavailable-screen.d.ts.map +1 -0
  220. package/lib/typescript/module/ui/spare-link-host.d.ts +4 -5
  221. package/lib/typescript/module/ui/spare-link-host.d.ts.map +1 -1
  222. package/lib/typescript/module/ui/widgets/index.d.ts +1 -2
  223. package/lib/typescript/module/ui/widgets/index.d.ts.map +1 -1
  224. package/lib/typescript/module/version.d.ts +1 -1
  225. package/lib/typescript/module/version.d.ts.map +1 -1
  226. package/package.json +24 -22
  227. package/plugins/with-spare-link.js +6 -26
  228. package/src/core/models/index.ts +1 -139
  229. package/src/core/models/payment-return-params.ts +269 -21
  230. package/src/core/models/pending-session-record.ts +10 -0
  231. package/src/core/services/hosted-flow-controller.ts +374 -0
  232. package/src/core/services/hosted-flow-state.ts +123 -0
  233. package/src/index.ts +20 -89
  234. package/src/internal/hosted/bridge-message.ts +106 -0
  235. package/src/internal/hosted/hosted-url.ts +33 -0
  236. package/src/internal/index.ts +0 -1
  237. package/src/internal/redact-uri.ts +69 -15
  238. package/src/internal/secure-store-pending-session-store.ts +28 -49
  239. package/src/internal/url-parts.ts +134 -0
  240. package/src/public/index.ts +2 -24
  241. package/src/public/payment-result.ts +50 -12
  242. package/src/public/recovery-result.ts +16 -25
  243. package/src/public/spare-link-config.ts +56 -43
  244. package/src/public/spare-link-event.ts +33 -42
  245. package/src/public/spare-link-host-api.ts +1 -14
  246. package/src/public/spare-link-instance.ts +57 -65
  247. package/src/public/spare-link-session.ts +4 -16
  248. package/src/public/spare-link.ts +1 -1
  249. package/src/ui/hooks/use-hosted-flow-state.ts +16 -0
  250. package/src/ui/hosted/hosted-payment-page.tsx +178 -0
  251. package/src/ui/hosted/hosted-payment-webview.tsx +164 -0
  252. package/src/ui/screens/index.ts +4 -6
  253. package/src/ui/screens/page-unavailable-screen.tsx +94 -0
  254. package/src/ui/spare-link-host.tsx +227 -247
  255. package/src/ui/widgets/index.ts +1 -2
  256. package/src/version.ts +1 -1
  257. package/CHANGELOG.md +0 -25
  258. package/lib/commonjs/core/client/link-api-client.js +0 -297
  259. package/lib/commonjs/core/client/link-api-client.js.map +0 -1
  260. package/lib/commonjs/core/errors/payment-api-error.js +0 -35
  261. package/lib/commonjs/core/errors/payment-api-error.js.map +0 -1
  262. package/lib/commonjs/core/models/link-session-status.js +0 -14
  263. package/lib/commonjs/core/models/link-session-status.js.map +0 -1
  264. package/lib/commonjs/core/models/payment-type.js +0 -45
  265. package/lib/commonjs/core/models/payment-type.js.map +0 -1
  266. package/lib/commonjs/core/models/wire-mappers.js +0 -277
  267. package/lib/commonjs/core/models/wire-mappers.js.map +0 -1
  268. package/lib/commonjs/core/services/consent-presenter.js +0 -150
  269. package/lib/commonjs/core/services/consent-presenter.js.map +0 -1
  270. package/lib/commonjs/core/services/execute-resume-if-needed.js +0 -216
  271. package/lib/commonjs/core/services/execute-resume-if-needed.js.map +0 -1
  272. package/lib/commonjs/core/services/multi-payment-rules-presenter.js +0 -151
  273. package/lib/commonjs/core/services/multi-payment-rules-presenter.js.map +0 -1
  274. package/lib/commonjs/core/services/payment-flow-controller.js +0 -547
  275. package/lib/commonjs/core/services/payment-flow-controller.js.map +0 -1
  276. package/lib/commonjs/core/services/payment-flow-state.js +0 -110
  277. package/lib/commonjs/core/services/payment-flow-state.js.map +0 -1
  278. package/lib/commonjs/core/services/payment-result-mapper.js +0 -49
  279. package/lib/commonjs/core/services/payment-result-mapper.js.map +0 -1
  280. package/lib/commonjs/core/services/presentation-utils.js +0 -11
  281. package/lib/commonjs/core/services/presentation-utils.js.map +0 -1
  282. package/lib/commonjs/core/services/redirect-buffer.js +0 -40
  283. package/lib/commonjs/core/services/redirect-buffer.js.map +0 -1
  284. package/lib/commonjs/core/services/user-friendly-messages.js +0 -46
  285. package/lib/commonjs/core/services/user-friendly-messages.js.map +0 -1
  286. package/lib/commonjs/internal/telemetry-collector.js +0 -80
  287. package/lib/commonjs/internal/telemetry-collector.js.map +0 -1
  288. package/lib/commonjs/public/constants.js +0 -21
  289. package/lib/commonjs/public/constants.js.map +0 -1
  290. package/lib/commonjs/public/spare-link-callbacks.js +0 -6
  291. package/lib/commonjs/public/spare-link-callbacks.js.map +0 -1
  292. package/lib/commonjs/ui/consent/charge-bearer-display.js +0 -99
  293. package/lib/commonjs/ui/consent/charge-bearer-display.js.map +0 -1
  294. package/lib/commonjs/ui/consent/consent-accordion.js +0 -94
  295. package/lib/commonjs/ui/consent/consent-accordion.js.map +0 -1
  296. package/lib/commonjs/ui/consent/consent-summary-section.js +0 -27
  297. package/lib/commonjs/ui/consent/consent-summary-section.js.map +0 -1
  298. package/lib/commonjs/ui/consent/cop-information.js +0 -168
  299. package/lib/commonjs/ui/consent/cop-information.js.map +0 -1
  300. package/lib/commonjs/ui/consent/international-payment-summary.js +0 -98
  301. package/lib/commonjs/ui/consent/international-payment-summary.js.map +0 -1
  302. package/lib/commonjs/ui/consent/label-value-rows.js +0 -59
  303. package/lib/commonjs/ui/consent/label-value-rows.js.map +0 -1
  304. package/lib/commonjs/ui/consent/multi-payment-rules-list.js +0 -130
  305. package/lib/commonjs/ui/consent/multi-payment-rules-list.js.map +0 -1
  306. package/lib/commonjs/ui/consent/multi-payment-summary.js +0 -99
  307. package/lib/commonjs/ui/consent/multi-payment-summary.js.map +0 -1
  308. package/lib/commonjs/ui/consent/single-payment-summary.js +0 -158
  309. package/lib/commonjs/ui/consent/single-payment-summary.js.map +0 -1
  310. package/lib/commonjs/ui/consent/terms-link.js +0 -35
  311. package/lib/commonjs/ui/consent/terms-link.js.map +0 -1
  312. package/lib/commonjs/ui/hooks/use-payment-flow-state.js.map +0 -1
  313. package/lib/commonjs/ui/payment-flow-page.js +0 -235
  314. package/lib/commonjs/ui/payment-flow-page.js.map +0 -1
  315. package/lib/commonjs/ui/screens/bank-selection-screen.js +0 -215
  316. package/lib/commonjs/ui/screens/bank-selection-screen.js.map +0 -1
  317. package/lib/commonjs/ui/screens/consent-details-screen.js +0 -124
  318. package/lib/commonjs/ui/screens/consent-details-screen.js.map +0 -1
  319. package/lib/commonjs/ui/screens/mandate-setup-success-screen.js +0 -79
  320. package/lib/commonjs/ui/screens/mandate-setup-success-screen.js.map +0 -1
  321. package/lib/commonjs/ui/widgets/layout-w-header.js +0 -106
  322. package/lib/commonjs/ui/widgets/layout-w-header.js.map +0 -1
  323. package/lib/commonjs/ui/widgets/stepper.js +0 -124
  324. package/lib/commonjs/ui/widgets/stepper.js.map +0 -1
  325. package/lib/module/core/client/link-api-client.js +0 -292
  326. package/lib/module/core/client/link-api-client.js.map +0 -1
  327. package/lib/module/core/errors/payment-api-error.js +0 -29
  328. package/lib/module/core/errors/payment-api-error.js.map +0 -1
  329. package/lib/module/core/models/link-session-status.js +0 -10
  330. package/lib/module/core/models/link-session-status.js.map +0 -1
  331. package/lib/module/core/models/payment-type.js +0 -36
  332. package/lib/module/core/models/payment-type.js.map +0 -1
  333. package/lib/module/core/models/wire-mappers.js +0 -263
  334. package/lib/module/core/models/wire-mappers.js.map +0 -1
  335. package/lib/module/core/services/consent-presenter.js +0 -140
  336. package/lib/module/core/services/consent-presenter.js.map +0 -1
  337. package/lib/module/core/services/execute-resume-if-needed.js +0 -211
  338. package/lib/module/core/services/execute-resume-if-needed.js.map +0 -1
  339. package/lib/module/core/services/multi-payment-rules-presenter.js +0 -146
  340. package/lib/module/core/services/multi-payment-rules-presenter.js.map +0 -1
  341. package/lib/module/core/services/payment-flow-controller.js +0 -544
  342. package/lib/module/core/services/payment-flow-controller.js.map +0 -1
  343. package/lib/module/core/services/payment-flow-state.js +0 -106
  344. package/lib/module/core/services/payment-flow-state.js.map +0 -1
  345. package/lib/module/core/services/payment-result-mapper.js +0 -45
  346. package/lib/module/core/services/payment-result-mapper.js.map +0 -1
  347. package/lib/module/core/services/presentation-utils.js +0 -7
  348. package/lib/module/core/services/presentation-utils.js.map +0 -1
  349. package/lib/module/core/services/redirect-buffer.js +0 -33
  350. package/lib/module/core/services/redirect-buffer.js.map +0 -1
  351. package/lib/module/core/services/user-friendly-messages.js +0 -42
  352. package/lib/module/core/services/user-friendly-messages.js.map +0 -1
  353. package/lib/module/internal/telemetry-collector.js +0 -75
  354. package/lib/module/internal/telemetry-collector.js.map +0 -1
  355. package/lib/module/public/constants.js +0 -17
  356. package/lib/module/public/constants.js.map +0 -1
  357. package/lib/module/public/spare-link-callbacks.js +0 -4
  358. package/lib/module/public/spare-link-callbacks.js.map +0 -1
  359. package/lib/module/ui/consent/charge-bearer-display.js +0 -95
  360. package/lib/module/ui/consent/charge-bearer-display.js.map +0 -1
  361. package/lib/module/ui/consent/consent-accordion.js +0 -90
  362. package/lib/module/ui/consent/consent-accordion.js.map +0 -1
  363. package/lib/module/ui/consent/consent-summary-section.js +0 -23
  364. package/lib/module/ui/consent/consent-summary-section.js.map +0 -1
  365. package/lib/module/ui/consent/cop-information.js +0 -165
  366. package/lib/module/ui/consent/cop-information.js.map +0 -1
  367. package/lib/module/ui/consent/international-payment-summary.js +0 -94
  368. package/lib/module/ui/consent/international-payment-summary.js.map +0 -1
  369. package/lib/module/ui/consent/label-value-rows.js +0 -55
  370. package/lib/module/ui/consent/label-value-rows.js.map +0 -1
  371. package/lib/module/ui/consent/multi-payment-rules-list.js +0 -125
  372. package/lib/module/ui/consent/multi-payment-rules-list.js.map +0 -1
  373. package/lib/module/ui/consent/multi-payment-summary.js +0 -95
  374. package/lib/module/ui/consent/multi-payment-summary.js.map +0 -1
  375. package/lib/module/ui/consent/single-payment-summary.js +0 -154
  376. package/lib/module/ui/consent/single-payment-summary.js.map +0 -1
  377. package/lib/module/ui/consent/terms-link.js +0 -31
  378. package/lib/module/ui/consent/terms-link.js.map +0 -1
  379. package/lib/module/ui/hooks/use-payment-flow-state.js.map +0 -1
  380. package/lib/module/ui/payment-flow-page.js +0 -232
  381. package/lib/module/ui/payment-flow-page.js.map +0 -1
  382. package/lib/module/ui/screens/bank-selection-screen.js +0 -211
  383. package/lib/module/ui/screens/bank-selection-screen.js.map +0 -1
  384. package/lib/module/ui/screens/consent-details-screen.js +0 -120
  385. package/lib/module/ui/screens/consent-details-screen.js.map +0 -1
  386. package/lib/module/ui/screens/mandate-setup-success-screen.js +0 -75
  387. package/lib/module/ui/screens/mandate-setup-success-screen.js.map +0 -1
  388. package/lib/module/ui/widgets/layout-w-header.js +0 -102
  389. package/lib/module/ui/widgets/layout-w-header.js.map +0 -1
  390. package/lib/module/ui/widgets/stepper.js +0 -120
  391. package/lib/module/ui/widgets/stepper.js.map +0 -1
  392. package/lib/typescript/commonjs/core/client/link-api-client.d.ts +0 -70
  393. package/lib/typescript/commonjs/core/client/link-api-client.d.ts.map +0 -1
  394. package/lib/typescript/commonjs/core/errors/payment-api-error.d.ts +0 -15
  395. package/lib/typescript/commonjs/core/errors/payment-api-error.d.ts.map +0 -1
  396. package/lib/typescript/commonjs/core/models/link-session-status.d.ts +0 -6
  397. package/lib/typescript/commonjs/core/models/link-session-status.d.ts.map +0 -1
  398. package/lib/typescript/commonjs/core/models/payment-type.d.ts +0 -18
  399. package/lib/typescript/commonjs/core/models/payment-type.d.ts.map +0 -1
  400. package/lib/typescript/commonjs/core/models/wire-mappers.d.ts +0 -19
  401. package/lib/typescript/commonjs/core/models/wire-mappers.d.ts.map +0 -1
  402. package/lib/typescript/commonjs/core/services/consent-presenter.d.ts +0 -67
  403. package/lib/typescript/commonjs/core/services/consent-presenter.d.ts.map +0 -1
  404. package/lib/typescript/commonjs/core/services/execute-resume-if-needed.d.ts +0 -32
  405. package/lib/typescript/commonjs/core/services/execute-resume-if-needed.d.ts.map +0 -1
  406. package/lib/typescript/commonjs/core/services/multi-payment-rules-presenter.d.ts +0 -9
  407. package/lib/typescript/commonjs/core/services/multi-payment-rules-presenter.d.ts.map +0 -1
  408. package/lib/typescript/commonjs/core/services/payment-flow-controller.d.ts +0 -146
  409. package/lib/typescript/commonjs/core/services/payment-flow-controller.d.ts.map +0 -1
  410. package/lib/typescript/commonjs/core/services/payment-flow-state.d.ts +0 -64
  411. package/lib/typescript/commonjs/core/services/payment-flow-state.d.ts.map +0 -1
  412. package/lib/typescript/commonjs/core/services/payment-result-mapper.d.ts +0 -5
  413. package/lib/typescript/commonjs/core/services/payment-result-mapper.d.ts.map +0 -1
  414. package/lib/typescript/commonjs/core/services/presentation-utils.d.ts +0 -5
  415. package/lib/typescript/commonjs/core/services/presentation-utils.d.ts.map +0 -1
  416. package/lib/typescript/commonjs/core/services/redirect-buffer.d.ts +0 -6
  417. package/lib/typescript/commonjs/core/services/redirect-buffer.d.ts.map +0 -1
  418. package/lib/typescript/commonjs/core/services/user-friendly-messages.d.ts +0 -6
  419. package/lib/typescript/commonjs/core/services/user-friendly-messages.d.ts.map +0 -1
  420. package/lib/typescript/commonjs/internal/telemetry-collector.d.ts +0 -2
  421. package/lib/typescript/commonjs/internal/telemetry-collector.d.ts.map +0 -1
  422. package/lib/typescript/commonjs/public/constants.d.ts +0 -12
  423. package/lib/typescript/commonjs/public/constants.d.ts.map +0 -1
  424. package/lib/typescript/commonjs/public/spare-link-callbacks.d.ts +0 -14
  425. package/lib/typescript/commonjs/public/spare-link-callbacks.d.ts.map +0 -1
  426. package/lib/typescript/commonjs/ui/consent/charge-bearer-display.d.ts +0 -5
  427. package/lib/typescript/commonjs/ui/consent/charge-bearer-display.d.ts.map +0 -1
  428. package/lib/typescript/commonjs/ui/consent/consent-accordion.d.ts +0 -10
  429. package/lib/typescript/commonjs/ui/consent/consent-accordion.d.ts.map +0 -1
  430. package/lib/typescript/commonjs/ui/consent/consent-summary-section.d.ts +0 -6
  431. package/lib/typescript/commonjs/ui/consent/consent-summary-section.d.ts.map +0 -1
  432. package/lib/typescript/commonjs/ui/consent/cop-information.d.ts +0 -6
  433. package/lib/typescript/commonjs/ui/consent/cop-information.d.ts.map +0 -1
  434. package/lib/typescript/commonjs/ui/consent/international-payment-summary.d.ts +0 -6
  435. package/lib/typescript/commonjs/ui/consent/international-payment-summary.d.ts.map +0 -1
  436. package/lib/typescript/commonjs/ui/consent/label-value-rows.d.ts +0 -10
  437. package/lib/typescript/commonjs/ui/consent/label-value-rows.d.ts.map +0 -1
  438. package/lib/typescript/commonjs/ui/consent/multi-payment-rules-list.d.ts +0 -15
  439. package/lib/typescript/commonjs/ui/consent/multi-payment-rules-list.d.ts.map +0 -1
  440. package/lib/typescript/commonjs/ui/consent/multi-payment-summary.d.ts +0 -6
  441. package/lib/typescript/commonjs/ui/consent/multi-payment-summary.d.ts.map +0 -1
  442. package/lib/typescript/commonjs/ui/consent/single-payment-summary.d.ts +0 -6
  443. package/lib/typescript/commonjs/ui/consent/single-payment-summary.d.ts.map +0 -1
  444. package/lib/typescript/commonjs/ui/consent/terms-link.d.ts +0 -2
  445. package/lib/typescript/commonjs/ui/consent/terms-link.d.ts.map +0 -1
  446. package/lib/typescript/commonjs/ui/hooks/use-payment-flow-state.d.ts +0 -9
  447. package/lib/typescript/commonjs/ui/hooks/use-payment-flow-state.d.ts.map +0 -1
  448. package/lib/typescript/commonjs/ui/payment-flow-page.d.ts +0 -20
  449. package/lib/typescript/commonjs/ui/payment-flow-page.d.ts.map +0 -1
  450. package/lib/typescript/commonjs/ui/screens/bank-selection-screen.d.ts +0 -15
  451. package/lib/typescript/commonjs/ui/screens/bank-selection-screen.d.ts.map +0 -1
  452. package/lib/typescript/commonjs/ui/screens/consent-details-screen.d.ts +0 -13
  453. package/lib/typescript/commonjs/ui/screens/consent-details-screen.d.ts.map +0 -1
  454. package/lib/typescript/commonjs/ui/screens/mandate-setup-success-screen.d.ts +0 -10
  455. package/lib/typescript/commonjs/ui/screens/mandate-setup-success-screen.d.ts.map +0 -1
  456. package/lib/typescript/commonjs/ui/widgets/layout-w-header.d.ts +0 -20
  457. package/lib/typescript/commonjs/ui/widgets/layout-w-header.d.ts.map +0 -1
  458. package/lib/typescript/commonjs/ui/widgets/stepper.d.ts +0 -15
  459. package/lib/typescript/commonjs/ui/widgets/stepper.d.ts.map +0 -1
  460. package/lib/typescript/module/core/client/link-api-client.d.ts +0 -70
  461. package/lib/typescript/module/core/client/link-api-client.d.ts.map +0 -1
  462. package/lib/typescript/module/core/errors/payment-api-error.d.ts +0 -15
  463. package/lib/typescript/module/core/errors/payment-api-error.d.ts.map +0 -1
  464. package/lib/typescript/module/core/models/link-session-status.d.ts +0 -6
  465. package/lib/typescript/module/core/models/link-session-status.d.ts.map +0 -1
  466. package/lib/typescript/module/core/models/payment-type.d.ts +0 -18
  467. package/lib/typescript/module/core/models/payment-type.d.ts.map +0 -1
  468. package/lib/typescript/module/core/models/wire-mappers.d.ts +0 -19
  469. package/lib/typescript/module/core/models/wire-mappers.d.ts.map +0 -1
  470. package/lib/typescript/module/core/services/consent-presenter.d.ts +0 -67
  471. package/lib/typescript/module/core/services/consent-presenter.d.ts.map +0 -1
  472. package/lib/typescript/module/core/services/execute-resume-if-needed.d.ts +0 -32
  473. package/lib/typescript/module/core/services/execute-resume-if-needed.d.ts.map +0 -1
  474. package/lib/typescript/module/core/services/multi-payment-rules-presenter.d.ts +0 -9
  475. package/lib/typescript/module/core/services/multi-payment-rules-presenter.d.ts.map +0 -1
  476. package/lib/typescript/module/core/services/payment-flow-controller.d.ts +0 -146
  477. package/lib/typescript/module/core/services/payment-flow-controller.d.ts.map +0 -1
  478. package/lib/typescript/module/core/services/payment-flow-state.d.ts +0 -64
  479. package/lib/typescript/module/core/services/payment-flow-state.d.ts.map +0 -1
  480. package/lib/typescript/module/core/services/payment-result-mapper.d.ts +0 -5
  481. package/lib/typescript/module/core/services/payment-result-mapper.d.ts.map +0 -1
  482. package/lib/typescript/module/core/services/presentation-utils.d.ts +0 -5
  483. package/lib/typescript/module/core/services/presentation-utils.d.ts.map +0 -1
  484. package/lib/typescript/module/core/services/redirect-buffer.d.ts +0 -6
  485. package/lib/typescript/module/core/services/redirect-buffer.d.ts.map +0 -1
  486. package/lib/typescript/module/core/services/user-friendly-messages.d.ts +0 -6
  487. package/lib/typescript/module/core/services/user-friendly-messages.d.ts.map +0 -1
  488. package/lib/typescript/module/internal/telemetry-collector.d.ts +0 -2
  489. package/lib/typescript/module/internal/telemetry-collector.d.ts.map +0 -1
  490. package/lib/typescript/module/public/constants.d.ts +0 -12
  491. package/lib/typescript/module/public/constants.d.ts.map +0 -1
  492. package/lib/typescript/module/public/spare-link-callbacks.d.ts +0 -14
  493. package/lib/typescript/module/public/spare-link-callbacks.d.ts.map +0 -1
  494. package/lib/typescript/module/ui/consent/charge-bearer-display.d.ts +0 -5
  495. package/lib/typescript/module/ui/consent/charge-bearer-display.d.ts.map +0 -1
  496. package/lib/typescript/module/ui/consent/consent-accordion.d.ts +0 -10
  497. package/lib/typescript/module/ui/consent/consent-accordion.d.ts.map +0 -1
  498. package/lib/typescript/module/ui/consent/consent-summary-section.d.ts +0 -6
  499. package/lib/typescript/module/ui/consent/consent-summary-section.d.ts.map +0 -1
  500. package/lib/typescript/module/ui/consent/cop-information.d.ts +0 -6
  501. package/lib/typescript/module/ui/consent/cop-information.d.ts.map +0 -1
  502. package/lib/typescript/module/ui/consent/international-payment-summary.d.ts +0 -6
  503. package/lib/typescript/module/ui/consent/international-payment-summary.d.ts.map +0 -1
  504. package/lib/typescript/module/ui/consent/label-value-rows.d.ts +0 -10
  505. package/lib/typescript/module/ui/consent/label-value-rows.d.ts.map +0 -1
  506. package/lib/typescript/module/ui/consent/multi-payment-rules-list.d.ts +0 -15
  507. package/lib/typescript/module/ui/consent/multi-payment-rules-list.d.ts.map +0 -1
  508. package/lib/typescript/module/ui/consent/multi-payment-summary.d.ts +0 -6
  509. package/lib/typescript/module/ui/consent/multi-payment-summary.d.ts.map +0 -1
  510. package/lib/typescript/module/ui/consent/single-payment-summary.d.ts +0 -6
  511. package/lib/typescript/module/ui/consent/single-payment-summary.d.ts.map +0 -1
  512. package/lib/typescript/module/ui/consent/terms-link.d.ts +0 -2
  513. package/lib/typescript/module/ui/consent/terms-link.d.ts.map +0 -1
  514. package/lib/typescript/module/ui/hooks/use-payment-flow-state.d.ts +0 -9
  515. package/lib/typescript/module/ui/hooks/use-payment-flow-state.d.ts.map +0 -1
  516. package/lib/typescript/module/ui/payment-flow-page.d.ts +0 -20
  517. package/lib/typescript/module/ui/payment-flow-page.d.ts.map +0 -1
  518. package/lib/typescript/module/ui/screens/bank-selection-screen.d.ts +0 -15
  519. package/lib/typescript/module/ui/screens/bank-selection-screen.d.ts.map +0 -1
  520. package/lib/typescript/module/ui/screens/consent-details-screen.d.ts +0 -13
  521. package/lib/typescript/module/ui/screens/consent-details-screen.d.ts.map +0 -1
  522. package/lib/typescript/module/ui/screens/mandate-setup-success-screen.d.ts +0 -10
  523. package/lib/typescript/module/ui/screens/mandate-setup-success-screen.d.ts.map +0 -1
  524. package/lib/typescript/module/ui/widgets/layout-w-header.d.ts +0 -20
  525. package/lib/typescript/module/ui/widgets/layout-w-header.d.ts.map +0 -1
  526. package/lib/typescript/module/ui/widgets/stepper.d.ts +0 -15
  527. package/lib/typescript/module/ui/widgets/stepper.d.ts.map +0 -1
  528. package/src/core/client/link-api-client.ts +0 -414
  529. package/src/core/errors/payment-api-error.ts +0 -35
  530. package/src/core/models/link-session-status.ts +0 -7
  531. package/src/core/models/payment-type.ts +0 -54
  532. package/src/core/models/wire-mappers.ts +0 -315
  533. package/src/core/services/consent-presenter.ts +0 -213
  534. package/src/core/services/execute-resume-if-needed.ts +0 -243
  535. package/src/core/services/multi-payment-rules-presenter.ts +0 -158
  536. package/src/core/services/payment-flow-controller.ts +0 -607
  537. package/src/core/services/payment-flow-state.ts +0 -124
  538. package/src/core/services/payment-result-mapper.ts +0 -41
  539. package/src/core/services/presentation-utils.ts +0 -4
  540. package/src/core/services/redirect-buffer.ts +0 -34
  541. package/src/core/services/user-friendly-messages.ts +0 -39
  542. package/src/internal/telemetry-collector.ts +0 -90
  543. package/src/public/constants.ts +0 -14
  544. package/src/public/spare-link-callbacks.ts +0 -20
  545. package/src/ui/consent/charge-bearer-display.tsx +0 -68
  546. package/src/ui/consent/consent-accordion.tsx +0 -89
  547. package/src/ui/consent/consent-summary-section.tsx +0 -19
  548. package/src/ui/consent/cop-information.tsx +0 -121
  549. package/src/ui/consent/international-payment-summary.tsx +0 -83
  550. package/src/ui/consent/label-value-rows.tsx +0 -50
  551. package/src/ui/consent/multi-payment-rules-list.tsx +0 -138
  552. package/src/ui/consent/multi-payment-summary.tsx +0 -82
  553. package/src/ui/consent/single-payment-summary.tsx +0 -123
  554. package/src/ui/consent/terms-link.tsx +0 -27
  555. package/src/ui/hooks/use-payment-flow-state.ts +0 -16
  556. package/src/ui/payment-flow-page.tsx +0 -254
  557. package/src/ui/screens/bank-selection-screen.tsx +0 -209
  558. package/src/ui/screens/consent-details-screen.tsx +0 -106
  559. package/src/ui/screens/mandate-setup-success-screen.tsx +0 -72
  560. package/src/ui/widgets/layout-w-header.tsx +0 -89
  561. 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
- }