@openlup/platform 0.25.0 → 0.27.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 (524) hide show
  1. package/CHANGELOG.md +156 -440
  2. package/README.md +230 -11
  3. package/dist/commerce/adapters/managed/commerceOmsControlPlane.d.ts +3 -0
  4. package/dist/commerce/adapters/managed/commerceOmsControlPlane.js +71 -0
  5. package/dist/commerce/adapters/managed/commerceOmsMutations.d.ts +10 -0
  6. package/dist/commerce/adapters/managed/commerceOmsMutations.js +119 -0
  7. package/dist/commerce/adapters/managed/commerceOmsPort.d.ts +28 -0
  8. package/dist/commerce/adapters/managed/commerceOmsPort.js +101 -0
  9. package/dist/commerce/adapters/managed/oms/accounting.d.ts +3 -0
  10. package/dist/commerce/adapters/managed/oms/accounting.js +13 -0
  11. package/dist/commerce/adapters/managed/oms/fulfillmentReads.d.ts +17 -0
  12. package/dist/commerce/adapters/managed/oms/fulfillmentReads.js +81 -0
  13. package/dist/commerce/adapters/managed/oms/inboundEvents.d.ts +9 -0
  14. package/dist/commerce/adapters/managed/oms/inboundEvents.js +40 -0
  15. package/dist/commerce/adapters/managed/oms/outboxEvents.d.ts +2 -0
  16. package/dist/commerce/adapters/managed/oms/outboxEvents.js +23 -0
  17. package/dist/commerce/adapters/managed/oms/paymentAttempts.d.ts +3 -0
  18. package/dist/commerce/adapters/managed/oms/paymentAttempts.js +15 -0
  19. package/dist/commerce/adapters/managed/oms/queueSelection.d.ts +12 -0
  20. package/dist/commerce/adapters/managed/oms/queueSelection.js +109 -0
  21. package/dist/commerce/adapters/managed/oms/readProjections.d.ts +18 -0
  22. package/dist/commerce/adapters/managed/oms/readProjections.js +13 -0
  23. package/dist/commerce/adapters/managed/oms/readQueries.d.ts +16 -0
  24. package/dist/commerce/adapters/managed/oms/readQueries.js +276 -0
  25. package/dist/commerce/adapters/managed/oms/types.d.ts +2 -0
  26. package/dist/commerce/adapters/managed/oms/types.js +7 -0
  27. package/dist/commerce/checkoutCommandSchemas.d.ts +89 -0
  28. package/dist/commerce/checkoutCommandSchemas.js +70 -0
  29. package/dist/commerce/checkoutHelpers.d.ts +21 -0
  30. package/dist/commerce/checkoutHelpers.js +29 -0
  31. package/dist/commerce/checkoutResumeSchemas.d.ts +158 -0
  32. package/dist/commerce/checkoutResumeSchemas.js +145 -0
  33. package/dist/commerce/checkoutSchemas.d.ts +158 -0
  34. package/dist/commerce/checkoutSchemas.js +161 -0
  35. package/dist/commerce/commerceReturnsPort.d.ts +97 -0
  36. package/dist/commerce/commerceReturnsPort.js +39 -0
  37. package/dist/commerce/configuratorIntentPersistenceSchemas.d.ts +20 -0
  38. package/dist/commerce/configuratorIntentPersistenceSchemas.js +21 -0
  39. package/dist/commerce/configuratorIntentSchemas.d.ts +63 -0
  40. package/dist/commerce/configuratorIntentSchemas.js +43 -0
  41. package/dist/commerce/contractPrimitives.d.ts +50 -0
  42. package/dist/commerce/contractPrimitives.js +25 -0
  43. package/dist/commerce/contracts/availability.d.ts +23 -0
  44. package/dist/commerce/contracts/availability.js +1 -0
  45. package/dist/commerce/contracts/fulfillmentRecovery.d.ts +25 -0
  46. package/dist/commerce/contracts/fulfillmentRecovery.js +1 -0
  47. package/dist/commerce/contracts/index.d.ts +13 -0
  48. package/dist/commerce/contracts/index.js +1 -0
  49. package/dist/commerce/contracts/intent.d.ts +86 -0
  50. package/dist/commerce/contracts/intent.js +1 -0
  51. package/dist/commerce/contracts/omsTypes.d.ts +1216 -0
  52. package/dist/commerce/contracts/omsTypes.js +1 -0
  53. package/dist/commerce/contracts/order.d.ts +39 -0
  54. package/dist/commerce/contracts/order.js +1 -0
  55. package/dist/commerce/contracts/orderMoney.d.ts +52 -0
  56. package/dist/commerce/contracts/orderMoney.js +1 -0
  57. package/dist/commerce/contracts/ports.d.ts +113 -0
  58. package/dist/commerce/contracts/ports.js +1 -0
  59. package/dist/commerce/contracts/recovery.d.ts +11 -0
  60. package/dist/commerce/contracts/recovery.js +1 -0
  61. package/dist/commerce/contracts/runtimePorts.d.ts +196 -0
  62. package/dist/commerce/contracts/runtimePorts.js +1 -0
  63. package/dist/commerce/contracts/state.d.ts +26 -0
  64. package/dist/commerce/contracts/state.js +43 -0
  65. package/dist/commerce/customerDefaultsSnapshotSchemas.d.ts +51 -0
  66. package/dist/commerce/customerDefaultsSnapshotSchemas.js +106 -0
  67. package/dist/commerce/errors.d.ts +18 -0
  68. package/dist/commerce/errors.js +36 -0
  69. package/dist/commerce/fulfillmentEligibility.d.ts +6 -0
  70. package/dist/commerce/fulfillmentEligibility.js +31 -0
  71. package/dist/commerce/index.d.ts +72 -0
  72. package/dist/commerce/index.js +67 -0
  73. package/dist/commerce/model/customerFulfillmentRecovery.d.ts +40 -0
  74. package/dist/commerce/model/customerFulfillmentRecovery.js +144 -0
  75. package/dist/commerce/model/fulfillmentCancellationEligibility.d.ts +7 -0
  76. package/dist/commerce/model/fulfillmentCancellationEligibility.js +9 -0
  77. package/dist/commerce/model/omsAccountingVisibility.d.ts +12 -0
  78. package/dist/commerce/model/omsAccountingVisibility.js +118 -0
  79. package/dist/commerce/model/omsBillingInvoiceBuyer.d.ts +2 -0
  80. package/dist/commerce/model/omsBillingInvoiceBuyer.js +15 -0
  81. package/dist/commerce/model/omsCurrency.d.ts +4 -0
  82. package/dist/commerce/model/omsCurrency.js +5 -0
  83. package/dist/commerce/model/omsFulfillmentDebug.d.ts +20 -0
  84. package/dist/commerce/model/omsFulfillmentDebug.js +122 -0
  85. package/dist/commerce/model/omsFulfillmentSummary.d.ts +16 -0
  86. package/dist/commerce/model/omsFulfillmentSummary.js +189 -0
  87. package/dist/commerce/model/omsListTotals.d.ts +13 -0
  88. package/dist/commerce/model/omsListTotals.js +32 -0
  89. package/dist/commerce/model/omsOperationalLadder.d.ts +51 -0
  90. package/dist/commerce/model/omsOperationalLadder.js +158 -0
  91. package/dist/commerce/model/omsOrderLineMoney.d.ts +4 -0
  92. package/dist/commerce/model/omsOrderLineMoney.js +25 -0
  93. package/dist/commerce/model/omsPaymentMethodSummary.d.ts +5 -0
  94. package/dist/commerce/model/omsPaymentMethodSummary.js +11 -0
  95. package/dist/commerce/model/omsReadModel.d.ts +43 -0
  96. package/dist/commerce/model/omsReadModel.js +211 -0
  97. package/dist/commerce/model/omsReadModelCommunication.d.ts +3 -0
  98. package/dist/commerce/model/omsReadModelCommunication.js +29 -0
  99. package/dist/commerce/model/omsReadModelHelpers.d.ts +125 -0
  100. package/dist/commerce/model/omsReadModelHelpers.js +212 -0
  101. package/dist/commerce/model/omsReadModelList.d.ts +33 -0
  102. package/dist/commerce/model/omsReadModelList.js +50 -0
  103. package/dist/commerce/model/omsReadModelListSummary.d.ts +3 -0
  104. package/dist/commerce/model/omsReadModelListSummary.js +13 -0
  105. package/dist/commerce/model/omsReadModelPricing.d.ts +5 -0
  106. package/dist/commerce/model/omsReadModelPricing.js +36 -0
  107. package/dist/commerce/model/omsReadModelProjections.d.ts +1 -0
  108. package/dist/commerce/model/omsReadModelProjections.js +1 -0
  109. package/dist/commerce/model/omsReadModelRowCore.d.ts +79 -0
  110. package/dist/commerce/model/omsReadModelRowCore.js +149 -0
  111. package/dist/commerce/model/omsReadModelRows.d.ts +1 -0
  112. package/dist/commerce/model/omsReadModelRows.js +6 -0
  113. package/dist/commerce/offerAvailability.d.ts +18 -0
  114. package/dist/commerce/offerAvailability.js +53 -0
  115. package/dist/commerce/offerAvailabilitySchemas.d.ts +43 -0
  116. package/dist/commerce/offerAvailabilitySchemas.js +42 -0
  117. package/dist/commerce/offerEvidenceSchemas.d.ts +7 -0
  118. package/dist/commerce/offerEvidenceSchemas.js +13 -0
  119. package/dist/commerce/oms/omsContractBase.d.ts +130 -0
  120. package/dist/commerce/oms/omsContractBase.js +86 -0
  121. package/dist/commerce/oms/omsContractReadAuxSchemas.d.ts +222 -0
  122. package/dist/commerce/oms/omsContractReadAuxSchemas.js +123 -0
  123. package/dist/commerce/oms/omsContractReadSchemas.d.ts +2266 -0
  124. package/dist/commerce/oms/omsContractReadSchemas.js +277 -0
  125. package/dist/commerce/oms/omsContractRequests.d.ts +196 -0
  126. package/dist/commerce/oms/omsContractRequests.js +118 -0
  127. package/dist/commerce/oms/omsContracts.d.ts +5 -0
  128. package/dist/commerce/oms/omsContracts.js +4 -0
  129. package/dist/commerce/oms/omsControlPlane.d.ts +275 -0
  130. package/dist/commerce/oms/omsControlPlane.js +72 -0
  131. package/dist/commerce/oms/omsFulfillmentContractSchemas.d.ts +203 -0
  132. package/dist/commerce/oms/omsFulfillmentContractSchemas.js +94 -0
  133. package/dist/commerce/oms/omsFulfillmentDebugSchemas.d.ts +69 -0
  134. package/dist/commerce/oms/omsFulfillmentDebugSchemas.js +33 -0
  135. package/dist/commerce/oms/omsFulfillmentHealthSchemas.d.ts +67 -0
  136. package/dist/commerce/oms/omsFulfillmentHealthSchemas.js +44 -0
  137. package/dist/commerce/oms/omsPorts.d.ts +84 -0
  138. package/dist/commerce/oms/omsPorts.js +148 -0
  139. package/dist/commerce/oms/omsPrimitives.d.ts +5 -0
  140. package/dist/commerce/oms/omsPrimitives.js +3 -0
  141. package/dist/commerce/oms/omsProviderEvidenceSchemas.d.ts +15 -0
  142. package/dist/commerce/oms/omsProviderEvidenceSchemas.js +12 -0
  143. package/dist/commerce/orderDraftErrors.d.ts +13 -0
  144. package/dist/commerce/orderDraftErrors.js +20 -0
  145. package/dist/commerce/orderEmailEligibility.d.ts +54 -0
  146. package/dist/commerce/orderEmailEligibility.js +123 -0
  147. package/dist/commerce/orderEmailLines.d.ts +12 -0
  148. package/dist/commerce/orderEmailLines.js +8 -0
  149. package/dist/commerce/orderFeedbackContracts.d.ts +41 -0
  150. package/dist/commerce/orderFeedbackContracts.js +33 -0
  151. package/dist/commerce/orderMoney.d.ts +6 -0
  152. package/dist/commerce/orderMoney.js +168 -0
  153. package/dist/commerce/orderReviewContracts.d.ts +475 -0
  154. package/dist/commerce/orderReviewContracts.js +94 -0
  155. package/dist/commerce/orderReviewPorts.d.ts +140 -0
  156. package/dist/commerce/orderReviewPorts.js +1 -0
  157. package/dist/commerce/outboxDispatchContracts.d.ts +30 -0
  158. package/dist/commerce/outboxDispatchContracts.js +1 -0
  159. package/dist/commerce/outboxEventSchemas.d.ts +162 -0
  160. package/dist/commerce/outboxEventSchemas.js +164 -0
  161. package/dist/commerce/outboxOrderDraftEmailPorts.d.ts +207 -0
  162. package/dist/commerce/outboxOrderDraftEmailPorts.js +12 -0
  163. package/dist/commerce/paymentContinuation.d.ts +4 -0
  164. package/dist/commerce/paymentContinuation.js +4 -0
  165. package/dist/commerce/ports.d.ts +8 -0
  166. package/dist/commerce/ports.js +1 -0
  167. package/dist/commerce/recoveryDestination.d.ts +3 -0
  168. package/dist/commerce/recoveryDestination.js +17 -0
  169. package/dist/commerce/runtimeErrors.d.ts +8 -0
  170. package/dist/commerce/runtimeErrors.js +16 -0
  171. package/dist/commerce/salesChannelEnvelope.d.ts +20 -0
  172. package/dist/commerce/salesChannelEnvelope.js +7 -0
  173. package/dist/commerce/schemas.d.ts +174 -0
  174. package/dist/commerce/schemas.js +84 -0
  175. package/dist/commerce/server/checkoutCompensation.d.ts +21 -0
  176. package/dist/commerce/server/checkoutCompensation.js +32 -0
  177. package/dist/commerce/server/checkoutConflictClassifiers.d.ts +17 -0
  178. package/dist/commerce/server/checkoutConflictClassifiers.js +38 -0
  179. package/dist/commerce/server/checkoutExpiredRecoveryPolicy.d.ts +38 -0
  180. package/dist/commerce/server/checkoutExpiredRecoveryPolicy.js +85 -0
  181. package/dist/commerce/server/checkoutInvoiceBuyerSnapshot.d.ts +22 -0
  182. package/dist/commerce/server/checkoutInvoiceBuyerSnapshot.js +30 -0
  183. package/dist/commerce/server/checkoutOfferPolicyPort.d.ts +33 -0
  184. package/dist/commerce/server/checkoutOfferPolicyPort.js +49 -0
  185. package/dist/commerce/server/checkoutPaymentContinuationCredential.d.ts +58 -0
  186. package/dist/commerce/server/checkoutPaymentContinuationCredential.js +154 -0
  187. package/dist/commerce/server/checkoutQuoteTypes.d.ts +19 -0
  188. package/dist/commerce/server/checkoutQuoteTypes.js +1 -0
  189. package/dist/commerce/server/checkoutRecoveryOrderPort.d.ts +42 -0
  190. package/dist/commerce/server/checkoutRecoveryOrderPort.js +1 -0
  191. package/dist/commerce/server/checkoutRecoveryToken.d.ts +40 -0
  192. package/dist/commerce/server/checkoutRecoveryToken.js +26 -0
  193. package/dist/commerce/server/checkoutRefusalContinuation.d.ts +24 -0
  194. package/dist/commerce/server/checkoutRefusalContinuation.js +18 -0
  195. package/dist/commerce/server/checkoutRuntimeTypes.d.ts +81 -0
  196. package/dist/commerce/server/checkoutRuntimeTypes.js +1 -0
  197. package/dist/commerce/server/commerceCheckoutCommandExecution.d.ts +60 -0
  198. package/dist/commerce/server/commerceCheckoutCommandExecution.js +136 -0
  199. package/dist/commerce/server/commerceCheckoutCompensation.d.ts +26 -0
  200. package/dist/commerce/server/commerceCheckoutCompensation.js +46 -0
  201. package/dist/commerce/server/commerceCheckoutContinuationTerms.d.ts +50 -0
  202. package/dist/commerce/server/commerceCheckoutContinuationTerms.js +66 -0
  203. package/dist/commerce/server/commerceCheckoutCustomerDefaults.d.ts +18 -0
  204. package/dist/commerce/server/commerceCheckoutCustomerDefaults.js +17 -0
  205. package/dist/commerce/server/commerceCheckoutFailureHandler.d.ts +51 -0
  206. package/dist/commerce/server/commerceCheckoutFailureHandler.js +90 -0
  207. package/dist/commerce/server/commerceCheckoutHandler.d.ts +213 -0
  208. package/dist/commerce/server/commerceCheckoutHandler.js +196 -0
  209. package/dist/commerce/server/commerceCheckoutHandlerAdmission.d.ts +58 -0
  210. package/dist/commerce/server/commerceCheckoutHandlerAdmission.js +94 -0
  211. package/dist/commerce/server/commerceCheckoutHandlerHelpers.d.ts +67 -0
  212. package/dist/commerce/server/commerceCheckoutHandlerHelpers.js +155 -0
  213. package/dist/commerce/server/commerceCheckoutOrchestrationError.d.ts +9 -0
  214. package/dist/commerce/server/commerceCheckoutOrchestrationError.js +14 -0
  215. package/dist/commerce/server/commerceCheckoutPromotionPriceChange.d.ts +47 -0
  216. package/dist/commerce/server/commerceCheckoutPromotionPriceChange.js +43 -0
  217. package/dist/commerce/server/commerceCheckoutProviderPayment.d.ts +34 -0
  218. package/dist/commerce/server/commerceCheckoutProviderPayment.js +37 -0
  219. package/dist/commerce/server/commerceCheckoutQuoteGuard.d.ts +62 -0
  220. package/dist/commerce/server/commerceCheckoutQuoteGuard.js +106 -0
  221. package/dist/commerce/server/commerceCheckoutResume.d.ts +29 -0
  222. package/dist/commerce/server/commerceCheckoutResume.js +81 -0
  223. package/dist/commerce/server/commerceCheckoutResumeGuard.d.ts +54 -0
  224. package/dist/commerce/server/commerceCheckoutResumeGuard.js +138 -0
  225. package/dist/commerce/server/commerceCheckoutSavedPaymentMethod.d.ts +39 -0
  226. package/dist/commerce/server/commerceCheckoutSavedPaymentMethod.js +44 -0
  227. package/dist/commerce/server/commerceCheckoutStartRuntimeFailure.d.ts +7 -0
  228. package/dist/commerce/server/commerceCheckoutStartRuntimeFailure.js +39 -0
  229. package/dist/commerce/server/commerceCheckoutTiming.d.ts +8 -0
  230. package/dist/commerce/server/commerceCheckoutTiming.js +31 -0
  231. package/dist/commerce/server/commerceDiagnostics.d.ts +6 -0
  232. package/dist/commerce/server/commerceDiagnostics.js +31 -0
  233. package/dist/commerce/server/commerceOmsCancelOrderHandler.d.ts +7 -0
  234. package/dist/commerce/server/commerceOmsCancelOrderHandler.js +22 -0
  235. package/dist/commerce/server/commerceOmsControlPlaneHandlers.d.ts +18 -0
  236. package/dist/commerce/server/commerceOmsControlPlaneHandlers.js +60 -0
  237. package/dist/commerce/server/commerceOmsHandlers.d.ts +47 -0
  238. package/dist/commerce/server/commerceOmsHandlers.js +176 -0
  239. package/dist/commerce/server/commerceOmsMarkRefundedHandler.d.ts +7 -0
  240. package/dist/commerce/server/commerceOmsMarkRefundedHandler.js +19 -0
  241. package/dist/commerce/server/commerceOrderDraft.d.ts +24 -0
  242. package/dist/commerce/server/commerceOrderDraft.js +92 -0
  243. package/dist/commerce/server/commercePaidOrderOrchestration.d.ts +131 -0
  244. package/dist/commerce/server/commercePaidOrderOrchestration.js +140 -0
  245. package/dist/commerce/server/commerceProviderAttemptFailure.d.ts +133 -0
  246. package/dist/commerce/server/commerceProviderAttemptFailure.js +175 -0
  247. package/dist/commerce/server/commerceReturnsHandlers.d.ts +41 -0
  248. package/dist/commerce/server/commerceReturnsHandlers.js +100 -0
  249. package/dist/commerce/server/commerceRuntimePort.d.ts +16 -0
  250. package/dist/commerce/server/commerceRuntimePort.js +57 -0
  251. package/dist/commerce/server/commerceRuntimeService.d.ts +98 -0
  252. package/dist/commerce/server/commerceRuntimeService.js +186 -0
  253. package/dist/commerce/server/commerceRuntimeStartResponse.d.ts +37 -0
  254. package/dist/commerce/server/commerceRuntimeStartResponse.js +56 -0
  255. package/dist/commerce/server/commerceStarterOfferGuard.d.ts +55 -0
  256. package/dist/commerce/server/commerceStarterOfferGuard.js +128 -0
  257. package/dist/commerce/server/configuratorIntentPersistence.d.ts +47 -0
  258. package/dist/commerce/server/configuratorIntentPersistence.js +85 -0
  259. package/dist/commerce/server/configuratorIntentPersistenceHandler.d.ts +14 -0
  260. package/dist/commerce/server/configuratorIntentPersistenceHandler.js +42 -0
  261. package/dist/commerce/server/emailRuntime.d.ts +47 -0
  262. package/dist/commerce/server/emailRuntime.js +1 -0
  263. package/dist/commerce/server/handlerSupport.d.ts +68 -0
  264. package/dist/commerce/server/handlerSupport.js +1 -0
  265. package/dist/commerce/server/index.d.ts +178 -0
  266. package/dist/commerce/server/index.js +127 -0
  267. package/dist/commerce/server/offerAvailability.d.ts +21 -0
  268. package/dist/commerce/server/offerAvailability.js +163 -0
  269. package/dist/commerce/server/orderDraftRpcPayload.d.ts +20 -0
  270. package/dist/commerce/server/orderDraftRpcPayload.js +21 -0
  271. package/dist/commerce/server/orderFeedbackSubmit.d.ts +20 -0
  272. package/dist/commerce/server/orderFeedbackSubmit.js +16 -0
  273. package/dist/commerce/server/orderFeedbackTokenCheck.d.ts +17 -0
  274. package/dist/commerce/server/orderFeedbackTokenCheck.js +14 -0
  275. package/dist/commerce/server/orderReviewAdminHandlers.d.ts +47 -0
  276. package/dist/commerce/server/orderReviewAdminHandlers.js +41 -0
  277. package/dist/commerce/server/orderReviewHandlers.d.ts +114 -0
  278. package/dist/commerce/server/orderReviewHandlers.js +42 -0
  279. package/dist/commerce/server/orderReviewLifecycle.d.ts +10 -0
  280. package/dist/commerce/server/orderReviewLifecycle.js +121 -0
  281. package/dist/commerce/server/orderReviewMedia.d.ts +11 -0
  282. package/dist/commerce/server/orderReviewMedia.js +172 -0
  283. package/dist/commerce/server/orderReviewRawUploadHandler.d.ts +40 -0
  284. package/dist/commerce/server/orderReviewRawUploadHandler.js +316 -0
  285. package/dist/commerce/server/outboxCheckoutExpiredEmailHandler.d.ts +14 -0
  286. package/dist/commerce/server/outboxCheckoutExpiredEmailHandler.js +57 -0
  287. package/dist/commerce/server/outboxCheckoutRecoveryEmailHandler.d.ts +13 -0
  288. package/dist/commerce/server/outboxCheckoutRecoveryEmailHandler.js +150 -0
  289. package/dist/commerce/server/outboxDispatchRegistry.d.ts +46 -0
  290. package/dist/commerce/server/outboxDispatchRegistry.js +184 -0
  291. package/dist/commerce/server/outboxDispatchRegistryComposition.d.ts +6 -0
  292. package/dist/commerce/server/outboxDispatchRegistryComposition.js +23 -0
  293. package/dist/commerce/server/outboxOrderDraftEmailHandler.d.ts +14 -0
  294. package/dist/commerce/server/outboxOrderDraftEmailHandler.js +130 -0
  295. package/dist/commerce/server/outboxOrderPaidEmailHandler.d.ts +21 -0
  296. package/dist/commerce/server/outboxOrderPaidEmailHandler.js +93 -0
  297. package/dist/commerce/server/outboxOrderPaidFulfillmentHandler.d.ts +3 -0
  298. package/dist/commerce/server/outboxOrderPaidFulfillmentHandler.js +1 -0
  299. package/dist/commerce/server/outboxOrderPaidFulfillmentPorts.d.ts +3 -0
  300. package/dist/commerce/server/outboxOrderPaidFulfillmentPorts.js +1 -0
  301. package/dist/commerce/server/outboxOrderRefundedEmailHandler.d.ts +13 -0
  302. package/dist/commerce/server/outboxOrderRefundedEmailHandler.js +42 -0
  303. package/dist/commerce/server/outboxPaymentFailedEmailHandler.d.ts +14 -0
  304. package/dist/commerce/server/outboxPaymentFailedEmailHandler.js +65 -0
  305. package/dist/commerce/server/outboxReturnEmailHandlers.d.ts +26 -0
  306. package/dist/commerce/server/outboxReturnEmailHandlers.js +53 -0
  307. package/dist/commerce/server/outboxShipmentDeliveredEmailHandler.d.ts +17 -0
  308. package/dist/commerce/server/outboxShipmentDeliveredEmailHandler.js +52 -0
  309. package/dist/commerce/server/outboxShipmentDispatchedEmailHandler.d.ts +13 -0
  310. package/dist/commerce/server/outboxShipmentDispatchedEmailHandler.js +87 -0
  311. package/dist/commerce/server/outboxShipmentExceptionEmailHandler.d.ts +13 -0
  312. package/dist/commerce/server/outboxShipmentExceptionEmailHandler.js +46 -0
  313. package/dist/commerce/server/referenceCheckoutHandler.d.ts +48 -0
  314. package/dist/commerce/server/referenceCheckoutHandler.js +68 -0
  315. package/dist/commerce/server/reservationSweepPort.d.ts +31 -0
  316. package/dist/commerce/server/reservationSweepPort.js +45 -0
  317. package/dist/commerce/server/starterTermsPort.d.ts +22 -0
  318. package/dist/commerce/server/starterTermsPort.js +1 -0
  319. package/dist/commerce/server/supabaseCommerceReturnsPort.d.ts +13 -0
  320. package/dist/commerce/server/supabaseCommerceReturnsPort.js +56 -0
  321. package/dist/communications/consentPurposeRegistry.d.ts +1 -1
  322. package/dist/communications/newsletterIntegrationContracts.d.ts +5 -5
  323. package/dist/composition/commerceContribution.d.ts +21 -0
  324. package/dist/composition/commerceContribution.js +27 -0
  325. package/dist/composition/index.d.ts +1 -0
  326. package/dist/composition/index.js +1 -0
  327. package/dist/fulfillment/handlerSchemas.d.ts +41 -41
  328. package/dist/fulfillment/index.d.ts +1 -1
  329. package/dist/fulfillment/index.js +1 -1
  330. package/dist/fulfillment/paidHandoff.d.ts +12 -1
  331. package/dist/fulfillment/paidHandoff.js +2 -2
  332. package/dist/fulfillment/providerDispatchWorker.d.ts +4 -4
  333. package/dist/identity/customerContracts.d.ts +2 -2
  334. package/dist/inventory/bindings.d.ts +3 -0
  335. package/dist/inventory/bindings.js +10 -4
  336. package/dist/inventory/index.d.ts +1 -0
  337. package/dist/inventory/index.js +1 -0
  338. package/dist/inventory/managedStockAvailability.d.ts +15 -0
  339. package/dist/inventory/managedStockAvailability.js +16 -0
  340. package/dist/inventory/postgresStockAvailability.js +2 -25
  341. package/dist/inventory/schemas.d.ts +1 -1
  342. package/dist/inventory/stockReadResponse.d.ts +4 -0
  343. package/dist/inventory/stockReadResponse.js +27 -0
  344. package/dist/pricing/browser/index.d.ts +6 -0
  345. package/dist/pricing/browser/index.js +6 -0
  346. package/dist/promotions/adminPromotionsContracts.d.ts +2 -2
  347. package/dist/subscriptions/contracts/renewal.d.ts +2 -0
  348. package/dist/subscriptions/index.d.ts +3 -2
  349. package/dist/subscriptions/index.js +3 -2
  350. package/dist/subscriptions/renewalCycleFailureMechanism.js +3 -2
  351. package/package.json +22 -2
  352. package/release-gates.json +63 -8
  353. package/src/commerce/adapters/managed/commerceOmsControlPlane.ts +80 -0
  354. package/src/commerce/adapters/managed/commerceOmsMutations.ts +145 -0
  355. package/src/commerce/adapters/managed/commerceOmsPort.ts +158 -0
  356. package/src/commerce/adapters/managed/oms/accounting.ts +18 -0
  357. package/src/commerce/adapters/managed/oms/fulfillmentReads.ts +82 -0
  358. package/src/commerce/adapters/managed/oms/inboundEvents.ts +45 -0
  359. package/src/commerce/adapters/managed/oms/outboxEvents.ts +30 -0
  360. package/src/commerce/adapters/managed/oms/paymentAttempts.ts +19 -0
  361. package/src/commerce/adapters/managed/oms/queueSelection.ts +132 -0
  362. package/src/commerce/adapters/managed/oms/readProjections.ts +22 -0
  363. package/src/commerce/adapters/managed/oms/readQueries.ts +292 -0
  364. package/src/commerce/adapters/managed/oms/types.ts +9 -0
  365. package/src/commerce/checkoutCommandSchemas.ts +93 -0
  366. package/src/commerce/checkoutHelpers.ts +47 -0
  367. package/src/commerce/checkoutResumeSchemas.ts +164 -0
  368. package/src/commerce/checkoutSchemas.ts +182 -0
  369. package/src/commerce/commerceReturnsPort.ts +67 -0
  370. package/src/commerce/configuratorIntentPersistenceSchemas.ts +26 -0
  371. package/src/commerce/configuratorIntentSchemas.ts +47 -0
  372. package/src/commerce/contractPrimitives.ts +30 -0
  373. package/src/commerce/contracts/availability.ts +21 -0
  374. package/src/commerce/contracts/fulfillmentRecovery.ts +26 -0
  375. package/src/commerce/contracts/index.ts +17 -0
  376. package/src/commerce/contracts/intent.ts +58 -0
  377. package/src/commerce/contracts/omsTypes.ts +1217 -0
  378. package/src/commerce/contracts/order.ts +44 -0
  379. package/src/commerce/contracts/orderMoney.ts +75 -0
  380. package/src/commerce/contracts/ports.ts +124 -0
  381. package/src/commerce/contracts/recovery.ts +24 -0
  382. package/src/commerce/contracts/runtimePorts.ts +201 -0
  383. package/src/commerce/contracts/state.ts +64 -0
  384. package/src/commerce/customerDefaultsSnapshotSchemas.ts +117 -0
  385. package/src/commerce/errors.ts +53 -0
  386. package/src/commerce/fulfillmentEligibility.ts +32 -0
  387. package/src/commerce/index.ts +82 -0
  388. package/src/commerce/model/customerFulfillmentRecovery.ts +185 -0
  389. package/src/commerce/model/fulfillmentCancellationEligibility.ts +18 -0
  390. package/src/commerce/model/omsAccountingVisibility.ts +135 -0
  391. package/src/commerce/model/omsBillingInvoiceBuyer.ts +20 -0
  392. package/src/commerce/model/omsCurrency.ts +8 -0
  393. package/src/commerce/model/omsFulfillmentDebug.ts +157 -0
  394. package/src/commerce/model/omsFulfillmentSummary.ts +225 -0
  395. package/src/commerce/model/omsListTotals.ts +38 -0
  396. package/src/commerce/model/omsOperationalLadder.ts +181 -0
  397. package/src/commerce/model/omsOrderLineMoney.ts +34 -0
  398. package/src/commerce/model/omsPaymentMethodSummary.ts +19 -0
  399. package/src/commerce/model/omsReadModel.ts +302 -0
  400. package/src/commerce/model/omsReadModelCommunication.ts +32 -0
  401. package/src/commerce/model/omsReadModelHelpers.ts +279 -0
  402. package/src/commerce/model/omsReadModelList.ts +90 -0
  403. package/src/commerce/model/omsReadModelListSummary.ts +19 -0
  404. package/src/commerce/model/omsReadModelPricing.ts +57 -0
  405. package/src/commerce/model/omsReadModelProjections.ts +1 -0
  406. package/src/commerce/model/omsReadModelRowCore.ts +193 -0
  407. package/src/commerce/model/omsReadModelRows.ts +7 -0
  408. package/src/commerce/offerAvailability.ts +75 -0
  409. package/src/commerce/offerAvailabilitySchemas.ts +56 -0
  410. package/src/commerce/offerEvidenceSchemas.ts +17 -0
  411. package/src/commerce/oms/omsContractBase.ts +92 -0
  412. package/src/commerce/oms/omsContractReadAuxSchemas.ts +130 -0
  413. package/src/commerce/oms/omsContractReadSchemas.ts +303 -0
  414. package/src/commerce/oms/omsContractRequests.ts +143 -0
  415. package/src/commerce/oms/omsContracts.ts +6 -0
  416. package/src/commerce/oms/omsControlPlane.ts +85 -0
  417. package/src/commerce/oms/omsFulfillmentContractSchemas.ts +113 -0
  418. package/src/commerce/oms/omsFulfillmentDebugSchemas.ts +38 -0
  419. package/src/commerce/oms/omsFulfillmentHealthSchemas.ts +46 -0
  420. package/src/commerce/oms/omsPorts.ts +165 -0
  421. package/src/commerce/oms/omsPrimitives.ts +3 -0
  422. package/src/commerce/oms/omsProviderEvidenceSchemas.ts +13 -0
  423. package/src/commerce/orderDraftErrors.ts +28 -0
  424. package/src/commerce/orderEmailEligibility.ts +131 -0
  425. package/src/commerce/orderEmailLines.ts +22 -0
  426. package/src/commerce/orderFeedbackContracts.ts +47 -0
  427. package/src/commerce/orderMoney.ts +207 -0
  428. package/src/commerce/orderReviewContracts.ts +124 -0
  429. package/src/commerce/orderReviewPorts.ts +94 -0
  430. package/src/commerce/outboxDispatchContracts.ts +30 -0
  431. package/src/commerce/outboxEventSchemas.ts +230 -0
  432. package/src/commerce/outboxOrderDraftEmailPorts.ts +241 -0
  433. package/src/commerce/paymentContinuation.ts +5 -0
  434. package/src/commerce/ports.ts +7 -0
  435. package/src/commerce/recoveryDestination.ts +23 -0
  436. package/src/commerce/runtimeErrors.ts +19 -0
  437. package/src/commerce/salesChannelEnvelope.ts +28 -0
  438. package/src/commerce/schemas.ts +104 -0
  439. package/src/commerce/server/checkoutCompensation.ts +49 -0
  440. package/src/commerce/server/checkoutConflictClassifiers.ts +53 -0
  441. package/src/commerce/server/checkoutExpiredRecoveryPolicy.ts +107 -0
  442. package/src/commerce/server/checkoutInvoiceBuyerSnapshot.ts +36 -0
  443. package/src/commerce/server/checkoutOfferPolicyPort.ts +60 -0
  444. package/src/commerce/server/checkoutPaymentContinuationCredential.ts +222 -0
  445. package/src/commerce/server/checkoutQuoteTypes.ts +9 -0
  446. package/src/commerce/server/checkoutRecoveryOrderPort.ts +40 -0
  447. package/src/commerce/server/checkoutRecoveryToken.ts +63 -0
  448. package/src/commerce/server/checkoutRefusalContinuation.ts +29 -0
  449. package/src/commerce/server/checkoutRuntimeTypes.ts +26 -0
  450. package/src/commerce/server/commerceCheckoutCommandExecution.ts +188 -0
  451. package/src/commerce/server/commerceCheckoutCompensation.ts +66 -0
  452. package/src/commerce/server/commerceCheckoutContinuationTerms.ts +87 -0
  453. package/src/commerce/server/commerceCheckoutCustomerDefaults.ts +24 -0
  454. package/src/commerce/server/commerceCheckoutFailureHandler.ts +144 -0
  455. package/src/commerce/server/commerceCheckoutHandler.ts +269 -0
  456. package/src/commerce/server/commerceCheckoutHandlerAdmission.ts +157 -0
  457. package/src/commerce/server/commerceCheckoutHandlerHelpers.ts +223 -0
  458. package/src/commerce/server/commerceCheckoutOrchestrationError.ts +15 -0
  459. package/src/commerce/server/commerceCheckoutPromotionPriceChange.ts +83 -0
  460. package/src/commerce/server/commerceCheckoutProviderPayment.ts +45 -0
  461. package/src/commerce/server/commerceCheckoutQuoteGuard.ts +172 -0
  462. package/src/commerce/server/commerceCheckoutResume.ts +132 -0
  463. package/src/commerce/server/commerceCheckoutResumeGuard.ts +195 -0
  464. package/src/commerce/server/commerceCheckoutSavedPaymentMethod.ts +85 -0
  465. package/src/commerce/server/commerceCheckoutStartRuntimeFailure.ts +59 -0
  466. package/src/commerce/server/commerceCheckoutTiming.ts +53 -0
  467. package/src/commerce/server/commerceDiagnostics.ts +37 -0
  468. package/src/commerce/server/commerceOmsCancelOrderHandler.ts +43 -0
  469. package/src/commerce/server/commerceOmsControlPlaneHandlers.ts +71 -0
  470. package/src/commerce/server/commerceOmsHandlers.ts +275 -0
  471. package/src/commerce/server/commerceOmsMarkRefundedHandler.ts +39 -0
  472. package/src/commerce/server/commerceOrderDraft.ts +131 -0
  473. package/src/commerce/server/commercePaidOrderOrchestration.ts +275 -0
  474. package/src/commerce/server/commerceProviderAttemptFailure.ts +257 -0
  475. package/src/commerce/server/commerceReturnsHandlers.ts +143 -0
  476. package/src/commerce/server/commerceRuntimePort.ts +75 -0
  477. package/src/commerce/server/commerceRuntimeService.ts +229 -0
  478. package/src/commerce/server/commerceRuntimeStartResponse.ts +76 -0
  479. package/src/commerce/server/commerceStarterOfferGuard.ts +200 -0
  480. package/src/commerce/server/configuratorIntentPersistence.ts +161 -0
  481. package/src/commerce/server/configuratorIntentPersistenceHandler.ts +54 -0
  482. package/src/commerce/server/emailRuntime.ts +30 -0
  483. package/src/commerce/server/handlerSupport.ts +22 -0
  484. package/src/commerce/server/index.ts +181 -0
  485. package/src/commerce/server/offerAvailability.ts +275 -0
  486. package/src/commerce/server/orderDraftRpcPayload.ts +39 -0
  487. package/src/commerce/server/orderFeedbackSubmit.ts +40 -0
  488. package/src/commerce/server/orderFeedbackTokenCheck.ts +28 -0
  489. package/src/commerce/server/orderReviewAdminHandlers.ts +43 -0
  490. package/src/commerce/server/orderReviewHandlers.ts +57 -0
  491. package/src/commerce/server/orderReviewLifecycle.ts +129 -0
  492. package/src/commerce/server/orderReviewMedia.ts +170 -0
  493. package/src/commerce/server/orderReviewRawUploadHandler.ts +300 -0
  494. package/src/commerce/server/outboxCheckoutExpiredEmailHandler.ts +86 -0
  495. package/src/commerce/server/outboxCheckoutRecoveryEmailHandler.ts +188 -0
  496. package/src/commerce/server/outboxDispatchRegistry.ts +269 -0
  497. package/src/commerce/server/outboxDispatchRegistryComposition.ts +31 -0
  498. package/src/commerce/server/outboxOrderDraftEmailHandler.ts +162 -0
  499. package/src/commerce/server/outboxOrderPaidEmailHandler.ts +147 -0
  500. package/src/commerce/server/outboxOrderPaidFulfillmentHandler.ts +4 -0
  501. package/src/commerce/server/outboxOrderPaidFulfillmentPorts.ts +3 -0
  502. package/src/commerce/server/outboxOrderRefundedEmailHandler.ts +58 -0
  503. package/src/commerce/server/outboxPaymentFailedEmailHandler.ts +99 -0
  504. package/src/commerce/server/outboxReturnEmailHandlers.ts +92 -0
  505. package/src/commerce/server/outboxShipmentDeliveredEmailHandler.ts +94 -0
  506. package/src/commerce/server/outboxShipmentDispatchedEmailHandler.ts +112 -0
  507. package/src/commerce/server/outboxShipmentExceptionEmailHandler.ts +73 -0
  508. package/src/commerce/server/referenceCheckoutHandler.ts +87 -0
  509. package/src/commerce/server/reservationSweepPort.ts +67 -0
  510. package/src/commerce/server/starterTermsPort.ts +22 -0
  511. package/src/commerce/server/supabaseCommerceReturnsPort.ts +81 -0
  512. package/src/composition/commerceContribution.ts +35 -0
  513. package/src/composition/index.ts +1 -0
  514. package/src/fulfillment/index.ts +1 -1
  515. package/src/fulfillment/paidHandoff.ts +2 -2
  516. package/src/inventory/bindings.ts +12 -4
  517. package/src/inventory/index.ts +1 -0
  518. package/src/inventory/managedStockAvailability.ts +23 -0
  519. package/src/inventory/postgresStockAvailability.ts +2 -21
  520. package/src/inventory/stockReadResponse.ts +25 -0
  521. package/src/pricing/browser/index.ts +6 -0
  522. package/src/subscriptions/contracts/renewal.ts +2 -1
  523. package/src/subscriptions/index.ts +3 -2
  524. package/src/subscriptions/renewalCycleFailureMechanism.ts +3 -1
@@ -0,0 +1,60 @@
1
+ import type { CheckoutKind, CheckoutOfferPolicyPort } from "../contracts/index.js";
2
+ import { commerceOfferEvidenceSchema } from "../offerEvidenceSchemas.js";
3
+ export type { CheckoutOfferPolicyPort } from "../contracts/index.js";
4
+ /** The refusal of an intent that carries an offer field when no adopter port is wired. */
5
+ export const CHECKOUT_OFFER_VERSION_UNSUPPORTED = "offer_version_unsupported";
6
+
7
+ export class CheckoutOfferRefusedError extends Error {
8
+ readonly reason: string;
9
+
10
+ constructor(reason: string) {
11
+ super(`checkout_offer_refused:${reason}`);
12
+ this.name = "CheckoutOfferRefusedError";
13
+ this.reason = reason;
14
+ }
15
+ }
16
+
17
+ export type CheckoutOfferBinding<Intent, Quote> = { port: CheckoutOfferPolicyPort<Intent, Quote>; offerVersion: string };
18
+
19
+ /**
20
+ * Null, without a port call, for an intent that carries neither `offerVersion`
21
+ * nor `minimumUnits`. Otherwise the adopter's port must bind the offer: without
22
+ * a port the intent is refused with `offer_version_unsupported`, and a port
23
+ * refusal keeps its own reason. Both throw `CheckoutOfferRefusedError`.
24
+ */
25
+ export async function resolveCheckoutOffer<Intent extends { offerVersion?: string; minimumUnits?: number }, Quote>(
26
+ port: CheckoutOfferPolicyPort<Intent, Quote> | undefined,
27
+ intent: Intent,
28
+ checkoutKind: CheckoutKind,
29
+ ): Promise<CheckoutOfferBinding<Intent, Quote> | null> {
30
+ if (intent.offerVersion === undefined && intent.minimumUnits === undefined) return null;
31
+ if (!port) throw new CheckoutOfferRefusedError(CHECKOUT_OFFER_VERSION_UNSUPPORTED);
32
+ const resolution = await port.resolve({ intent, checkoutKind });
33
+ if (resolution.kind === "refused") throw new CheckoutOfferRefusedError(resolution.reason);
34
+ return { port, offerVersion: resolution.offerVersion };
35
+ }
36
+
37
+ /**
38
+ * Writes a bound offer version and the adopter's evidence, checked against
39
+ * `commerceOfferEvidenceSchema`, into an accepted snapshot's context. Without a
40
+ * binding the same snapshot is returned; a bound snapshot without a context
41
+ * fails closed.
42
+ */
43
+ export async function withCheckoutOfferContext<Intent, Quote extends { context?: object }, Response extends { quote: Quote }>(
44
+ binding: CheckoutOfferBinding<Intent, Quote> | null,
45
+ intent: Intent,
46
+ snapshot: Response,
47
+ ): Promise<Response> {
48
+ if (!binding) return snapshot;
49
+ const context = snapshot.quote.context;
50
+ if (!context) throw new Error("checkout_offer_context_missing");
51
+ const offerEvidence = commerceOfferEvidenceSchema.parse(await binding.port.evidence({
52
+ intent,
53
+ offerVersion: binding.offerVersion,
54
+ quote: snapshot.quote,
55
+ }));
56
+ return {
57
+ ...snapshot,
58
+ quote: { ...snapshot.quote, context: { ...context, offerVersion: binding.offerVersion, offerEvidence } },
59
+ };
60
+ }
@@ -0,0 +1,222 @@
1
+ import { createHmac, timingSafeEqual } from "node:crypto";
2
+ import { CHECKOUT_PAYMENT_CONTINUATION_TTL_SECONDS } from "../paymentContinuation.js";
3
+ export type CheckoutContinuationAction = { kind: string; provider?: string; clientSecret?: string; url?: string };
4
+
5
+ const PURPOSE = "commerce.checkout-payment-continuation.v1" as const;
6
+ const DEFAULT_TTL_SECONDS = CHECKOUT_PAYMENT_CONTINUATION_TTL_SECONDS;
7
+ const MIN_TTL_SECONDS = 60;
8
+ const MAX_TTL_SECONDS = CHECKOUT_PAYMENT_CONTINUATION_TTL_SECONDS;
9
+ const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
10
+ const JOURNEY_PATTERN = /^checkout:[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
11
+
12
+
13
+
14
+ export interface CheckoutPaymentContinuationInput<Rail extends string = string> {
15
+ journeyId: string;
16
+ orderId: string;
17
+ clientId: string;
18
+ paymentIntentId: string;
19
+ paymentAttemptId: string;
20
+ executionRail: Rail;
21
+ }
22
+
23
+ export interface CheckoutPaymentContinuationClaims<Rail extends string = string> extends CheckoutPaymentContinuationInput<Rail> {
24
+ version: 1;
25
+ purpose: typeof PURPOSE;
26
+ expiresAt: number;
27
+ }
28
+
29
+ export interface CheckoutPaymentContinuationCodec<Rail extends string = string> {
30
+ issue(input: CheckoutPaymentContinuationInput<Rail>): {
31
+ claims: CheckoutPaymentContinuationClaims<Rail>;
32
+ setCookie: string;
33
+ };
34
+ verifyCookieHeader(cookieHeader: unknown): CheckoutPaymentContinuationClaims<Rail> | null;
35
+ }
36
+
37
+ export type CheckoutPaymentContinuationMinter<Rail extends string = string> = (
38
+ res: CheckoutCookieResponse,
39
+ input: CheckoutPaymentContinuationInput<Rail>,
40
+ ) => void;
41
+
42
+ export interface CheckoutCookieResponse {
43
+ getHeader?(name: string): string | number | string[] | undefined;
44
+ setHeader(name: string, value: number | string | readonly string[]): unknown;
45
+ }
46
+
47
+ export function mintPaymentContinuationOnFreshAction<Rail extends string>(input: {
48
+ mint?: CheckoutPaymentContinuationMinter<Rail>;
49
+ res: CheckoutCookieResponse;
50
+ journeyId: string;
51
+ clientId: string;
52
+ requestRail: string;
53
+ response: { status: string; clientAction?: CheckoutContinuationAction };
54
+ result: {
55
+ continuationActionOrigin: "fresh_execution" | null;
56
+ executionRail: string;
57
+ paymentAttemptId: string | null;
58
+ paymentIntentId: string;
59
+ orderId: string;
60
+ };
61
+ }, executionRails: readonly [Rail, Rail]): void {
62
+ const { result, response } = input;
63
+ if (
64
+ result.continuationActionOrigin !== "fresh_execution"
65
+ || !result.paymentAttemptId
66
+ || !isCheckoutContinuationRail(result.executionRail, executionRails)
67
+ || result.executionRail !== input.requestRail
68
+ || response.status === "price_changed"
69
+ || !responseWantsContinuation(response, result.executionRail, executionRails)
70
+ ) return;
71
+ // Split out from the guard above ON PURPOSE. Every condition there says "this
72
+ // attempt does not want a continuation"; this one says "it wants one and we
73
+ // cannot issue it", which is an operator problem and used to be
74
+ // indistinguishable from the first. That silence is how the capability stayed
75
+ // dormant in every environment without anyone noticing. Rail and reason only:
76
+ // no order, client, attempt or intent id is logged.
77
+ if (!input.mint) {
78
+ console.warn(
79
+ "checkout_payment_continuation_unavailable",
80
+ JSON.stringify({ executionRail: result.executionRail, reason: "no_signing_secret" }),
81
+ );
82
+ return;
83
+ }
84
+ try {
85
+ input.mint(input.res, {
86
+ journeyId: input.journeyId,
87
+ orderId: result.orderId,
88
+ clientId: input.clientId,
89
+ paymentIntentId: result.paymentIntentId,
90
+ paymentAttemptId: result.paymentAttemptId,
91
+ executionRail: result.executionRail,
92
+ });
93
+ } catch {
94
+ // Continuation is best-effort; checkout success must never depend on it.
95
+ }
96
+ }
97
+
98
+ export function createCheckoutPaymentContinuationCodec<Rail extends string>(
99
+ rootSecret: string | undefined,
100
+ options: { cookieName: string; executionRails: readonly [Rail, Rail]; now?: () => Date; ttlSeconds?: number },
101
+ ): CheckoutPaymentContinuationCodec<Rail> | null {
102
+ if (!rootSecret || Buffer.byteLength(rootSecret, "utf8") < 32) return null;
103
+ const now = options.now ?? (() => new Date());
104
+ const ttlSeconds = options.ttlSeconds ?? DEFAULT_TTL_SECONDS;
105
+ if (!Number.isInteger(ttlSeconds) || ttlSeconds < MIN_TTL_SECONDS || ttlSeconds > MAX_TTL_SECONDS) {
106
+ throw new Error(
107
+ `Checkout payment continuation TTL must be between ${MIN_TTL_SECONDS} and ${MAX_TTL_SECONDS} seconds`,
108
+ );
109
+ }
110
+ const signingKey = createHmac("sha256", rootSecret).update(PURPOSE).digest();
111
+
112
+ function sign(payload: string): string {
113
+ return createHmac("sha256", signingKey).update(payload).digest("base64url");
114
+ }
115
+
116
+ return {
117
+ issue(input) {
118
+ if (!isValidInput(input, options.executionRails)) throw new Error("Invalid checkout payment continuation input");
119
+ const claims: CheckoutPaymentContinuationClaims<Rail> = {
120
+ version: 1,
121
+ purpose: PURPOSE,
122
+ expiresAt: Math.floor(now().getTime() / 1000) + ttlSeconds,
123
+ ...input,
124
+ };
125
+ const payload = Buffer.from(JSON.stringify(claims), "utf8").toString("base64url");
126
+ const token = `${payload}.${sign(payload)}`;
127
+ return {
128
+ claims,
129
+ setCookie: `${options.cookieName}=${token}; Path=/; Max-Age=${ttlSeconds}; Secure; HttpOnly; SameSite=Strict`,
130
+ };
131
+ },
132
+ verifyCookieHeader(cookieHeader) {
133
+ const token = readCookie(cookieHeader, options.cookieName);
134
+ if (!token) return null;
135
+ const separator = token.indexOf(".");
136
+ if (separator <= 0 || separator === token.length - 1 || token.indexOf(".", separator + 1) !== -1) return null;
137
+ const payload = token.slice(0, separator);
138
+ const suppliedSignature = token.slice(separator + 1);
139
+ const expectedSignature = sign(payload);
140
+ const supplied = Buffer.from(suppliedSignature, "utf8");
141
+ const expected = Buffer.from(expectedSignature, "utf8");
142
+ if (supplied.length !== expected.length || !timingSafeEqual(supplied, expected)) return null;
143
+ try {
144
+ const parsed = JSON.parse(Buffer.from(payload, "base64url").toString("utf8")) as unknown;
145
+ if (!isValidClaims(parsed, options.executionRails)) return null;
146
+ if (parsed.expiresAt <= Math.floor(now().getTime() / 1000)) return null;
147
+ return parsed;
148
+ } catch {
149
+ return null;
150
+ }
151
+ },
152
+ };
153
+ }
154
+
155
+ function isValidInput<Rail extends string>(value: unknown, executionRails: readonly Rail[]): value is CheckoutPaymentContinuationInput<Rail> {
156
+ if (!isRecord(value)) return false;
157
+ return JOURNEY_PATTERN.test(readString(value, "journeyId"))
158
+ && UUID_PATTERN.test(readString(value, "orderId"))
159
+ && UUID_PATTERN.test(readString(value, "clientId"))
160
+ && UUID_PATTERN.test(readString(value, "paymentIntentId"))
161
+ && UUID_PATTERN.test(readString(value, "paymentAttemptId"))
162
+ && isCheckoutContinuationRail(value.executionRail, executionRails);
163
+ }
164
+
165
+ function isValidClaims<Rail extends string>(value: unknown, executionRails: readonly Rail[]): value is CheckoutPaymentContinuationClaims<Rail> {
166
+ if (!isRecord(value)) return false;
167
+ const keys = Object.keys(value).sort();
168
+ const expectedKeys = [
169
+ "clientId", "expiresAt", "journeyId", "orderId", "paymentAttemptId",
170
+ "executionRail", "paymentIntentId", "purpose", "version",
171
+ ].sort();
172
+ return keys.length === expectedKeys.length
173
+ && keys.every((key, index) => key === expectedKeys[index])
174
+ && value.version === 1
175
+ && value.purpose === PURPOSE
176
+ && Number.isInteger(value.expiresAt)
177
+ && isValidInput(value, executionRails);
178
+ }
179
+
180
+ function readCookie(header: unknown, name: string): string | null {
181
+ const raw = Array.isArray(header) ? header[0] : header;
182
+ if (typeof raw !== "string") return null;
183
+ for (const part of raw.split(";")) {
184
+ const trimmed = part.trim();
185
+ const separator = trimmed.indexOf("=");
186
+ if (separator > 0 && trimmed.slice(0, separator) === name) {
187
+ return trimmed.slice(separator + 1) || null;
188
+ }
189
+ }
190
+ return null;
191
+ }
192
+
193
+ function isRecord(value: unknown): value is Record<string, unknown> {
194
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
195
+ }
196
+
197
+ function readString(value: Record<string, unknown>, key: string): string {
198
+ return typeof value[key] === "string" ? value[key] : "";
199
+ }
200
+
201
+ function responseWantsContinuation<Rail extends string>(
202
+ response: { status: string; clientAction?: CheckoutContinuationAction },
203
+ rail: Rail,
204
+ executionRails: readonly Rail[],
205
+ ): boolean {
206
+ return actionMatchesExecutionRail(response.clientAction, rail, executionRails)
207
+ || (response.clientAction?.kind === "none" && response.status === "processing");
208
+ }
209
+
210
+ function actionMatchesExecutionRail<Rail extends string>(
211
+ action: CheckoutContinuationAction | undefined,
212
+ rail: Rail,
213
+ executionRails: readonly Rail[],
214
+ ): boolean {
215
+ return rail === executionRails[0]
216
+ ? action?.kind === "provider_embedded" && action.provider === executionRails[0]
217
+ : action?.kind === "redirect";
218
+ }
219
+
220
+ export function isCheckoutContinuationRail<Rail extends string>(value: unknown, executionRails: readonly Rail[]): value is Rail {
221
+ return typeof value === "string" && (executionRails as readonly string[]).includes(value);
222
+ }
@@ -0,0 +1,9 @@
1
+ import type { AcquisitionTermsExpectation, ResolvedAcquisitionTerms, CreateQuoteResponse, CommerceQuoteContext, PricingPolicySnapshot } from "../../pricing/index.js";
2
+ export interface CheckoutQuoteSnapshot extends CreateQuoteResponse {
3
+ quote: CreateQuoteResponse["quote"] & { context?: CommerceQuoteContext & { pricingPolicy?: PricingPolicySnapshot; acquisitionTerms?: ResolvedAcquisitionTerms; shippingTerms?: unknown; offerVersion?: string } };
4
+ }
5
+ export interface ExpectedCheckoutQuote {
6
+ totalGross: { amountMinor: number; currency: string };
7
+ pricingPolicy?: PricingPolicySnapshot;
8
+ acquisitionTerms?: AcquisitionTermsExpectation;
9
+ }
@@ -0,0 +1,40 @@
1
+ export interface CheckoutRecoveryPriorPaymentEvidence {
2
+ paymentIntentId: string;
3
+ paymentAttemptId: string;
4
+ provider: string;
5
+ providerPaymentId: string | null;
6
+ idempotencyKey: string;
7
+ retryRequestId: string | null;
8
+ }
9
+
10
+ export type CheckoutRecoveryOrderSnapshot<Quote, PaymentStatus, Host extends object = object> = Host & {
11
+ orderId: string;
12
+ orderRef: string;
13
+ orderNumber: string;
14
+ clientId: string;
15
+ status: string;
16
+ mode: "subscription_cycle" | "one_time_order";
17
+ totalMinor: number;
18
+ currency: string;
19
+ cadenceDays: number | null;
20
+ createdAt: string;
21
+ customerEmail: string | null;
22
+ customerName: string | null;
23
+ paymentIntentId: string | null;
24
+ paymentIntentStatus: PaymentStatus | null;
25
+ subscriptionId: string | null;
26
+ subscriptionCycleId: string | null;
27
+ shippingAddressId?: string | null;
28
+ quoteSnapshot?: Quote | null;
29
+ runtimeMetadata?: Record<string, unknown>;
30
+ invoiceBuyerSnapshot?: Record<string, unknown>;
31
+ recoveryRootOrderId?: string;
32
+ recreatedFromOrderId?: string | null;
33
+ technicallyExpired?: boolean;
34
+ priorPaymentEvidence?: CheckoutRecoveryPriorPaymentEvidence | null;
35
+ }
36
+
37
+ export interface CheckoutRecoveryOrderReadPort<Order> {
38
+ getRecoveryOrder(input: { orderId: string }): Promise<Order | null>;
39
+ getLatestRecoveryOrder?(input: { orderId: string }): Promise<Order | null>;
40
+ }
@@ -0,0 +1,63 @@
1
+ import { createHash, randomBytes } from "node:crypto";
2
+
3
+ export interface CheckoutRecoveryTokenContext {
4
+ tokenId: string;
5
+ orderId: string;
6
+ clientId: string;
7
+ /** "subscription_cycle" | "one_time_order" — drives copy + post-pay activation. */
8
+ mode: string;
9
+ status: string;
10
+ }
11
+
12
+ export interface CheckoutRecoveryTokenInspection {
13
+ tokenId: string;
14
+ orderId: string;
15
+ clientId: string;
16
+ /** Null when the token exists but the order row is already gone. */
17
+ mode: string | null;
18
+ status: string | null;
19
+ subscriptionId: string | null;
20
+ tokenState: string;
21
+ }
22
+
23
+ /** Inspection RPC states; only the named continuation states may resume pending orders. */
24
+ export function classifyCheckoutRecoveryTokenState(
25
+ tokenState: string,
26
+ ): "continuation" | "expired_policy" | "refused" {
27
+ switch (tokenState) {
28
+ case "active":
29
+ case "order_not_recoverable":
30
+ return "continuation";
31
+ case "expired":
32
+ return "expired_policy";
33
+ case "revoked":
34
+ case "used":
35
+ case "order_not_found":
36
+ default:
37
+ return "refused";
38
+ }
39
+ }
40
+
41
+ export interface CheckoutRecoveryTokenPort {
42
+ /** Issue a token for an unpaid order. Returns the new token row id. */
43
+ issue(input: { orderId: string; rawToken: string; expiresAt: string }): Promise<string>;
44
+ /** Validate a raw token; returns the order context, or null if invalid/expired/not recoverable. */
45
+ validate(rawToken: string, now?: Date): Promise<CheckoutRecoveryTokenContext | null>;
46
+ /**
47
+ * Inspect without granting continuation; callers must check state before reconstructing authority.
48
+ */
49
+ inspect(rawToken: string, now?: Date): Promise<CheckoutRecoveryTokenInspection | null>;
50
+ }
51
+
52
+ /** Canonical hash: SHA-256 hex of the raw token (matches the SQL `encode(sha256(...))`). */
53
+ export function hashCheckoutRecoveryToken(token: string): string {
54
+ return createHash("sha256").update(token).digest("hex");
55
+ }
56
+
57
+ /** A non-hex prefix keeps quoted-printable mail transports from consuming the URL separator. */
58
+ export const CHECKOUT_RECOVERY_TOKEN_PREFIX = "rcv_";
59
+
60
+ /** A 256-bit URL-safe random token for the deep-link, with the QP-safe prefix. */
61
+ export function generateCheckoutRecoveryToken(): string {
62
+ return CHECKOUT_RECOVERY_TOKEN_PREFIX + randomBytes(32).toString("base64url");
63
+ }
@@ -0,0 +1,29 @@
1
+ import type { CheckoutContinuationAction } from "./checkoutPaymentContinuationCredential.js";
2
+ import { isCheckoutContinuationRail } from "./checkoutPaymentContinuationCredential.js";
3
+ import type { CheckoutCookieResponse, CheckoutPaymentContinuationMinter } from "./checkoutPaymentContinuationCredential.js";
4
+
5
+ /** A separate guard: refusal diagnostics must not widen existing action authority. */
6
+ export function mintCheckoutRefusalContinuation<Rail extends string>(input: {
7
+ mint?: CheckoutPaymentContinuationMinter<Rail>;
8
+ res: CheckoutCookieResponse;
9
+ journeyId: string;
10
+ clientId: string;
11
+ requestRail: string;
12
+ response: { status: string; clientAction?: CheckoutContinuationAction };
13
+ result: { orderId: string; paymentIntentId: string; paymentAttemptId: string | null;
14
+ executionRail: string; continuationActionOrigin: "fresh_execution" | null;
15
+ status: string; runtimePaymentStatus?: string; paymentAttemptStatus?: string | null };
16
+ }, executionRails: readonly [Rail, Rail]): void {
17
+ const { result, response } = input;
18
+ if (!input.mint || result.continuationActionOrigin !== "fresh_execution"
19
+ || result.runtimePaymentStatus !== "failed" || result.paymentAttemptStatus !== "failed" || response.status !== "failed"
20
+ || (response.clientAction && response.clientAction.kind !== "none")
21
+ || !result.orderId || !result.paymentIntentId || !result.paymentAttemptId
22
+ || result.executionRail !== input.requestRail
23
+ || !isCheckoutContinuationRail(result.executionRail, executionRails)) return;
24
+ try {
25
+ input.mint(input.res, { journeyId: input.journeyId, clientId: input.clientId,
26
+ orderId: result.orderId, paymentIntentId: result.paymentIntentId,
27
+ paymentAttemptId: result.paymentAttemptId, executionRail: result.executionRail });
28
+ } catch { /* Optional guidance must never turn a settled refusal into an error. */ }
29
+ }
@@ -0,0 +1,26 @@
1
+ import type { PaymentExecutionBaseInput, PaymentExecutionBaseResult } from "@openlup/core/payment";
2
+ export type CheckoutExecutionProvider = string;
3
+ export type CheckoutProviderFlow = string;
4
+ export interface CheckoutRuntimeRequest<MethodKind extends string = string, RecurringModel extends string = string> {
5
+ idempotencyKey: string; paymentProvider: CheckoutExecutionProvider; providerFlow: CheckoutProviderFlow;
6
+ paymentAttemptSequence?: number; paymentMethodRef?: string; paymentMethodAliasType?: MethodKind;
7
+ paymentMethodRecurringModel?: RecurringModel; providerPayer?: { email: string; name: string; ip?: string | null; userAgent?: string | null };
8
+ saveForFutureUse?: boolean; returnContext?: "public" | "account"; paymentExecution?: unknown; declaredBankId?: string;
9
+ metadata: Record<string, unknown>;
10
+ }
11
+ export interface CheckoutRuntimeExecutionInput<Transient, Flow extends string = string, MethodKind extends string = string, RecurringModel extends string = string> extends PaymentExecutionBaseInput {
12
+ orderRef: string; providerFlow?: Flow; clientId?: string; orderId?: string;
13
+ paymentMethodRef?: string; paymentMethodAliasType?: MethodKind; paymentMethodRecurringModel?: RecurringModel;
14
+ payer?: { email: string; name: string; ip?: string | null; userAgent?: string | null };
15
+ saveForFutureUse?: boolean; returnContext?: "public" | "account"; transientProviderInput?: Transient | null;
16
+ }
17
+ export interface CheckoutRuntimeExecutionResult extends PaymentExecutionBaseResult {
18
+ provider: CheckoutExecutionProvider; clientSecret?: string | null; redirectUrl?: string | null;
19
+ }
20
+ export interface CheckoutRuntimeExecutionPort<Execution, Transient, Flow extends string = string, MethodKind extends string = string, RecurringModel extends string = string> { execute(input: CheckoutRuntimeExecutionInput<Transient, Flow, MethodKind, RecurringModel>): Promise<Execution> }
21
+ export interface CheckoutRuntimeResultRequest { idempotencyKey: string; orderId: string; paymentIntentId: string; resultStatus: string }
22
+ export interface CheckoutRuntimePaymentPort {
23
+ createIntent(input: { idempotencyKey: string; targetKind: "one_time_order" | "subscription_cycle"; orderId: string; subscriptionId: string | null; subscriptionCycleId: string | null; amountMinor: number; currency: string; metadata: Record<string, unknown> }): Promise<{ paymentIntentId: string; paymentId: string; status: string; replayed: boolean }>;
24
+ applyResult(input: CheckoutRuntimeResultRequest): Promise<{ orderId: string; kind: string }>;
25
+ }
26
+ export interface CheckoutRuntimeResponse { runtime: { orderId: string } }
@@ -0,0 +1,188 @@
1
+ import type { z } from "zod";
2
+ import type { CreateQuoteRequest, PricingPolicySnapshot } from "../../pricing/index.js";
3
+ import type { CheckoutJourney, CommerceOrderDraftWritePort, CheckoutCommandRuntimeResult } from "../contracts/index.js";
4
+ import type { CommerceQuotePort } from "../ports.js";
5
+ import type { CheckoutCommandV1, CheckoutCommandPersistenceResult } from "../checkoutCommandSchemas.js";
6
+ import { buildOrderDeliveryContact } from "../checkoutHelpers.js";
7
+ import { CommerceRuntimeConflictError, CommerceRuntimePersistenceError } from "../runtimeErrors.js";
8
+ import { tryCompensate, type CheckoutCompensationPort } from "./commerceCheckoutCompensation.js";
9
+ import { CheckoutOrchestrationError } from "./commerceCheckoutOrchestrationError.js";
10
+ import type { PaidOrderOrchestrationDeps, CheckoutJourneyRuntimeRequest, CheckoutJourneyRuntimeResponse, CheckoutJourneyResultRequest, OrchestratedCheckoutResult } from "./commercePaidOrderOrchestration.js";
11
+ import type { CheckoutExecutionProvider } from "./checkoutRuntimeTypes.js";
12
+ import type { CheckoutPaymentExecution } from "./commerceCheckoutProviderPayment.js";
13
+ import type { CheckoutQuoteSnapshot } from "./checkoutQuoteTypes.js";
14
+ export interface CheckoutCommandQuoteRequest extends CreateQuoteRequest { customerEligibilityContext: { email: string } }
15
+ export interface CheckoutCommandExecutionRequest<Provider extends string = string, MethodKind extends string = string, RecurringModel extends string = string> {
16
+ command: CheckoutCommandV1; paymentProvider: Provider; paymentAttemptSequence?: number;
17
+ paymentMethodRef?: string; paymentMethodAliasType?: MethodKind; paymentMethodRecurringModel?: RecurringModel;
18
+ saveForFutureUse?: boolean; returnContext?: "public" | "account";
19
+ providerPayer?: { email: string; name: string; ip?: string | null; userAgent?: string | null }; metadata?: Record<string, unknown>;
20
+ }
21
+ export function checkoutCommandJourney(
22
+ command: CheckoutCommandV1,
23
+ metadata: Record<string, unknown> | undefined,
24
+ ): CheckoutJourney<CheckoutCommandQuoteRequest, PricingPolicySnapshot> {
25
+ return {
26
+ idempotencyKey: command.idempotencyKey,
27
+ contactEmail: command.customer.email,
28
+ createQuoteRequest: () => ({
29
+ mode: command.mode,
30
+ lines: command.lines.map((line) => ({
31
+ sku: line.sku,
32
+ quantity: line.quantity,
33
+ modeAtLine: command.mode,
34
+ })),
35
+ cadenceDays: command.cadenceDays ?? null,
36
+ promoCodes: [],
37
+ customerEligibilityContext: { email: command.customer.email },
38
+ }),
39
+ createRuntimeMetadata: () => ({
40
+ ...metadata,
41
+ checkoutCommandVersion: command.version,
42
+ cadenceDays: command.cadenceDays,
43
+ deliveryContact: buildOrderDeliveryContact({
44
+ recipientName: `${command.customer.firstName} ${command.customer.lastName}`,
45
+ contactEmail: command.customer.email,
46
+ contactPhone: command.customer.phone,
47
+ line1: command.shippingAddress.street,
48
+ city: command.shippingAddress.city,
49
+ postalCode: command.shippingAddress.postalCode,
50
+ country: command.shippingAddress.country,
51
+ }),
52
+ }),
53
+ };
54
+ }
55
+
56
+ export function createCheckoutCommandExecutor<Provisioned extends { clientId: string; addressId: string }, Snapshot extends CheckoutQuoteSnapshot, Draft extends { orderDraft: { orderId: string } }, Extension extends object, Runtime extends CheckoutJourneyRuntimeResponse<Provider>, Settlement, ExecutionPort extends object, PaymentExecution extends CheckoutPaymentExecution, Provider extends string, Flow extends string, MethodKind extends string = string, RecurringModel extends string = string>(bindings: {
57
+ commandSchema: z.ZodType<CheckoutCommandV1>;
58
+ commandProvisioned(persistence: CheckoutCommandPersistenceResult): Provisioned;
59
+ orchestrateCheckoutJourney(deps: PaidOrderOrchestrationDeps<Provisioned, CheckoutCommandQuoteRequest, Snapshot, Draft, Extension, Runtime, Settlement, PaymentExecution, Provider, Flow, MethodKind, RecurringModel>, journey: CheckoutJourney<CheckoutCommandQuoteRequest, PricingPolicySnapshot>): Promise<OrchestratedCheckoutResult<Snapshot, Provider>>;
60
+ }) {
61
+ type CheckoutCommandExecutionDeps = {
62
+ quotePort?: CommerceQuotePort<CheckoutCommandQuoteRequest, Snapshot, import("../../pricing/index.js").CreateQuoteOptions>;
63
+ persistencePort?: { persistCheckoutCommand(command: CheckoutCommandV1): Promise<CheckoutCommandPersistenceResult> };
64
+ orderDraftPort?: CommerceOrderDraftWritePort<{ idempotencyKey: string; quoteSnapshot: Snapshot }, Draft>;
65
+ resolveExecutionPort?: (provider: string) => ExecutionPort;
66
+ compensationPort?: CheckoutCompensationPort; now?: () => Date;
67
+ startRuntime(request: CheckoutJourneyRuntimeRequest<Snapshot, PaymentExecution, Provider, Flow, MethodKind, RecurringModel> & Extension, executionPort: ExecutionPort): Promise<Runtime>;
68
+ applyPaymentResult(request: CheckoutJourneyResultRequest): Promise<Settlement>;
69
+ };
70
+
71
+ const COMMAND_CONFLICT_REASONS = new Set([
72
+ "journey_consumed",
73
+ "promotion_code_price_changed",
74
+ "provider_attempt_in_flight",
75
+ ]);
76
+
77
+ async function executeCheckoutCommand(
78
+ request: CheckoutCommandExecutionRequest<Provider, MethodKind, RecurringModel>,
79
+ deps: CheckoutCommandExecutionDeps,
80
+ ): Promise<CheckoutCommandRuntimeResult<Snapshot, CheckoutCommandPersistenceResult, Draft, Runtime, Settlement>> {
81
+ const command = bindings.commandSchema.safeParse(request.command);
82
+ if (!command.success) throw new CommerceRuntimeConflictError("Checkout command is invalid");
83
+ const { quotePort, persistencePort, orderDraftPort, resolveExecutionPort } = deps;
84
+ if (!quotePort || !persistencePort || !orderDraftPort || !resolveExecutionPort) {
85
+ throw new CommerceRuntimePersistenceError(
86
+ "Checkout command runtime composition is incomplete",
87
+ { missing: [!quotePort && "quote", !persistencePort && "persistence", !orderDraftPort && "order_draft", !resolveExecutionPort && "payment_provider"].filter(Boolean) },
88
+ );
89
+ }
90
+
91
+ const adapter = resolveExecutionPort(request.paymentProvider) as unknown;
92
+ if (typeof adapter !== "object" || adapter === null || !("execute" in adapter) || typeof adapter.execute !== "function") {
93
+ throw new CommerceRuntimePersistenceError("Checkout command payment provider adapter is unavailable");
94
+ }
95
+ const executionPort = adapter as ExecutionPort;
96
+ const journey = checkoutCommandJourney(command.data, request.metadata);
97
+ // Quote and its currency guard stay ahead of every write: a mismatched
98
+ // currency must not leave a persisted client, address, or draft behind.
99
+ const quoteSnapshot = await quotePort.createQuote(journey.createQuoteRequest());
100
+ if (quoteSnapshot.quote.currency !== command.data.currency) {
101
+ throw new CommerceRuntimeConflictError("Checkout command currency does not match quote", {
102
+ commandCurrency: command.data.currency,
103
+ quoteCurrency: quoteSnapshot.quote.currency,
104
+ });
105
+ }
106
+
107
+ const persistence = await persistencePort.persistCheckoutCommand(command.data);
108
+ if (persistence.subjectId !== null) {
109
+ throw new CommerceRuntimePersistenceError("Checkout command persistence returned an unexpected subject");
110
+ }
111
+
112
+ // From here the neutral command runs the SAME application service as the
113
+ // legacy configurator checkout: one stage sequence, one start-runtime failure
114
+ // mapping, one provider invariant set, one settle step, one compensation.
115
+ const captured: {
116
+ orderDraft: Draft | null;
117
+ runtime: Runtime | null;
118
+ settlement: Settlement | null;
119
+ } = { orderDraft: null, runtime: null, settlement: null };
120
+ try {
121
+ const orchestrationDeps: PaidOrderOrchestrationDeps<Provisioned, CheckoutCommandQuoteRequest, Snapshot, Draft, Extension, Runtime, Settlement, PaymentExecution, Provider, Flow, MethodKind, RecurringModel> & { journey: CheckoutJourney<CheckoutCommandQuoteRequest, PricingPolicySnapshot> } = {
122
+ journey,
123
+ provisioned: bindings.commandProvisioned(persistence),
124
+ checkoutKind: command.data.mode === "subscription" ? "subscription_initial" : "one_time",
125
+ quotePort,
126
+ quoteSnapshot,
127
+ orderDraftPort: {
128
+ createOrderDraft: async (draftRequest, options) => {
129
+ captured.orderDraft = await orderDraftPort.createOrderDraft(draftRequest, options);
130
+ return captured.orderDraft;
131
+ },
132
+ },
133
+ runtimePort: {
134
+ startRuntime: async (startRequest) => {
135
+ captured.runtime = await deps.startRuntime(startRequest, executionPort);
136
+ return captured.runtime;
137
+ },
138
+ applyPaymentResult: async (settleRequest) => {
139
+ captured.settlement = await deps.applyPaymentResult(settleRequest);
140
+ return captured.settlement;
141
+ },
142
+ },
143
+ paymentProvider: request.paymentProvider,
144
+ paymentAttemptSequence: request.paymentAttemptSequence,
145
+ paymentMethodRef: request.paymentMethodRef,
146
+ paymentMethodAliasType: request.paymentMethodAliasType,
147
+ paymentMethodRecurringModel: request.paymentMethodRecurringModel,
148
+ saveForFutureUse: request.saveForFutureUse,
149
+ returnContext: request.returnContext,
150
+ providerPayer: request.providerPayer,
151
+ now: deps.now ?? (() => new Date()),
152
+ };
153
+ await bindings.orchestrateCheckoutJourney(orchestrationDeps, journey);
154
+ } catch (error) {
155
+ throw await mapOrchestrationFailure(error, journey.idempotencyKey, deps.compensationPort);
156
+ }
157
+ if (!captured.orderDraft || !captured.runtime) {
158
+ throw new CommerceRuntimePersistenceError("Checkout command runtime produced no result");
159
+ }
160
+
161
+ return {
162
+ quoteSnapshot,
163
+ persistence,
164
+ orderDraft: captured.orderDraft,
165
+ runtime: captured.runtime,
166
+ settlement: captured.settlement,
167
+ };
168
+ }
169
+
170
+ async function mapOrchestrationFailure(
171
+ error: unknown,
172
+ idempotencyKey: string,
173
+ compensationPort: CheckoutCompensationPort | undefined,
174
+ ): Promise<unknown> {
175
+ if (!(error instanceof CheckoutOrchestrationError)) return error;
176
+ // `orderIdForCompensation` is a compensation capability, not an order id: the
177
+ // saga deliberately withholds it when a provider attempt may be in flight.
178
+ if (error.orderIdForCompensation && compensationPort) {
179
+ await tryCompensate(compensationPort, idempotencyKey, error.orderIdForCompensation);
180
+ }
181
+ const details = { stage: error.message.split(":")[0], reason: error.reason };
182
+ return error.reason && COMMAND_CONFLICT_REASONS.has(error.reason)
183
+ ? new CommerceRuntimeConflictError("Checkout command could not be completed", details)
184
+ : new CommerceRuntimePersistenceError("Checkout command runtime failed", details);
185
+ }
186
+
187
+ return { executeCheckoutCommand };
188
+ }