@aglyn/plugins-commerce 1.0.0-beta.285 → 1.0.0-beta.287

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 (420) hide show
  1. package/README.md +1 -1
  2. package/package.json +13 -13
  3. package/src/lib/components/cart.js +25 -12
  4. package/src/lib/components/cart.js.map +1 -1
  5. package/src/lib/components/commerce-console-page.js +70 -13
  6. package/src/lib/components/commerce-console-page.js.map +1 -1
  7. package/src/lib/components/console/order-detail-dialog.component.js +2 -1
  8. package/src/lib/components/console/order-detail-dialog.component.js.map +1 -1
  9. package/src/lib/components/console/payment-methods-card.component.js +1 -1
  10. package/src/lib/components/console/payment-methods-card.component.js.map +1 -1
  11. package/src/lib/components/console/pos/pos-cart-panel.component.d.ts +5 -0
  12. package/src/lib/components/console/pos/pos-cart-panel.component.js +18 -12
  13. package/src/lib/components/console/pos/pos-cart-panel.component.js.map +1 -1
  14. package/src/lib/components/console/pos/pos-hardware-api.d.ts +76 -5
  15. package/src/lib/components/console/pos/pos-hardware-api.js +53 -11
  16. package/src/lib/components/console/pos/pos-hardware-api.js.map +1 -1
  17. package/src/lib/components/console/pos/pos-hardware-buyer.component.d.ts +18 -0
  18. package/src/lib/components/console/pos/pos-hardware-buyer.component.js +629 -0
  19. package/src/lib/components/console/pos/pos-hardware-buyer.component.js.map +1 -0
  20. package/src/lib/components/console/pos/pos-hardware-sale-api.d.ts +162 -0
  21. package/src/lib/components/console/pos/pos-hardware-sale-api.js +122 -0
  22. package/src/lib/components/console/pos/pos-hardware-sale-api.js.map +1 -0
  23. package/src/lib/components/console/pos/pos-hardware-sale-terms.component.d.ts +39 -0
  24. package/src/lib/components/console/pos/pos-hardware-sale-terms.component.js +251 -0
  25. package/src/lib/components/console/pos/pos-hardware-sale-terms.component.js.map +1 -0
  26. package/src/lib/components/console/pos/use-pos-display.js +50 -0
  27. package/src/lib/components/console/pos/use-pos-display.js.map +1 -1
  28. package/src/lib/components/console/pos-cellular-control.component.d.ts +41 -0
  29. package/src/lib/components/console/pos-cellular-control.component.js +211 -0
  30. package/src/lib/components/console/pos-cellular-control.component.js.map +1 -0
  31. package/src/lib/components/console/pos-devices-card.component.d.ts +9 -1
  32. package/src/lib/components/console/pos-devices-card.component.js +47 -15
  33. package/src/lib/components/console/pos-devices-card.component.js.map +1 -1
  34. package/src/lib/components/console/pos-display/pos-display-api.d.ts +6 -0
  35. package/src/lib/components/console/pos-display/pos-display-api.js +8 -1
  36. package/src/lib/components/console/pos-display/pos-display-api.js.map +1 -1
  37. package/src/lib/components/console/pos-display-page.component.d.ts +13 -0
  38. package/src/lib/components/console/pos-display-page.component.js +44 -2
  39. package/src/lib/components/console/pos-display-page.component.js.map +1 -1
  40. package/src/lib/components/console/pos-hardware-card.component.d.ts +12 -4
  41. package/src/lib/components/console/pos-hardware-card.component.js +157 -36
  42. package/src/lib/components/console/pos-hardware-card.component.js.map +1 -1
  43. package/src/lib/components/console/pos-hardware-orders-staff-page.component.js +360 -80
  44. package/src/lib/components/console/pos-hardware-orders-staff-page.component.js.map +1 -1
  45. package/src/lib/components/console/pos-hardware-terms-page.component.d.ts +34 -0
  46. package/src/lib/components/console/pos-hardware-terms-page.component.js +257 -0
  47. package/src/lib/components/console/pos-hardware-terms-page.component.js.map +1 -0
  48. package/src/lib/components/console/pos-hardware-terms-sign-page.component.d.ts +27 -0
  49. package/src/lib/components/console/pos-hardware-terms-sign-page.component.js +104 -0
  50. package/src/lib/components/console/pos-hardware-terms-sign-page.component.js.map +1 -0
  51. package/src/lib/components/console/pos-hardware-waiting-card.component.d.ts +24 -0
  52. package/src/lib/components/console/pos-hardware-waiting-card.component.js +205 -0
  53. package/src/lib/components/console/pos-hardware-waiting-card.component.js.map +1 -0
  54. package/src/lib/components/console/pos-ops/pos-check-in-dialog.component.js +297 -201
  55. package/src/lib/components/console/pos-ops/pos-check-in-dialog.component.js.map +1 -1
  56. package/src/lib/components/console/pos-ops/pos-check-ins-card.component.d.ts +3 -0
  57. package/src/lib/components/console/pos-ops/pos-check-ins-card.component.js +260 -92
  58. package/src/lib/components/console/pos-ops/pos-check-ins-card.component.js.map +1 -1
  59. package/src/lib/components/console/pos-ops/pos-operations-bar.component.d.ts +9 -0
  60. package/src/lib/components/console/pos-ops/pos-operations-bar.component.js +15 -6
  61. package/src/lib/components/console/pos-ops/pos-operations-bar.component.js.map +1 -1
  62. package/src/lib/components/console/pos-ops/pos-rain-check-dialog.component.d.ts +25 -0
  63. package/src/lib/components/console/pos-ops/pos-rain-check-dialog.component.js +136 -0
  64. package/src/lib/components/console/pos-ops/pos-rain-check-dialog.component.js.map +1 -0
  65. package/src/lib/components/console/pos-ops/pos-shift-panel.component.d.ts +6 -0
  66. package/src/lib/components/console/pos-ops/pos-shift-panel.component.js +48 -31
  67. package/src/lib/components/console/pos-ops/pos-shift-panel.component.js.map +1 -1
  68. package/src/lib/components/console/pos-page.component.d.ts +1 -1
  69. package/src/lib/components/console/pos-page.component.js +63 -12
  70. package/src/lib/components/console/pos-page.component.js.map +1 -1
  71. package/src/lib/components/console/pos-reader-splash-setting.component.js +1 -1
  72. package/src/lib/components/console/pos-reader-splash-setting.component.js.map +1 -1
  73. package/src/lib/components/console/product-check-in-fields.component.d.ts +4 -2
  74. package/src/lib/components/console/product-check-in-fields.component.js +60 -14
  75. package/src/lib/components/console/product-check-in-fields.component.js.map +1 -1
  76. package/src/lib/components/console/product-editor-dialog.component.js +44 -1
  77. package/src/lib/components/console/product-editor-dialog.component.js.map +1 -1
  78. package/src/lib/components/console/product-hardware-sku-field.component.d.ts +19 -0
  79. package/src/lib/components/console/product-hardware-sku-field.component.js +92 -0
  80. package/src/lib/components/console/product-hardware-sku-field.component.js.map +1 -0
  81. package/src/lib/components/console/product-kiosk-offer-field.component.d.ts +22 -0
  82. package/src/lib/components/console/product-kiosk-offer-field.component.js +94 -0
  83. package/src/lib/components/console/product-kiosk-offer-field.component.js.map +1 -0
  84. package/src/lib/components/console/product-register-fields.component.d.ts +4 -0
  85. package/src/lib/components/console/product-register-fields.component.js +31 -2
  86. package/src/lib/components/console/product-register-fields.component.js.map +1 -1
  87. package/src/lib/components/console/products-hub-card.component.js +11 -2
  88. package/src/lib/components/console/products-hub-card.component.js.map +1 -1
  89. package/src/lib/components/console/register-hardware-card.component.d.ts +11 -0
  90. package/src/lib/components/console/register-hardware-card.component.js +56 -27
  91. package/src/lib/components/console/register-hardware-card.component.js.map +1 -1
  92. package/src/lib/components/console/reservation-guests-dialog.component.d.ts +28 -0
  93. package/src/lib/components/console/reservation-guests-dialog.component.js +189 -0
  94. package/src/lib/components/console/reservation-guests-dialog.component.js.map +1 -0
  95. package/src/lib/components/console/reservations-card.component.d.ts +9 -0
  96. package/src/lib/components/console/reservations-card.component.js +158 -23
  97. package/src/lib/components/console/reservations-card.component.js.map +1 -1
  98. package/src/lib/components/console/shippingeasy-card.component.js +1 -1
  99. package/src/lib/components/console/shippingeasy-card.component.js.map +1 -1
  100. package/src/lib/components/console/shipstation-card.component.d.ts +1 -1
  101. package/src/lib/components/console/shipstation-card.component.js +3 -3
  102. package/src/lib/components/console/shipstation-card.component.js.map +1 -1
  103. package/src/lib/components/product-detail.d.ts +4 -0
  104. package/src/lib/components/product-detail.js +40 -5
  105. package/src/lib/components/product-detail.js.map +1 -1
  106. package/src/lib/components/product-reviews.js +28 -11
  107. package/src/lib/components/product-reviews.js.map +1 -1
  108. package/src/lib/components/reservation-widget.js +28 -5
  109. package/src/lib/components/reservation-widget.js.map +1 -1
  110. package/src/lib/components/use-day-picker.d.ts +25 -0
  111. package/src/lib/components/use-day-picker.js +57 -0
  112. package/src/lib/components/use-day-picker.js.map +1 -0
  113. package/src/lib/constants/operator-alerts.d.ts +55 -0
  114. package/src/lib/constants/operator-alerts.js +156 -1
  115. package/src/lib/constants/operator-alerts.js.map +1 -1
  116. package/src/lib/declarations.console-server.js +54 -1
  117. package/src/lib/declarations.console-server.js.map +1 -1
  118. package/src/lib/declarations.d.ts +4 -2
  119. package/src/lib/declarations.js +11 -4
  120. package/src/lib/declarations.js.map +1 -1
  121. package/src/lib/declarations.server.js +9 -0
  122. package/src/lib/declarations.server.js.map +1 -1
  123. package/src/lib/model/commerce-cart.d.ts +9 -1
  124. package/src/lib/model/commerce-cart.js +4 -3
  125. package/src/lib/model/commerce-cart.js.map +1 -1
  126. package/src/lib/model/commerce-check-in-product.d.ts +26 -0
  127. package/src/lib/model/commerce-check-in-product.js +64 -2
  128. package/src/lib/model/commerce-check-in-product.js.map +1 -1
  129. package/src/lib/model/commerce-check-in-record.d.ts +127 -0
  130. package/src/lib/model/commerce-check-in-record.js +36 -0
  131. package/src/lib/model/commerce-check-in-record.js.map +1 -0
  132. package/src/lib/model/commerce-check-in.d.ts +91 -87
  133. package/src/lib/model/commerce-check-in.js +186 -62
  134. package/src/lib/model/commerce-check-in.js.map +1 -1
  135. package/src/lib/model/commerce-kiosk-offer.d.ts +31 -0
  136. package/src/lib/model/commerce-kiosk-offer.js +35 -0
  137. package/src/lib/model/commerce-kiosk-offer.js.map +1 -0
  138. package/src/lib/model/commerce-orders.d.ts +76 -0
  139. package/src/lib/model/commerce-orders.js +6 -0
  140. package/src/lib/model/commerce-orders.js.map +1 -1
  141. package/src/lib/model/commerce-pos-day-report.d.ts +54 -1
  142. package/src/lib/model/commerce-pos-day-report.js +39 -2
  143. package/src/lib/model/commerce-pos-day-report.js.map +1 -1
  144. package/src/lib/model/commerce-pos-offline.d.ts +1 -1
  145. package/src/lib/model/commerce-pos-offline.js +6 -1
  146. package/src/lib/model/commerce-pos-offline.js.map +1 -1
  147. package/src/lib/model/commerce-pos-ops.js +3 -2
  148. package/src/lib/model/commerce-pos-ops.js.map +1 -1
  149. package/src/lib/model/commerce-pos.d.ts +36 -3
  150. package/src/lib/model/commerce-pos.js +14 -6
  151. package/src/lib/model/commerce-pos.js.map +1 -1
  152. package/src/lib/model/commerce-receipt.js +3 -2
  153. package/src/lib/model/commerce-receipt.js.map +1 -1
  154. package/src/lib/model/commerce-reservations.d.ts +69 -4
  155. package/src/lib/model/commerce-reservations.js +57 -5
  156. package/src/lib/model/commerce-reservations.js.map +1 -1
  157. package/src/lib/model/commerce.d.ts +66 -0
  158. package/src/lib/model/commerce.js +15 -0
  159. package/src/lib/model/commerce.js.map +1 -1
  160. package/src/lib/model/order-list-fields.d.ts +11 -0
  161. package/src/lib/model/order-list-fields.js +17 -1
  162. package/src/lib/model/order-list-fields.js.map +1 -1
  163. package/src/lib/model/own-store-tax-summary.d.ts +152 -0
  164. package/src/lib/model/own-store-tax-summary.js +288 -0
  165. package/src/lib/model/own-store-tax-summary.js.map +1 -0
  166. package/src/lib/model/plugin-permissions.d.ts +67 -0
  167. package/src/lib/model/plugin-permissions.js +224 -7
  168. package/src/lib/model/plugin-permissions.js.map +1 -1
  169. package/src/lib/model/pos-cellular.d.ts +223 -0
  170. package/src/lib/model/pos-cellular.js +293 -0
  171. package/src/lib/model/pos-cellular.js.map +1 -0
  172. package/src/lib/model/pos-hardware-in-person.d.ts +98 -0
  173. package/src/lib/model/pos-hardware-in-person.js +224 -0
  174. package/src/lib/model/pos-hardware-in-person.js.map +1 -0
  175. package/src/lib/model/pos-hardware-tax-summary.d.ts +166 -0
  176. package/src/lib/model/pos-hardware-tax-summary.js +225 -0
  177. package/src/lib/model/pos-hardware-tax-summary.js.map +1 -0
  178. package/src/lib/model/pos-hardware-terms.d.ts +74 -0
  179. package/src/lib/model/pos-hardware-terms.js +115 -0
  180. package/src/lib/model/pos-hardware-terms.js.map +1 -0
  181. package/src/lib/model/pos-hardware.d.ts +349 -7
  182. package/src/lib/model/pos-hardware.js +291 -20
  183. package/src/lib/model/pos-hardware.js.map +1 -1
  184. package/src/lib/model/product-write.d.ts +10 -0
  185. package/src/lib/model/product-write.js +4 -2
  186. package/src/lib/model/product-write.js.map +1 -1
  187. package/src/lib/plugin.js +16 -0
  188. package/src/lib/plugin.js.map +1 -1
  189. package/src/lib/server/billing-webhook.js +25 -1
  190. package/src/lib/server/billing-webhook.js.map +1 -1
  191. package/src/lib/server/cancel-order.js +7 -5
  192. package/src/lib/server/cancel-order.js.map +1 -1
  193. package/src/lib/server/cart-checkout.js +20 -8
  194. package/src/lib/server/cart-checkout.js.map +1 -1
  195. package/src/lib/server/cart.js +29 -0
  196. package/src/lib/server/cart.js.map +1 -1
  197. package/src/lib/server/checkout.js +42 -13
  198. package/src/lib/server/checkout.js.map +1 -1
  199. package/src/lib/server/collection-membership.d.ts +4 -0
  200. package/src/lib/server/collection-membership.js +5 -10
  201. package/src/lib/server/collection-membership.js.map +1 -1
  202. package/src/lib/server/commerce-site-keys.d.ts +29 -0
  203. package/src/lib/server/commerce-site-keys.js +40 -0
  204. package/src/lib/server/commerce-site-keys.js.map +1 -0
  205. package/src/lib/server/draft-order.js +8 -5
  206. package/src/lib/server/draft-order.js.map +1 -1
  207. package/src/lib/server/fulfill-order.js +7 -5
  208. package/src/lib/server/fulfill-order.js.map +1 -1
  209. package/src/lib/server/gift-cards.js +8 -5
  210. package/src/lib/server/gift-cards.js.map +1 -1
  211. package/src/lib/server/local-fulfillment-status.js +9 -6
  212. package/src/lib/server/local-fulfillment-status.js.map +1 -1
  213. package/src/lib/server/member-post.js +6 -5
  214. package/src/lib/server/member-post.js.map +1 -1
  215. package/src/lib/server/membership-admin-password.d.ts +4 -2
  216. package/src/lib/server/membership-admin-password.js +10 -8
  217. package/src/lib/server/membership-admin-password.js.map +1 -1
  218. package/src/lib/server/membership-admin-remove.d.ts +7 -5
  219. package/src/lib/server/membership-admin-remove.js +9 -9
  220. package/src/lib/server/membership-admin-remove.js.map +1 -1
  221. package/src/lib/server/order-notifications.js +5 -2
  222. package/src/lib/server/order-notifications.js.map +1 -1
  223. package/src/lib/server/order-print.js +7 -5
  224. package/src/lib/server/order-print.js.map +1 -1
  225. package/src/lib/server/order-receipt-send.js +8 -5
  226. package/src/lib/server/order-receipt-send.js.map +1 -1
  227. package/src/lib/server/orders-shipping-prepare.js +9 -6
  228. package/src/lib/server/orders-shipping-prepare.js.map +1 -1
  229. package/src/lib/server/own-store-tax-return-source.d.ts +47 -0
  230. package/src/lib/server/own-store-tax-return-source.js +312 -0
  231. package/src/lib/server/own-store-tax-return-source.js.map +1 -0
  232. package/src/lib/server/payment-methods.js +13 -9
  233. package/src/lib/server/payment-methods.js.map +1 -1
  234. package/src/lib/server/pos-auth.d.ts +37 -6
  235. package/src/lib/server/pos-auth.js +40 -15
  236. package/src/lib/server/pos-auth.js.map +1 -1
  237. package/src/lib/server/pos-cellular-billing.d.ts +81 -0
  238. package/src/lib/server/pos-cellular-billing.js +711 -0
  239. package/src/lib/server/pos-cellular-billing.js.map +1 -0
  240. package/src/lib/server/pos-cellular-notify.d.ts +47 -0
  241. package/src/lib/server/pos-cellular-notify.js +150 -0
  242. package/src/lib/server/pos-cellular-notify.js.map +1 -0
  243. package/src/lib/server/pos-cellular.d.ts +88 -0
  244. package/src/lib/server/pos-cellular.js +339 -0
  245. package/src/lib/server/pos-cellular.js.map +1 -0
  246. package/src/lib/server/pos-check-in.d.ts +5 -1
  247. package/src/lib/server/pos-check-in.js +296 -28
  248. package/src/lib/server/pos-check-in.js.map +1 -1
  249. package/src/lib/server/pos-day-report.js +29 -3
  250. package/src/lib/server/pos-day-report.js.map +1 -1
  251. package/src/lib/server/pos-display.d.ts +16 -0
  252. package/src/lib/server/pos-display.js +129 -2
  253. package/src/lib/server/pos-display.js.map +1 -1
  254. package/src/lib/server/pos-hardware-admin.d.ts +10 -1
  255. package/src/lib/server/pos-hardware-admin.js +250 -84
  256. package/src/lib/server/pos-hardware-admin.js.map +1 -1
  257. package/src/lib/server/pos-hardware-attach.d.ts +105 -0
  258. package/src/lib/server/pos-hardware-attach.js +443 -0
  259. package/src/lib/server/pos-hardware-attach.js.map +1 -0
  260. package/src/lib/server/pos-hardware-buyer-lookup.d.ts +58 -0
  261. package/src/lib/server/pos-hardware-buyer-lookup.js +180 -0
  262. package/src/lib/server/pos-hardware-buyer-lookup.js.map +1 -0
  263. package/src/lib/server/pos-hardware-buyer-record.d.ts +29 -0
  264. package/src/lib/server/pos-hardware-buyer-record.js +86 -0
  265. package/src/lib/server/pos-hardware-buyer-record.js.map +1 -0
  266. package/src/lib/server/pos-hardware-cancel.d.ts +58 -0
  267. package/src/lib/server/pos-hardware-cancel.js +147 -0
  268. package/src/lib/server/pos-hardware-cancel.js.map +1 -0
  269. package/src/lib/server/pos-hardware-closure-notices.d.ts +27 -0
  270. package/src/lib/server/pos-hardware-closure-notices.js +85 -0
  271. package/src/lib/server/pos-hardware-closure-notices.js.map +1 -0
  272. package/src/lib/server/pos-hardware-closure.d.ts +60 -0
  273. package/src/lib/server/pos-hardware-closure.js +153 -0
  274. package/src/lib/server/pos-hardware-closure.js.map +1 -0
  275. package/src/lib/server/pos-hardware-in-person.d.ts +61 -0
  276. package/src/lib/server/pos-hardware-in-person.js +236 -0
  277. package/src/lib/server/pos-hardware-in-person.js.map +1 -0
  278. package/src/lib/server/pos-hardware-notify.d.ts +40 -2
  279. package/src/lib/server/pos-hardware-notify.js +195 -14
  280. package/src/lib/server/pos-hardware-notify.js.map +1 -1
  281. package/src/lib/server/pos-hardware-readers.d.ts +115 -0
  282. package/src/lib/server/pos-hardware-readers.js +430 -0
  283. package/src/lib/server/pos-hardware-readers.js.map +1 -0
  284. package/src/lib/server/pos-hardware-returns.d.ts +116 -0
  285. package/src/lib/server/pos-hardware-returns.js +502 -0
  286. package/src/lib/server/pos-hardware-returns.js.map +1 -0
  287. package/src/lib/server/pos-hardware-sale-fields.d.ts +28 -0
  288. package/src/lib/server/pos-hardware-sale-fields.js +44 -0
  289. package/src/lib/server/pos-hardware-sale-fields.js.map +1 -0
  290. package/src/lib/server/pos-hardware-sale.d.ts +54 -0
  291. package/src/lib/server/pos-hardware-sale.js +369 -0
  292. package/src/lib/server/pos-hardware-sale.js.map +1 -0
  293. package/src/lib/server/pos-hardware-tax-return-source.d.ts +99 -0
  294. package/src/lib/server/pos-hardware-tax-return-source.js +462 -0
  295. package/src/lib/server/pos-hardware-tax-return-source.js.map +1 -0
  296. package/src/lib/server/pos-hardware-terms.d.ts +64 -0
  297. package/src/lib/server/pos-hardware-terms.js +154 -0
  298. package/src/lib/server/pos-hardware-terms.js.map +1 -0
  299. package/src/lib/server/pos-hardware-user-eraser.d.ts +3 -0
  300. package/src/lib/server/pos-hardware-user-eraser.js +31 -7
  301. package/src/lib/server/pos-hardware-user-eraser.js.map +1 -1
  302. package/src/lib/server/pos-hardware-webhook.d.ts +5 -0
  303. package/src/lib/server/pos-hardware-webhook.js +51 -6
  304. package/src/lib/server/pos-hardware-webhook.js.map +1 -1
  305. package/src/lib/server/pos-hardware.d.ts +74 -1
  306. package/src/lib/server/pos-hardware.js +175 -10
  307. package/src/lib/server/pos-hardware.js.map +1 -1
  308. package/src/lib/server/pos-kiosk.d.ts +2 -0
  309. package/src/lib/server/pos-kiosk.js +17 -12
  310. package/src/lib/server/pos-kiosk.js.map +1 -1
  311. package/src/lib/server/pos-offline-card-order.d.ts +64 -0
  312. package/src/lib/server/pos-offline-card-order.js +102 -0
  313. package/src/lib/server/pos-offline-card-order.js.map +1 -0
  314. package/src/lib/server/pos-offline-card-reconcile.d.ts +67 -1
  315. package/src/lib/server/pos-offline-card-reconcile.js +215 -18
  316. package/src/lib/server/pos-offline-card-reconcile.js.map +1 -1
  317. package/src/lib/server/pos-offline-sync.d.ts +39 -0
  318. package/src/lib/server/pos-offline-sync.js +190 -55
  319. package/src/lib/server/pos-offline-sync.js.map +1 -1
  320. package/src/lib/server/pos-ops-gate.d.ts +15 -4
  321. package/src/lib/server/pos-ops-gate.js +42 -9
  322. package/src/lib/server/pos-ops-gate.js.map +1 -1
  323. package/src/lib/server/pos-ops-routes.js +24 -0
  324. package/src/lib/server/pos-ops-routes.js.map +1 -1
  325. package/src/lib/server/pos-order-refund-ids.d.ts +28 -0
  326. package/src/lib/server/pos-order-refund-ids.js +31 -0
  327. package/src/lib/server/pos-order-refund-ids.js.map +1 -0
  328. package/src/lib/server/pos-order.js +52 -49
  329. package/src/lib/server/pos-order.js.map +1 -1
  330. package/src/lib/server/pos-payment.js +1 -1
  331. package/src/lib/server/pos-payment.js.map +1 -1
  332. package/src/lib/server/pos-reader-splash-admin.js +30 -32
  333. package/src/lib/server/pos-reader-splash-admin.js.map +1 -1
  334. package/src/lib/server/pos-reader-splash-images-route.d.ts +17 -0
  335. package/src/lib/server/pos-reader-splash-images-route.js +113 -0
  336. package/src/lib/server/pos-reader-splash-images-route.js.map +1 -0
  337. package/src/lib/server/pos-reader-splash-images.d.ts +51 -0
  338. package/src/lib/server/pos-reader-splash-images.js +123 -0
  339. package/src/lib/server/pos-reader-splash-images.js.map +1 -0
  340. package/src/lib/server/pos-reader-splash.d.ts +68 -1
  341. package/src/lib/server/pos-reader-splash.js +182 -11
  342. package/src/lib/server/pos-reader-splash.js.map +1 -1
  343. package/src/lib/server/pos-readers.d.ts +29 -0
  344. package/src/lib/server/pos-readers.js +134 -35
  345. package/src/lib/server/pos-readers.js.map +1 -1
  346. package/src/lib/server/pos-return.d.ts +10 -0
  347. package/src/lib/server/pos-return.js +26 -1
  348. package/src/lib/server/pos-return.js.map +1 -1
  349. package/src/lib/server/pos-sale.js +6 -1
  350. package/src/lib/server/pos-sale.js.map +1 -1
  351. package/src/lib/server/pos-shift.js +11 -0
  352. package/src/lib/server/pos-shift.js.map +1 -1
  353. package/src/lib/server/pos-staff-pin.js +25 -20
  354. package/src/lib/server/pos-staff-pin.js.map +1 -1
  355. package/src/lib/server/pos-terminal.d.ts +14 -4
  356. package/src/lib/server/pos-terminal.js +34 -38
  357. package/src/lib/server/pos-terminal.js.map +1 -1
  358. package/src/lib/server/printers.d.ts +7 -3
  359. package/src/lib/server/printers.js +18 -12
  360. package/src/lib/server/printers.js.map +1 -1
  361. package/src/lib/server/product-drafts.d.ts +11 -1
  362. package/src/lib/server/product-drafts.js +12 -8
  363. package/src/lib/server/product-drafts.js.map +1 -1
  364. package/src/lib/server/product.d.ts +15 -1
  365. package/src/lib/server/product.js +16 -3
  366. package/src/lib/server/product.js.map +1 -1
  367. package/src/lib/server/products-write.d.ts +26 -2
  368. package/src/lib/server/products-write.js +19 -7
  369. package/src/lib/server/products-write.js.map +1 -1
  370. package/src/lib/server/refund.js +34 -11
  371. package/src/lib/server/refund.js.map +1 -1
  372. package/src/lib/server/reservation-availability-query.d.ts +8 -0
  373. package/src/lib/server/reservation-availability-query.js +11 -1
  374. package/src/lib/server/reservation-availability-query.js.map +1 -1
  375. package/src/lib/server/reservation-availability.d.ts +1 -1
  376. package/src/lib/server/reservation-availability.js +7 -2
  377. package/src/lib/server/reservation-availability.js.map +1 -1
  378. package/src/lib/server/reservation-guests.d.ts +32 -0
  379. package/src/lib/server/reservation-guests.js +285 -0
  380. package/src/lib/server/reservation-guests.js.map +1 -0
  381. package/src/lib/server/reservation-walk-in.d.ts +11 -1
  382. package/src/lib/server/reservation-walk-in.js +56 -12
  383. package/src/lib/server/reservation-walk-in.js.map +1 -1
  384. package/src/lib/server/reserve.js +18 -5
  385. package/src/lib/server/reserve.js.map +1 -1
  386. package/src/lib/server/returns.js +9 -6
  387. package/src/lib/server/returns.js.map +1 -1
  388. package/src/lib/server/reviews.d.ts +22 -2
  389. package/src/lib/server/reviews.js +88 -20
  390. package/src/lib/server/reviews.js.map +1 -1
  391. package/src/lib/server/shipping-connectors.js +10 -11
  392. package/src/lib/server/shipping-connectors.js.map +1 -1
  393. package/src/lib/server/site-page-resolver.js +20 -3
  394. package/src/lib/server/site-page-resolver.js.map +1 -1
  395. package/src/lib/server/store-day.d.ts +33 -0
  396. package/src/lib/server/store-day.js +46 -0
  397. package/src/lib/server/store-day.js.map +1 -0
  398. package/src/lib/server/store-setup-ai-writer.d.ts +2 -1
  399. package/src/lib/server/store-setup-ai-writer.js +5 -6
  400. package/src/lib/server/store-setup-ai-writer.js.map +1 -1
  401. package/src/lib/server/storefront-tax.d.ts +13 -0
  402. package/src/lib/server/storefront-tax.js +8 -1
  403. package/src/lib/server/storefront-tax.js.map +1 -1
  404. package/src/lib/server/tax-return-source.d.ts +32 -3
  405. package/src/lib/server/tax-return-source.js +99 -20
  406. package/src/lib/server/tax-return-source.js.map +1 -1
  407. package/src/lib/server.js +100 -2
  408. package/src/lib/server.js.map +1 -1
  409. package/src/lib/testing/fake-firestore.js +58 -16
  410. package/src/lib/testing/fake-firestore.js.map +1 -1
  411. package/src/lib/testing/pos-ops-memory-firestore.js +18 -4
  412. package/src/lib/testing/pos-ops-memory-firestore.js.map +1 -1
  413. package/src/lib/testing/site-register-permissions.d.ts +29 -0
  414. package/src/lib/testing/site-register-permissions.js +38 -0
  415. package/src/lib/testing/site-register-permissions.js.map +1 -0
  416. package/src/lib/transfer/tracking.server.js +8 -5
  417. package/src/lib/transfer/tracking.server.js.map +1 -1
  418. package/src/lib/utils/add-to-cart.d.ts +2 -0
  419. package/src/lib/utils/add-to-cart.js +6 -3
  420. package/src/lib/utils/add-to-cart.js.map +1 -1
@@ -17,6 +17,8 @@ import { _ as _extends } from "@swc/helpers/_/_extends";
17
17
  */ import { firebaseAdmin } from "@aglyn/tenant-data-admin";
18
18
  import { authorizePosStaff, posRequestBody } from "./pos-auth.js";
19
19
  import { revokePosDisplays } from "./pos-display.js";
20
+ import { parsePosHardwareInPersonConfig } from "../model/pos-hardware.js";
21
+ import { parsePosCellularConfig, posCellularView } from "../model/pos-cellular.js";
20
22
  import { posStripe, posStripeErrorMessage, posStripeTestMode, posTerminalAvailable } from "./pos-stripe.js";
21
23
  import { ensurePosTerminalLocation, ownedTerminalReader, refreshPosReaderStatus } from "./pos-terminal.js";
22
24
  /**
@@ -34,12 +36,14 @@ import { ensurePosTerminalLocation, ownedTerminalReader, refreshPosReaderStatus
34
36
  });
35
37
  const body = posRequestBody(req);
36
38
  const hostId = String((_body_hostId = body['hostId']) != null ? _body_hostId : '');
37
- const gate = await authorizePosStaff(req, hostId);
39
+ const action = String((_body_action = body['action']) != null ? _body_action : '');
40
+ // Listing the readers is the register's; adding, renaming and removing one
41
+ // is setting it up (AGL-4047).
42
+ const gate = await authorizePosStaff(req, hostId, action === 'list' ? undefined : 'posDevices');
38
43
  if ('error' in gate) return res.status(gate.status).json({
39
44
  error: gate.error
40
45
  });
41
46
  const staff = gate.staff;
42
- const action = String((_body_action = body['action']) != null ? _body_action : '');
43
47
  try {
44
48
  switch(action){
45
49
  case 'list':
@@ -52,6 +56,13 @@ import { ensurePosTerminalLocation, ownedTerminalReader, refreshPosReaderStatus
52
56
  return await removeReader(staff, body, res);
53
57
  case 'remove-register':
54
58
  return await removeRegister(staff, body, res);
59
+ case 'cellular':
60
+ {
61
+ // 4G for the store's S710s (AGL-4038): set up like the readers, so
62
+ // "Registers and devices" on the store.
63
+ const answer = await (await import("./pos-cellular.js")).setPosStoreCellular(staff, body);
64
+ return res.status(answer.status).json(answer.body);
65
+ }
55
66
  default:
56
67
  return res.status(400).json({
57
68
  error: 'Unknown action'
@@ -64,6 +75,22 @@ import { ensurePosTerminalLocation, ownedTerminalReader, refreshPosReaderStatus
64
75
  });
65
76
  }
66
77
  };
78
+ /**
79
+ * The 4G row for the card (AGL-4038), or nothing: with why this viewer may
80
+ * not turn it on, since it is charged to the workspace ("Manage billing"),
81
+ * asked only where the row shows.
82
+ */ async function cellularFor(staff, terminal, readers) {
83
+ const config = parsePosCellularConfig(process.env);
84
+ if (!posCellularView(config, terminal, readers)) return {};
85
+ const { mayTurnOnPosCellular, POS_CELLULAR_BILLING_REFUSAL } = await import("./pos-cellular.js");
86
+ const turnOnBlocked = await mayTurnOnPosCellular(staff.uid, staff.hostId) ? null : POS_CELLULAR_BILLING_REFUSAL;
87
+ const cellular = posCellularView(config, terminal, readers, {
88
+ turnOnBlocked
89
+ });
90
+ return cellular ? {
91
+ cellular
92
+ } : {};
93
+ }
67
94
  function readersRef(hostId) {
68
95
  return firebaseAdmin.app().firestore().collection('hosts').doc(hostId).collection('terminalReaders');
69
96
  }
@@ -80,10 +107,11 @@ async function listReaders(staff, refresh) {
80
107
  }));
81
108
  }
82
109
  const config = await firebaseAdmin.app().firestore().collection('hosts').doc(staff.hostId).collection('terminal').doc('config').get();
83
- return {
110
+ return _extends({
84
111
  available,
85
112
  testMode: posStripeTestMode(),
86
- locationReady: Boolean(config.get('stripeLocationId')),
113
+ locationReady: Boolean(config.get('stripeLocationId'))
114
+ }, available ? await cellularFor(staff, config.data(), readers) : {}, {
87
115
  readers: readers.map((reader)=>{
88
116
  var _reader_registerId, _reader_deviceType, _reader_serialNumber, _reader_status;
89
117
  return {
@@ -96,38 +124,75 @@ async function listReaders(staff, refresh) {
96
124
  livemode: reader.livemode
97
125
  };
98
126
  })
99
- };
127
+ });
100
128
  }
101
129
  async function registerExists(hostId, registerId) {
102
130
  if (!/^[A-Za-z0-9_-]{1,128}$/.test(registerId)) return false;
103
131
  return (await firebaseAdmin.app().firestore().collection('hosts').doc(hostId).collection('registers').doc(registerId).get()).exists;
104
132
  }
105
133
  async function registerReader(staff, body, res) {
106
- var _body_registrationCode, _body_label, _body_registerId, _ref, _host_get, _address_line1, _address_city, _address_postalCode, _address_country, _created_body_status;
107
- var _created_body;
108
- if (!posTerminalAvailable()) {
109
- return res.status(409).json({
110
- error: 'Card readers are not available yet.'
111
- });
112
- }
113
- const registrationCode = String((_body_registrationCode = body['registrationCode']) != null ? _body_registrationCode : '').trim();
114
- if (!/^[A-Za-z0-9-]{3,64}$/.test(registrationCode)) {
115
- return res.status(400).json({
116
- error: 'Enter the code the reader shows on its screen.'
117
- });
118
- }
119
- const label = String((_body_label = body['label']) != null ? _body_label : '').trim().slice(0, 60) || 'Card reader';
134
+ var _body_registerId;
120
135
  const registerId = String((_body_registerId = body['registerId']) != null ? _body_registerId : '');
121
136
  if (registerId && !await registerExists(staff.hostId, registerId)) {
122
137
  return res.status(404).json({
123
138
  error: 'Unknown register'
124
139
  });
125
140
  }
126
- const host = await firebaseAdmin.app().firestore().collection('hosts').doc(staff.hostId).get();
127
- const address = body['address'];
128
- const location = await ensurePosTerminalLocation(_extends({
141
+ const registered = await registerPosTerminalReader(_extends({
129
142
  hostId: staff.hostId,
130
143
  orgId: staff.orgId,
144
+ uid: staff.uid,
145
+ registrationCode: body['registrationCode'],
146
+ label: body['label']
147
+ }, registerId ? {
148
+ registerId
149
+ } : {}, body['address'] ? {
150
+ address: body['address']
151
+ } : {}));
152
+ if ('error' in registered) return res.status(registered.status).json({
153
+ error: registered.error
154
+ });
155
+ return res.status(200).json({
156
+ reader: _extends({
157
+ id: registered.id
158
+ }, registered.reader)
159
+ });
160
+ }
161
+ /**
162
+ * Registers a reader to a store by the code it shows: the store's Stripe
163
+ * Terminal Location (made from `address` when the store has none), the
164
+ * reader at Stripe, and `hosts/{hostId}/terminalReaders/{id}`. The POS
165
+ * devices card's Add card reader, and the platform's own register setting a
166
+ * reader up for the store of the person who just bought it (AGL-4038).
167
+ *
168
+ * A reader whose serial number was taken when it was sold in person is
169
+ * found on its hardware order, which moves on to Set up (AGL-4038,
170
+ * `pos-hardware-readers.ts`); that never fails the registration.
171
+ */ export async function registerPosTerminalReader(input) {
172
+ var _input_registrationCode, _input_label, _input_registerId, _ref, _host_get, _address_line1, _address_city, _address_postalCode, _address_country, _created_body_status;
173
+ var _created_body;
174
+ if (!posTerminalAvailable()) {
175
+ return {
176
+ ok: false,
177
+ status: 409,
178
+ error: 'Card readers are not available yet.'
179
+ };
180
+ }
181
+ const registrationCode = String((_input_registrationCode = input.registrationCode) != null ? _input_registrationCode : '').trim();
182
+ if (!/^[A-Za-z0-9-]{3,64}$/.test(registrationCode)) {
183
+ return {
184
+ ok: false,
185
+ status: 400,
186
+ error: 'Enter the code the reader shows on its screen.'
187
+ };
188
+ }
189
+ const label = String((_input_label = input.label) != null ? _input_label : '').trim().slice(0, 60) || 'Card reader';
190
+ const registerId = (_input_registerId = input.registerId) != null ? _input_registerId : '';
191
+ const host = await firebaseAdmin.app().firestore().collection('hosts').doc(input.hostId).get();
192
+ const address = input.address;
193
+ const location = await ensurePosTerminalLocation(_extends({
194
+ hostId: input.hostId,
195
+ orgId: input.orgId,
131
196
  displayName: String((_ref = (_host_get = host.get('name')) != null ? _host_get : host.get('title')) != null ? _ref : 'Store')
132
197
  }, address ? {
133
198
  address: _extends({
@@ -143,9 +208,11 @@ async function registerReader(staff, body, res) {
143
208
  country: String((_address_country = address.country) != null ? _address_country : '').toUpperCase().slice(0, 2)
144
209
  })
145
210
  } : {}));
146
- if ('error' in location) return res.status(location.status).json({
211
+ if ('error' in location) return {
212
+ ok: false,
213
+ status: location.status,
147
214
  error: location.error
148
- });
215
+ };
149
216
  // Not keyed: a registration code is single-use at Stripe, which is the
150
217
  // dedupe — a second press with the same code is refused there, and no
151
218
  // other store can ever register a reader this one already holds.
@@ -154,16 +221,18 @@ async function registerReader(staff, body, res) {
154
221
  registration_code: registrationCode,
155
222
  label,
156
223
  location: location.locationId,
157
- 'metadata[orgId]': staff.orgId,
158
- 'metadata[hostId]': staff.hostId
224
+ 'metadata[orgId]': input.orgId,
225
+ 'metadata[hostId]': input.hostId
159
226
  }, registerId ? {
160
227
  'metadata[registerId]': registerId
161
228
  } : {})
162
229
  });
163
230
  if (!created.ok || !((_created_body = created.body) == null ? void 0 : _created_body.id)) {
164
- return res.status(400).json({
231
+ return {
232
+ ok: false,
233
+ status: 400,
165
234
  error: posStripeErrorMessage(created.body, 'That code did not register a reader. Check the code on the reader and try again.')
166
- });
235
+ };
167
236
  }
168
237
  const reader = _extends({
169
238
  label
@@ -179,14 +248,29 @@ async function registerReader(staff, body, res) {
179
248
  status: String((_created_body_status = created.body.status) != null ? _created_body_status : 'offline'),
180
249
  livemode: Boolean(created.body.livemode),
181
250
  createdAtMs: Date.now(),
182
- createdBy: staff.uid
183
- });
184
- await readersRef(staff.hostId).doc(String(created.body.id)).set(reader);
185
- return res.status(200).json({
186
- reader: _extends({
187
- id: String(created.body.id)
188
- }, reader)
251
+ createdBy: input.uid
189
252
  });
253
+ const id = String(created.body.id);
254
+ await readersRef(input.hostId).doc(id).set(reader);
255
+ await syncCellular(input.hostId, input.orgId);
256
+ if (reader.serialNumber && parsePosHardwareInPersonConfig(process.env)) {
257
+ try {
258
+ await (await import("./pos-hardware-readers.js")).matchRegisteredPosHardwareReader({
259
+ hostId: input.hostId,
260
+ orgId: input.orgId,
261
+ uid: input.uid,
262
+ readerId: id,
263
+ serialNumber: reader.serialNumber
264
+ });
265
+ } catch (error) {
266
+ console.error('[pos-readers] the hardware order was not matched', id, error);
267
+ }
268
+ }
269
+ return {
270
+ ok: true,
271
+ id,
272
+ reader
273
+ };
190
274
  }
191
275
  async function updateReader(staff, body, res) {
192
276
  var _body_registerId;
@@ -240,10 +324,25 @@ async function removeReader(staff, body, res) {
240
324
  });
241
325
  }
242
326
  await readersRef(staff.hostId).doc(reader.id).delete();
327
+ await syncCellular(staff.hostId, staff.orgId);
243
328
  return res.status(200).json({
244
329
  ok: true
245
330
  });
246
331
  }
332
+ /**
333
+ * A reader added to or removed from a store with 4G (AGL-4038) starts or
334
+ * stops counting toward its monthly charge. Never fails the reader's own
335
+ * change; the next turn-on, turn-off or reader change heals a miss.
336
+ */ async function syncCellular(hostId, orgId) {
337
+ try {
338
+ await (await import("./pos-cellular.js")).syncPosCellularReaders({
339
+ hostId,
340
+ orgId
341
+ });
342
+ } catch (error) {
343
+ console.error('[pos-readers] the 4G record was not updated', hostId, error);
344
+ }
345
+ }
247
346
  /**
248
347
  * Removes a register on the server (AGL-3617). The settings card deleted it
249
348
  * with a client `deleteDoc`, which the Firestore rules refuse for everyone but
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/server/pos-readers.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { firebaseAdmin } from '@aglyn/tenant-data-admin'\nimport type { PluginApiHandler } from '@aglyn/aglyn/server'\nimport { authorizePosStaff, posRequestBody, type PosStaff } from './pos-auth'\nimport { revokePosDisplays } from './pos-display'\nimport { posStripe, posStripeErrorMessage, posStripeTestMode, posTerminalAvailable } from './pos-stripe'\nimport {\n ensurePosTerminalLocation,\n ownedTerminalReader,\n refreshPosReaderStatus,\n type PosTerminalAddress,\n type PosTerminalReader,\n} from './pos-terminal'\n\n/**\n * `POST /api/commerce/pos-readers` (AGL-3607): the site's Stripe Terminal\n * card readers, from the \"Card readers\" settings card, and the server-side\n * removal of a register.\n *\n * Every action names a reader by id, and every one reads that reader under\n * the CALLER's site first (`ownedTerminalReader`): a reader id copied from\n * another store is \"not on this site\", whatever Stripe would say about it.\n */\nexport const posReadersHandler: PluginApiHandler = async (req, res) => {\n if (req.method !== 'POST') return res.status(405).json({ error: 'Method not allowed' })\n const body = posRequestBody(req)\n const hostId = String(body['hostId'] ?? '')\n const gate = await authorizePosStaff(req, hostId)\n if ('error' in gate) return res.status(gate.status).json({ error: gate.error })\n const staff = gate.staff\n const action = String(body['action'] ?? '')\n try {\n switch (action) {\n case 'list':\n return res.status(200).json(await listReaders(staff, body['refresh'] === true))\n case 'register':\n return await registerReader(staff, body, res)\n case 'update':\n return await updateReader(staff, body, res)\n case 'remove':\n return await removeReader(staff, body, res)\n case 'remove-register':\n return await removeRegister(staff, body, res)\n default:\n return res.status(400).json({ error: 'Unknown action' })\n }\n } catch (error) {\n console.error('[pos-readers]', action, error)\n return res.status(500).json({ error: 'Card readers could not be updated' })\n }\n}\n\nfunction readersRef(hostId: string) {\n return firebaseAdmin.app().firestore().collection('hosts').doc(hostId).collection('terminalReaders')\n}\n\nasync function listReaders(staff: PosStaff, refresh: boolean) {\n const available = posTerminalAvailable()\n const snapshot = await readersRef(staff.hostId).limit(50).get()\n const readers = snapshot.docs.map((doc: any) => ({\n id: doc.id as string,\n ...(doc.data() as PosTerminalReader),\n }))\n if (available && refresh) {\n await Promise.all(\n readers.map(async (reader: PosTerminalReader & { id: string }) => {\n const fresh = await refreshPosReaderStatus(staff.hostId, reader.id).catch(() => null)\n if (fresh) reader.status = fresh.status\n }),\n )\n }\n const config = await firebaseAdmin\n .app()\n .firestore()\n .collection('hosts')\n .doc(staff.hostId)\n .collection('terminal')\n .doc('config')\n .get()\n return {\n available,\n testMode: posStripeTestMode(),\n locationReady: Boolean(config.get('stripeLocationId')),\n readers: readers.map((reader: PosTerminalReader & { id: string }) => ({\n id: reader.id,\n label: reader.label,\n registerId: reader.registerId ?? null,\n deviceType: reader.deviceType ?? null,\n serialNumber: reader.serialNumber ?? null,\n status: reader.status ?? 'offline',\n livemode: reader.livemode,\n })),\n }\n}\n\nasync function registerExists(hostId: string, registerId: string): Promise<boolean> {\n if (!/^[A-Za-z0-9_-]{1,128}$/.test(registerId)) return false\n return (\n await firebaseAdmin\n .app()\n .firestore()\n .collection('hosts')\n .doc(hostId)\n .collection('registers')\n .doc(registerId)\n .get()\n ).exists\n}\n\nasync function registerReader(\n staff: PosStaff,\n body: Record<string, any>,\n res: Parameters<PluginApiHandler>[1],\n) {\n if (!posTerminalAvailable()) {\n return res.status(409).json({ error: 'Card readers are not available yet.' })\n }\n const registrationCode = String(body['registrationCode'] ?? '').trim()\n if (!/^[A-Za-z0-9-]{3,64}$/.test(registrationCode)) {\n return res.status(400).json({ error: 'Enter the code the reader shows on its screen.' })\n }\n const label = String(body['label'] ?? '').trim().slice(0, 60) || 'Card reader'\n const registerId = String(body['registerId'] ?? '')\n if (registerId && !(await registerExists(staff.hostId, registerId))) {\n return res.status(404).json({ error: 'Unknown register' })\n }\n const host = await firebaseAdmin.app().firestore().collection('hosts').doc(staff.hostId).get()\n const address = body['address'] as PosTerminalAddress | undefined\n const location = await ensurePosTerminalLocation({\n hostId: staff.hostId,\n orgId: staff.orgId,\n displayName: String(host.get('name') ?? host.get('title') ?? 'Store'),\n ...(address\n ? {\n address: {\n line1: String(address.line1 ?? '').slice(0, 200),\n ...(address.line2 ? { line2: String(address.line2).slice(0, 200) } : {}),\n city: String(address.city ?? '').slice(0, 100),\n ...(address.state ? { state: String(address.state).slice(0, 100) } : {}),\n postalCode: String(address.postalCode ?? '').slice(0, 20),\n country: String(address.country ?? '').toUpperCase().slice(0, 2),\n },\n }\n : {}),\n })\n if ('error' in location) return res.status(location.status).json({ error: location.error })\n // Not keyed: a registration code is single-use at Stripe, which is the\n // dedupe — a second press with the same code is refused there, and no\n // other store can ever register a reader this one already holds.\n const created = await posStripe('POST', 'terminal/readers', {\n params: {\n registration_code: registrationCode,\n label,\n location: location.locationId,\n 'metadata[orgId]': staff.orgId,\n 'metadata[hostId]': staff.hostId,\n ...(registerId ? { 'metadata[registerId]': registerId } : {}),\n },\n })\n if (!created.ok || !created.body?.id) {\n return res.status(400).json({\n error: posStripeErrorMessage(\n created.body,\n 'That code did not register a reader. Check the code on the reader and try again.',\n ),\n })\n }\n const reader: PosTerminalReader = {\n label,\n ...(registerId ? { registerId } : {}),\n stripeLocationId: location.locationId,\n ...(created.body.device_type ? { deviceType: String(created.body.device_type) } : {}),\n ...(created.body.serial_number ? { serialNumber: String(created.body.serial_number) } : {}),\n status: String(created.body.status ?? 'offline'),\n livemode: Boolean(created.body.livemode),\n createdAtMs: Date.now(),\n createdBy: staff.uid,\n }\n await readersRef(staff.hostId).doc(String(created.body.id)).set(reader)\n return res.status(200).json({ reader: { id: String(created.body.id), ...reader } })\n}\n\nasync function updateReader(\n staff: PosStaff,\n body: Record<string, any>,\n res: Parameters<PluginApiHandler>[1],\n) {\n const reader = await ownedTerminalReader(staff.hostId, body['readerId'])\n if (!reader) return res.status(404).json({ error: 'That card reader is not on this site.' })\n const patch: Record<string, unknown> = {}\n if (typeof body['label'] === 'string') {\n patch['label'] = body['label'].trim().slice(0, 60) || reader.label\n }\n if ('registerId' in body) {\n const registerId = String(body['registerId'] ?? '')\n if (registerId && !(await registerExists(staff.hostId, registerId))) {\n return res.status(404).json({ error: 'Unknown register' })\n }\n patch['registerId'] = registerId || firebaseAdmin.firestore.FieldValue.delete()\n }\n const updated = await posStripe('POST', `terminal/readers/${reader.id}`, {\n params: {\n ...(patch['label'] ? { label: String(patch['label']) } : {}),\n ...('registerId' in body ? { 'metadata[registerId]': String(body['registerId'] ?? '') } : {}),\n },\n })\n if (!updated.ok) {\n return res.status(502).json({ error: posStripeErrorMessage(updated.body, 'The reader could not be updated.') })\n }\n await readersRef(staff.hostId).doc(reader.id).set(patch, { merge: true })\n return res.status(200).json({ ok: true })\n}\n\nasync function removeReader(\n staff: PosStaff,\n body: Record<string, any>,\n res: Parameters<PluginApiHandler>[1],\n) {\n const reader = await ownedTerminalReader(staff.hostId, body['readerId'])\n if (!reader) return res.status(404).json({ error: 'That card reader is not on this site.' })\n const removed = await posStripe('DELETE', `terminal/readers/${reader.id}`)\n // Already gone at Stripe is the outcome asked for; anything else is not.\n if (!removed.ok && removed.status !== 404) {\n return res.status(502).json({ error: posStripeErrorMessage(removed.body, 'The reader could not be removed.') })\n }\n await readersRef(staff.hostId).doc(reader.id).delete()\n return res.status(200).json({ ok: true })\n}\n\n/**\n * Removes a register on the server (AGL-3617). The settings card deleted it\n * with a client `deleteDoc`, which the Firestore rules refuse for everyone but\n * staff (`registers` is server-owned since AGL-1775), so a merchant's Remove\n * button failed with a permission error. Removing it here also signs out its\n * customer displays and unbinds its readers.\n */\nasync function removeRegister(\n staff: PosStaff,\n body: Record<string, any>,\n res: Parameters<PluginApiHandler>[1],\n) {\n const registerId = String(body['registerId'] ?? '')\n if (!(await registerExists(staff.hostId, registerId))) {\n return res.status(404).json({ error: 'Unknown register' })\n }\n const firestore = firebaseAdmin.app().firestore()\n const registerRef = firestore\n .collection('hosts')\n .doc(staff.hostId)\n .collection('registers')\n .doc(registerId)\n await revokePosDisplays(staff.hostId, registerId)\n await registerRef.delete()\n const bound = await readersRef(staff.hostId).where('registerId', '==', registerId).limit(50).get()\n await Promise.all(\n bound.docs.map((doc: any) =>\n doc.ref.set({ registerId: firebaseAdmin.firestore.FieldValue.delete() }, { merge: true }),\n ),\n )\n return res.status(200).json({ ok: true })\n}\n"],"names":["firebaseAdmin","authorizePosStaff","posRequestBody","revokePosDisplays","posStripe","posStripeErrorMessage","posStripeTestMode","posTerminalAvailable","ensurePosTerminalLocation","ownedTerminalReader","refreshPosReaderStatus","posReadersHandler","req","res","body","method","status","json","error","hostId","String","gate","staff","action","listReaders","registerReader","updateReader","removeReader","removeRegister","console","readersRef","app","firestore","collection","doc","refresh","available","snapshot","limit","get","readers","docs","map","id","data","Promise","all","reader","fresh","catch","config","testMode","locationReady","Boolean","label","registerId","deviceType","serialNumber","livemode","registerExists","test","exists","host","address","created","registrationCode","trim","slice","location","orgId","displayName","line1","line2","city","state","postalCode","country","toUpperCase","params","registration_code","locationId","ok","stripeLocationId","device_type","serial_number","createdAtMs","Date","now","createdBy","uid","set","patch","FieldValue","delete","updated","merge","removed","registerRef","bound","where","ref"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/server/pos-readers.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { firebaseAdmin } from '@aglyn/tenant-data-admin'\nimport type { PluginApiHandler } from '@aglyn/aglyn/server'\nimport { authorizePosStaff, posRequestBody, type PosStaff } from './pos-auth'\nimport { revokePosDisplays } from './pos-display'\nimport { parsePosHardwareInPersonConfig } from '../model/pos-hardware'\nimport { parsePosCellularConfig, posCellularView, type PosCellularView } from '../model/pos-cellular'\nimport { posStripe, posStripeErrorMessage, posStripeTestMode, posTerminalAvailable } from './pos-stripe'\nimport {\n ensurePosTerminalLocation,\n ownedTerminalReader,\n refreshPosReaderStatus,\n type PosTerminalAddress,\n type PosTerminalReader,\n} from './pos-terminal'\n\n/**\n * `POST /api/commerce/pos-readers` (AGL-3607): the site's Stripe Terminal\n * card readers, from the \"Card readers\" settings card, and the server-side\n * removal of a register.\n *\n * Every action names a reader by id, and every one reads that reader under\n * the CALLER's site first (`ownedTerminalReader`): a reader id copied from\n * another store is \"not on this site\", whatever Stripe would say about it.\n */\nexport const posReadersHandler: PluginApiHandler = async (req, res) => {\n if (req.method !== 'POST') return res.status(405).json({ error: 'Method not allowed' })\n const body = posRequestBody(req)\n const hostId = String(body['hostId'] ?? '')\n const action = String(body['action'] ?? '')\n // Listing the readers is the register's; adding, renaming and removing one\n // is setting it up (AGL-4047).\n const gate = await authorizePosStaff(req, hostId, action === 'list' ? undefined : 'posDevices')\n if ('error' in gate) return res.status(gate.status).json({ error: gate.error })\n const staff = gate.staff\n try {\n switch (action) {\n case 'list':\n return res.status(200).json(await listReaders(staff, body['refresh'] === true))\n case 'register':\n return await registerReader(staff, body, res)\n case 'update':\n return await updateReader(staff, body, res)\n case 'remove':\n return await removeReader(staff, body, res)\n case 'remove-register':\n return await removeRegister(staff, body, res)\n case 'cellular': {\n // 4G for the store's S710s (AGL-4038): set up like the readers, so\n // \"Registers and devices\" on the store.\n const answer = await (await import('./pos-cellular')).setPosStoreCellular(staff, body)\n return res.status(answer.status).json(answer.body)\n }\n default:\n return res.status(400).json({ error: 'Unknown action' })\n }\n } catch (error) {\n console.error('[pos-readers]', action, error)\n return res.status(500).json({ error: 'Card readers could not be updated' })\n }\n}\n\n/**\n * The 4G row for the card (AGL-4038), or nothing: with why this viewer may\n * not turn it on, since it is charged to the workspace (\"Manage billing\"),\n * asked only where the row shows.\n */\nasync function cellularFor(\n staff: PosStaff,\n terminal: Record<string, unknown> | undefined,\n readers: ReadonlyArray<{ deviceType?: unknown }>,\n): Promise<{ cellular?: PosCellularView }> {\n const config = parsePosCellularConfig(process.env)\n if (!posCellularView(config, terminal, readers)) return {}\n const { mayTurnOnPosCellular, POS_CELLULAR_BILLING_REFUSAL } = await import('./pos-cellular')\n const turnOnBlocked = (await mayTurnOnPosCellular(staff.uid, staff.hostId)) ? null : POS_CELLULAR_BILLING_REFUSAL\n const cellular = posCellularView(config, terminal, readers, { turnOnBlocked })\n return cellular ? { cellular } : {}\n}\n\nfunction readersRef(hostId: string) {\n return firebaseAdmin.app().firestore().collection('hosts').doc(hostId).collection('terminalReaders')\n}\n\nasync function listReaders(staff: PosStaff, refresh: boolean) {\n const available = posTerminalAvailable()\n const snapshot = await readersRef(staff.hostId).limit(50).get()\n const readers = snapshot.docs.map((doc: any) => ({\n id: doc.id as string,\n ...(doc.data() as PosTerminalReader),\n }))\n if (available && refresh) {\n await Promise.all(\n readers.map(async (reader: PosTerminalReader & { id: string }) => {\n const fresh = await refreshPosReaderStatus(staff.hostId, reader.id).catch(() => null)\n if (fresh) reader.status = fresh.status\n }),\n )\n }\n const config = await firebaseAdmin\n .app()\n .firestore()\n .collection('hosts')\n .doc(staff.hostId)\n .collection('terminal')\n .doc('config')\n .get()\n return {\n available,\n testMode: posStripeTestMode(),\n locationReady: Boolean(config.get('stripeLocationId')),\n // 4G for the store's S710s (AGL-4038), only where it is offered and the\n // store has one; absent otherwise, so the card shows nothing of it.\n ...(available ? await cellularFor(staff, config.data(), readers) : {}),\n readers: readers.map((reader: PosTerminalReader & { id: string }) => ({\n id: reader.id,\n label: reader.label,\n registerId: reader.registerId ?? null,\n deviceType: reader.deviceType ?? null,\n serialNumber: reader.serialNumber ?? null,\n status: reader.status ?? 'offline',\n livemode: reader.livemode,\n })),\n }\n}\n\nasync function registerExists(hostId: string, registerId: string): Promise<boolean> {\n if (!/^[A-Za-z0-9_-]{1,128}$/.test(registerId)) return false\n return (\n await firebaseAdmin\n .app()\n .firestore()\n .collection('hosts')\n .doc(hostId)\n .collection('registers')\n .doc(registerId)\n .get()\n ).exists\n}\n\nasync function registerReader(\n staff: PosStaff,\n body: Record<string, any>,\n res: Parameters<PluginApiHandler>[1],\n) {\n const registerId = String(body['registerId'] ?? '')\n if (registerId && !(await registerExists(staff.hostId, registerId))) {\n return res.status(404).json({ error: 'Unknown register' })\n }\n const registered = await registerPosTerminalReader({\n hostId: staff.hostId,\n orgId: staff.orgId,\n uid: staff.uid,\n registrationCode: body['registrationCode'],\n label: body['label'],\n ...(registerId ? { registerId } : {}),\n ...(body['address'] ? { address: body['address'] as PosTerminalAddress } : {}),\n })\n if ('error' in registered) return res.status(registered.status).json({ error: registered.error })\n return res.status(200).json({ reader: { id: registered.id, ...registered.reader } })\n}\n\n/**\n * Registers a reader to a store by the code it shows: the store's Stripe\n * Terminal Location (made from `address` when the store has none), the\n * reader at Stripe, and `hosts/{hostId}/terminalReaders/{id}`. The POS\n * devices card's Add card reader, and the platform's own register setting a\n * reader up for the store of the person who just bought it (AGL-4038).\n *\n * A reader whose serial number was taken when it was sold in person is\n * found on its hardware order, which moves on to Set up (AGL-4038,\n * `pos-hardware-readers.ts`); that never fails the registration.\n */\nexport async function registerPosTerminalReader(input: {\n hostId: string\n orgId: string\n uid: string\n registrationCode: unknown\n label?: unknown\n registerId?: string\n address?: PosTerminalAddress\n}): Promise<\n { ok: true; id: string; reader: PosTerminalReader } | { ok: false; status: number; error: string }\n> {\n if (!posTerminalAvailable()) {\n return { ok: false, status: 409, error: 'Card readers are not available yet.' }\n }\n const registrationCode = String(input.registrationCode ?? '').trim()\n if (!/^[A-Za-z0-9-]{3,64}$/.test(registrationCode)) {\n return { ok: false, status: 400, error: 'Enter the code the reader shows on its screen.' }\n }\n const label = String(input.label ?? '').trim().slice(0, 60) || 'Card reader'\n const registerId = input.registerId ?? ''\n const host = await firebaseAdmin.app().firestore().collection('hosts').doc(input.hostId).get()\n const address = input.address\n const location = await ensurePosTerminalLocation({\n hostId: input.hostId,\n orgId: input.orgId,\n displayName: String(host.get('name') ?? host.get('title') ?? 'Store'),\n ...(address\n ? {\n address: {\n line1: String(address.line1 ?? '').slice(0, 200),\n ...(address.line2 ? { line2: String(address.line2).slice(0, 200) } : {}),\n city: String(address.city ?? '').slice(0, 100),\n ...(address.state ? { state: String(address.state).slice(0, 100) } : {}),\n postalCode: String(address.postalCode ?? '').slice(0, 20),\n country: String(address.country ?? '').toUpperCase().slice(0, 2),\n },\n }\n : {}),\n })\n if ('error' in location) return { ok: false, status: location.status, error: location.error }\n // Not keyed: a registration code is single-use at Stripe, which is the\n // dedupe — a second press with the same code is refused there, and no\n // other store can ever register a reader this one already holds.\n const created = await posStripe('POST', 'terminal/readers', {\n params: {\n registration_code: registrationCode,\n label,\n location: location.locationId,\n 'metadata[orgId]': input.orgId,\n 'metadata[hostId]': input.hostId,\n ...(registerId ? { 'metadata[registerId]': registerId } : {}),\n },\n })\n if (!created.ok || !created.body?.id) {\n return {\n ok: false,\n status: 400,\n error: posStripeErrorMessage(\n created.body,\n 'That code did not register a reader. Check the code on the reader and try again.',\n ),\n }\n }\n const reader: PosTerminalReader = {\n label,\n ...(registerId ? { registerId } : {}),\n stripeLocationId: location.locationId,\n ...(created.body.device_type ? { deviceType: String(created.body.device_type) } : {}),\n ...(created.body.serial_number ? { serialNumber: String(created.body.serial_number) } : {}),\n status: String(created.body.status ?? 'offline'),\n livemode: Boolean(created.body.livemode),\n createdAtMs: Date.now(),\n createdBy: input.uid,\n }\n const id = String(created.body.id)\n await readersRef(input.hostId).doc(id).set(reader)\n await syncCellular(input.hostId, input.orgId)\n if (reader.serialNumber && parsePosHardwareInPersonConfig(process.env)) {\n try {\n await (await import('./pos-hardware-readers')).matchRegisteredPosHardwareReader({\n hostId: input.hostId,\n orgId: input.orgId,\n uid: input.uid,\n readerId: id,\n serialNumber: reader.serialNumber,\n })\n } catch (error) {\n console.error('[pos-readers] the hardware order was not matched', id, error)\n }\n }\n return { ok: true, id, reader }\n}\n\nasync function updateReader(\n staff: PosStaff,\n body: Record<string, any>,\n res: Parameters<PluginApiHandler>[1],\n) {\n const reader = await ownedTerminalReader(staff.hostId, body['readerId'])\n if (!reader) return res.status(404).json({ error: 'That card reader is not on this site.' })\n const patch: Record<string, unknown> = {}\n if (typeof body['label'] === 'string') {\n patch['label'] = body['label'].trim().slice(0, 60) || reader.label\n }\n if ('registerId' in body) {\n const registerId = String(body['registerId'] ?? '')\n if (registerId && !(await registerExists(staff.hostId, registerId))) {\n return res.status(404).json({ error: 'Unknown register' })\n }\n patch['registerId'] = registerId || firebaseAdmin.firestore.FieldValue.delete()\n }\n const updated = await posStripe('POST', `terminal/readers/${reader.id}`, {\n params: {\n ...(patch['label'] ? { label: String(patch['label']) } : {}),\n ...('registerId' in body ? { 'metadata[registerId]': String(body['registerId'] ?? '') } : {}),\n },\n })\n if (!updated.ok) {\n return res.status(502).json({ error: posStripeErrorMessage(updated.body, 'The reader could not be updated.') })\n }\n await readersRef(staff.hostId).doc(reader.id).set(patch, { merge: true })\n return res.status(200).json({ ok: true })\n}\n\nasync function removeReader(\n staff: PosStaff,\n body: Record<string, any>,\n res: Parameters<PluginApiHandler>[1],\n) {\n const reader = await ownedTerminalReader(staff.hostId, body['readerId'])\n if (!reader) return res.status(404).json({ error: 'That card reader is not on this site.' })\n const removed = await posStripe('DELETE', `terminal/readers/${reader.id}`)\n // Already gone at Stripe is the outcome asked for; anything else is not.\n if (!removed.ok && removed.status !== 404) {\n return res.status(502).json({ error: posStripeErrorMessage(removed.body, 'The reader could not be removed.') })\n }\n await readersRef(staff.hostId).doc(reader.id).delete()\n await syncCellular(staff.hostId, staff.orgId)\n return res.status(200).json({ ok: true })\n}\n\n/**\n * A reader added to or removed from a store with 4G (AGL-4038) starts or\n * stops counting toward its monthly charge. Never fails the reader's own\n * change; the next turn-on, turn-off or reader change heals a miss.\n */\nasync function syncCellular(hostId: string, orgId: string): Promise<void> {\n try {\n await (await import('./pos-cellular')).syncPosCellularReaders({ hostId, orgId })\n } catch (error) {\n console.error('[pos-readers] the 4G record was not updated', hostId, error)\n }\n}\n\n/**\n * Removes a register on the server (AGL-3617). The settings card deleted it\n * with a client `deleteDoc`, which the Firestore rules refuse for everyone but\n * staff (`registers` is server-owned since AGL-1775), so a merchant's Remove\n * button failed with a permission error. Removing it here also signs out its\n * customer displays and unbinds its readers.\n */\nasync function removeRegister(\n staff: PosStaff,\n body: Record<string, any>,\n res: Parameters<PluginApiHandler>[1],\n) {\n const registerId = String(body['registerId'] ?? '')\n if (!(await registerExists(staff.hostId, registerId))) {\n return res.status(404).json({ error: 'Unknown register' })\n }\n const firestore = firebaseAdmin.app().firestore()\n const registerRef = firestore\n .collection('hosts')\n .doc(staff.hostId)\n .collection('registers')\n .doc(registerId)\n await revokePosDisplays(staff.hostId, registerId)\n await registerRef.delete()\n const bound = await readersRef(staff.hostId).where('registerId', '==', registerId).limit(50).get()\n await Promise.all(\n bound.docs.map((doc: any) =>\n doc.ref.set({ registerId: firebaseAdmin.firestore.FieldValue.delete() }, { merge: true }),\n ),\n )\n return res.status(200).json({ ok: true })\n}\n"],"names":["firebaseAdmin","authorizePosStaff","posRequestBody","revokePosDisplays","parsePosHardwareInPersonConfig","parsePosCellularConfig","posCellularView","posStripe","posStripeErrorMessage","posStripeTestMode","posTerminalAvailable","ensurePosTerminalLocation","ownedTerminalReader","refreshPosReaderStatus","posReadersHandler","req","res","body","method","status","json","error","hostId","String","action","gate","undefined","staff","listReaders","registerReader","updateReader","removeReader","removeRegister","answer","setPosStoreCellular","console","cellularFor","terminal","readers","config","process","env","mayTurnOnPosCellular","POS_CELLULAR_BILLING_REFUSAL","turnOnBlocked","uid","cellular","readersRef","app","firestore","collection","doc","refresh","available","snapshot","limit","get","docs","map","id","data","Promise","all","reader","fresh","catch","testMode","locationReady","Boolean","label","registerId","deviceType","serialNumber","livemode","registerExists","test","exists","registered","registerPosTerminalReader","orgId","registrationCode","address","input","host","created","ok","trim","slice","location","displayName","line1","line2","city","state","postalCode","country","toUpperCase","params","registration_code","locationId","stripeLocationId","device_type","serial_number","createdAtMs","Date","now","createdBy","set","syncCellular","matchRegisteredPosHardwareReader","readerId","patch","FieldValue","delete","updated","merge","removed","syncPosCellularReaders","registerRef","bound","where","ref"],"mappings":";AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,aAAa,QAAQ,2BAA0B;AAExD,SAASC,iBAAiB,EAAEC,cAAc,QAAuB,gBAAY;AAC7E,SAASC,iBAAiB,QAAQ,mBAAe;AACjD,SAASC,8BAA8B,QAAQ,2BAAuB;AACtE,SAASC,sBAAsB,EAAEC,eAAe,QAA8B,2BAAuB;AACrG,SAASC,SAAS,EAAEC,qBAAqB,EAAEC,iBAAiB,EAAEC,oBAAoB,QAAQ,kBAAc;AACxG,SACEC,yBAAyB,EACzBC,mBAAmB,EACnBC,sBAAsB,QAGjB,oBAAgB;AAEvB;;;;;;;;CAQC,GACD,OAAO,MAAMC,oBAAsC,OAAOC,KAAKC;QAGvCC,cACAA;IAHtB,IAAIF,IAAIG,MAAM,KAAK,QAAQ,OAAOF,IAAIG,MAAM,CAAC,KAAKC,IAAI,CAAC;QAAEC,OAAO;IAAqB;IACrF,MAAMJ,OAAOf,eAAea;IAC5B,MAAMO,SAASC,QAAON,eAAAA,IAAI,CAAC,SAAS,YAAdA,eAAkB;IACxC,MAAMO,SAASD,QAAON,eAAAA,IAAI,CAAC,SAAS,YAAdA,eAAkB;IACxC,2EAA2E;IAC3E,+BAA+B;IAC/B,MAAMQ,OAAO,MAAMxB,kBAAkBc,KAAKO,QAAQE,WAAW,SAASE,YAAY;IAClF,IAAI,WAAWD,MAAM,OAAOT,IAAIG,MAAM,CAACM,KAAKN,MAAM,EAAEC,IAAI,CAAC;QAAEC,OAAOI,KAAKJ,KAAK;IAAC;IAC7E,MAAMM,QAAQF,KAAKE,KAAK;IACxB,IAAI;QACF,OAAQH;YACN,KAAK;gBACH,OAAOR,IAAIG,MAAM,CAAC,KAAKC,IAAI,CAAC,MAAMQ,YAAYD,OAAOV,IAAI,CAAC,UAAU,KAAK;YAC3E,KAAK;gBACH,OAAO,MAAMY,eAAeF,OAAOV,MAAMD;YAC3C,KAAK;gBACH,OAAO,MAAMc,aAAaH,OAAOV,MAAMD;YACzC,KAAK;gBACH,OAAO,MAAMe,aAAaJ,OAAOV,MAAMD;YACzC,KAAK;gBACH,OAAO,MAAMgB,eAAeL,OAAOV,MAAMD;YAC3C,KAAK;gBAAY;oBACf,mEAAmE;oBACnE,wCAAwC;oBACxC,MAAMiB,SAAS,MAAM,AAAC,CAAA,MAAM,MAAM,CAAC,oBAAgB,EAAGC,mBAAmB,CAACP,OAAOV;oBACjF,OAAOD,IAAIG,MAAM,CAACc,OAAOd,MAAM,EAAEC,IAAI,CAACa,OAAOhB,IAAI;gBACnD;YACA;gBACE,OAAOD,IAAIG,MAAM,CAAC,KAAKC,IAAI,CAAC;oBAAEC,OAAO;gBAAiB;QAC1D;IACF,EAAE,OAAOA,OAAO;QACdc,QAAQd,KAAK,CAAC,iBAAiBG,QAAQH;QACvC,OAAOL,IAAIG,MAAM,CAAC,KAAKC,IAAI,CAAC;YAAEC,OAAO;QAAoC;IAC3E;AACF,EAAC;AAED;;;;CAIC,GACD,eAAee,YACbT,KAAe,EACfU,QAA6C,EAC7CC,OAAgD;IAEhD,MAAMC,SAASlC,uBAAuBmC,QAAQC,GAAG;IACjD,IAAI,CAACnC,gBAAgBiC,QAAQF,UAAUC,UAAU,OAAO,CAAC;IACzD,MAAM,EAAEI,oBAAoB,EAAEC,4BAA4B,EAAE,GAAG,MAAM,MAAM,CAAC;IAC5E,MAAMC,gBAAgB,AAAC,MAAMF,qBAAqBf,MAAMkB,GAAG,EAAElB,MAAML,MAAM,IAAK,OAAOqB;IACrF,MAAMG,WAAWxC,gBAAgBiC,QAAQF,UAAUC,SAAS;QAAEM;IAAc;IAC5E,OAAOE,WAAW;QAAEA;IAAS,IAAI,CAAC;AACpC;AAEA,SAASC,WAAWzB,MAAc;IAChC,OAAOtB,cAAcgD,GAAG,GAAGC,SAAS,GAAGC,UAAU,CAAC,SAASC,GAAG,CAAC7B,QAAQ4B,UAAU,CAAC;AACpF;AAEA,eAAetB,YAAYD,KAAe,EAAEyB,OAAgB;IAC1D,MAAMC,YAAY3C;IAClB,MAAM4C,WAAW,MAAMP,WAAWpB,MAAML,MAAM,EAAEiC,KAAK,CAAC,IAAIC,GAAG;IAC7D,MAAMlB,UAAUgB,SAASG,IAAI,CAACC,GAAG,CAAC,CAACP,MAAc;YAC/CQ,IAAIR,IAAIQ,EAAE;WACNR,IAAIS,IAAI;IAEd,IAAIP,aAAaD,SAAS;QACxB,MAAMS,QAAQC,GAAG,CACfxB,QAAQoB,GAAG,CAAC,OAAOK;YACjB,MAAMC,QAAQ,MAAMnD,uBAAuBc,MAAML,MAAM,EAAEyC,OAAOJ,EAAE,EAAEM,KAAK,CAAC,IAAM;YAChF,IAAID,OAAOD,OAAO5C,MAAM,GAAG6C,MAAM7C,MAAM;QACzC;IAEJ;IACA,MAAMoB,SAAS,MAAMvC,cAClBgD,GAAG,GACHC,SAAS,GACTC,UAAU,CAAC,SACXC,GAAG,CAACxB,MAAML,MAAM,EAChB4B,UAAU,CAAC,YACXC,GAAG,CAAC,UACJK,GAAG;IACN,OAAO;QACLH;QACAa,UAAUzD;QACV0D,eAAeC,QAAQ7B,OAAOiB,GAAG,CAAC;OAG9BH,YAAY,MAAMjB,YAAYT,OAAOY,OAAOqB,IAAI,IAAItB,WAAW,CAAC;QACpEA,SAASA,QAAQoB,GAAG,CAAC,CAACK;gBAGRA,oBACAA,oBACEA,sBACNA;mBAN4D;gBACpEJ,IAAII,OAAOJ,EAAE;gBACbU,OAAON,OAAOM,KAAK;gBACnBC,UAAU,GAAEP,qBAAAA,OAAOO,UAAU,YAAjBP,qBAAqB;gBACjCQ,UAAU,GAAER,qBAAAA,OAAOQ,UAAU,YAAjBR,qBAAqB;gBACjCS,YAAY,GAAET,uBAAAA,OAAOS,YAAY,YAAnBT,uBAAuB;gBACrC5C,MAAM,GAAE4C,iBAAAA,OAAO5C,MAAM,YAAb4C,iBAAiB;gBACzBU,UAAUV,OAAOU,QAAQ;YAC3B;;;AAEJ;AAEA,eAAeC,eAAepD,MAAc,EAAEgD,UAAkB;IAC9D,IAAI,CAAC,yBAAyBK,IAAI,CAACL,aAAa,OAAO;IACvD,OAAO,AACL,CAAA,MAAMtE,cACHgD,GAAG,GACHC,SAAS,GACTC,UAAU,CAAC,SACXC,GAAG,CAAC7B,QACJ4B,UAAU,CAAC,aACXC,GAAG,CAACmB,YACJd,GAAG,EAAC,EACPoB,MAAM;AACV;AAEA,eAAe/C,eACbF,KAAe,EACfV,IAAyB,EACzBD,GAAoC;QAEVC;IAA1B,MAAMqD,aAAa/C,QAAON,mBAAAA,IAAI,CAAC,aAAa,YAAlBA,mBAAsB;IAChD,IAAIqD,cAAc,CAAE,MAAMI,eAAe/C,MAAML,MAAM,EAAEgD,aAAc;QACnE,OAAOtD,IAAIG,MAAM,CAAC,KAAKC,IAAI,CAAC;YAAEC,OAAO;QAAmB;IAC1D;IACA,MAAMwD,aAAa,MAAMC,0BAA0B;QACjDxD,QAAQK,MAAML,MAAM;QACpByD,OAAOpD,MAAMoD,KAAK;QAClBlC,KAAKlB,MAAMkB,GAAG;QACdmC,kBAAkB/D,IAAI,CAAC,mBAAmB;QAC1CoD,OAAOpD,IAAI,CAAC,QAAQ;OAChBqD,aAAa;QAAEA;IAAW,IAAI,CAAC,GAC/BrD,IAAI,CAAC,UAAU,GAAG;QAAEgE,SAAShE,IAAI,CAAC,UAAU;IAAuB,IAAI,CAAC;IAE9E,IAAI,WAAW4D,YAAY,OAAO7D,IAAIG,MAAM,CAAC0D,WAAW1D,MAAM,EAAEC,IAAI,CAAC;QAAEC,OAAOwD,WAAWxD,KAAK;IAAC;IAC/F,OAAOL,IAAIG,MAAM,CAAC,KAAKC,IAAI,CAAC;QAAE2C,QAAQ;YAAEJ,IAAIkB,WAAWlB,EAAE;WAAKkB,WAAWd,MAAM;IAAG;AACpF;AAEA;;;;;;;;;;CAUC,GACD,OAAO,eAAee,0BAA0BI,KAQ/C;QAMiCA,yBAIXA,cACFA,mBAMGC,MAAAA,WAIEF,gBAEDA,eAEMA,qBACHA,kBAmCTG;QAhBGA;IA1CpB,IAAI,CAAC1E,wBAAwB;QAC3B,OAAO;YAAE2E,IAAI;YAAOlE,QAAQ;YAAKE,OAAO;QAAsC;IAChF;IACA,MAAM2D,mBAAmBzD,QAAO2D,0BAAAA,MAAMF,gBAAgB,YAAtBE,0BAA0B,IAAII,IAAI;IAClE,IAAI,CAAC,uBAAuBX,IAAI,CAACK,mBAAmB;QAClD,OAAO;YAAEK,IAAI;YAAOlE,QAAQ;YAAKE,OAAO;QAAiD;IAC3F;IACA,MAAMgD,QAAQ9C,QAAO2D,eAAAA,MAAMb,KAAK,YAAXa,eAAe,IAAII,IAAI,GAAGC,KAAK,CAAC,GAAG,OAAO;IAC/D,MAAMjB,cAAaY,oBAAAA,MAAMZ,UAAU,YAAhBY,oBAAoB;IACvC,MAAMC,OAAO,MAAMnF,cAAcgD,GAAG,GAAGC,SAAS,GAAGC,UAAU,CAAC,SAASC,GAAG,CAAC+B,MAAM5D,MAAM,EAAEkC,GAAG;IAC5F,MAAMyB,UAAUC,MAAMD,OAAO;IAC7B,MAAMO,WAAW,MAAM7E,0BAA0B;QAC/CW,QAAQ4D,MAAM5D,MAAM;QACpByD,OAAOG,MAAMH,KAAK;QAClBU,aAAalE,QAAO4D,QAAAA,YAAAA,KAAK3B,GAAG,CAAC,mBAAT2B,YAAoBA,KAAK3B,GAAG,CAAC,oBAA7B2B,OAAyC;OACzDF,UACA;QACEA,SAAS;YACPS,OAAOnE,QAAO0D,iBAAAA,QAAQS,KAAK,YAAbT,iBAAiB,IAAIM,KAAK,CAAC,GAAG;WACxCN,QAAQU,KAAK,GAAG;YAAEA,OAAOpE,OAAO0D,QAAQU,KAAK,EAAEJ,KAAK,CAAC,GAAG;QAAK,IAAI,CAAC;YACtEK,MAAMrE,QAAO0D,gBAAAA,QAAQW,IAAI,YAAZX,gBAAgB,IAAIM,KAAK,CAAC,GAAG;WACtCN,QAAQY,KAAK,GAAG;YAAEA,OAAOtE,OAAO0D,QAAQY,KAAK,EAAEN,KAAK,CAAC,GAAG;QAAK,IAAI,CAAC;YACtEO,YAAYvE,QAAO0D,sBAAAA,QAAQa,UAAU,YAAlBb,sBAAsB,IAAIM,KAAK,CAAC,GAAG;YACtDQ,SAASxE,QAAO0D,mBAAAA,QAAQc,OAAO,YAAfd,mBAAmB,IAAIe,WAAW,GAAGT,KAAK,CAAC,GAAG;;IAElE,IACA,CAAC;IAEP,IAAI,WAAWC,UAAU,OAAO;QAAEH,IAAI;QAAOlE,QAAQqE,SAASrE,MAAM;QAAEE,OAAOmE,SAASnE,KAAK;IAAC;IAC5F,uEAAuE;IACvE,sEAAsE;IACtE,iEAAiE;IACjE,MAAM+D,UAAU,MAAM7E,UAAU,QAAQ,oBAAoB;QAC1D0F,QAAQ;YACNC,mBAAmBlB;YACnBX;YACAmB,UAAUA,SAASW,UAAU;YAC7B,mBAAmBjB,MAAMH,KAAK;YAC9B,oBAAoBG,MAAM5D,MAAM;WAC5BgD,aAAa;YAAE,wBAAwBA;QAAW,IAAI,CAAC;IAE/D;IACA,IAAI,CAACc,QAAQC,EAAE,IAAI,GAACD,gBAAAA,QAAQnE,IAAI,qBAAZmE,cAAczB,EAAE,GAAE;QACpC,OAAO;YACL0B,IAAI;YACJlE,QAAQ;YACRE,OAAOb,sBACL4E,QAAQnE,IAAI,EACZ;QAEJ;IACF;IACA,MAAM8C,SAA4B;QAChCM;OACIC,aAAa;QAAEA;IAAW,IAAI,CAAC;QACnC8B,kBAAkBZ,SAASW,UAAU;OACjCf,QAAQnE,IAAI,CAACoF,WAAW,GAAG;QAAE9B,YAAYhD,OAAO6D,QAAQnE,IAAI,CAACoF,WAAW;IAAE,IAAI,CAAC,GAC/EjB,QAAQnE,IAAI,CAACqF,aAAa,GAAG;QAAE9B,cAAcjD,OAAO6D,QAAQnE,IAAI,CAACqF,aAAa;IAAE,IAAI,CAAC;QACzFnF,QAAQI,QAAO6D,uBAAAA,QAAQnE,IAAI,CAACE,MAAM,YAAnBiE,uBAAuB;QACtCX,UAAUL,QAAQgB,QAAQnE,IAAI,CAACwD,QAAQ;QACvC8B,aAAaC,KAAKC,GAAG;QACrBC,WAAWxB,MAAMrC,GAAG;;IAEtB,MAAMc,KAAKpC,OAAO6D,QAAQnE,IAAI,CAAC0C,EAAE;IACjC,MAAMZ,WAAWmC,MAAM5D,MAAM,EAAE6B,GAAG,CAACQ,IAAIgD,GAAG,CAAC5C;IAC3C,MAAM6C,aAAa1B,MAAM5D,MAAM,EAAE4D,MAAMH,KAAK;IAC5C,IAAIhB,OAAOS,YAAY,IAAIpE,+BAA+BoC,QAAQC,GAAG,GAAG;QACtE,IAAI;YACF,MAAM,AAAC,CAAA,MAAM,MAAM,CAAC,4BAAwB,EAAGoE,gCAAgC,CAAC;gBAC9EvF,QAAQ4D,MAAM5D,MAAM;gBACpByD,OAAOG,MAAMH,KAAK;gBAClBlC,KAAKqC,MAAMrC,GAAG;gBACdiE,UAAUnD;gBACVa,cAAcT,OAAOS,YAAY;YACnC;QACF,EAAE,OAAOnD,OAAO;YACdc,QAAQd,KAAK,CAAC,oDAAoDsC,IAAItC;QACxE;IACF;IACA,OAAO;QAAEgE,IAAI;QAAM1B;QAAII;IAAO;AAChC;AAEA,eAAejC,aACbH,KAAe,EACfV,IAAyB,EACzBD,GAAoC;QAkB4BC;IAhBhE,MAAM8C,SAAS,MAAMnD,oBAAoBe,MAAML,MAAM,EAAEL,IAAI,CAAC,WAAW;IACvE,IAAI,CAAC8C,QAAQ,OAAO/C,IAAIG,MAAM,CAAC,KAAKC,IAAI,CAAC;QAAEC,OAAO;IAAwC;IAC1F,MAAM0F,QAAiC,CAAC;IACxC,IAAI,OAAO9F,IAAI,CAAC,QAAQ,KAAK,UAAU;QACrC8F,KAAK,CAAC,QAAQ,GAAG9F,IAAI,CAAC,QAAQ,CAACqE,IAAI,GAAGC,KAAK,CAAC,GAAG,OAAOxB,OAAOM,KAAK;IACpE;IACA,IAAI,gBAAgBpD,MAAM;YACEA;QAA1B,MAAMqD,aAAa/C,QAAON,oBAAAA,IAAI,CAAC,aAAa,YAAlBA,oBAAsB;QAChD,IAAIqD,cAAc,CAAE,MAAMI,eAAe/C,MAAML,MAAM,EAAEgD,aAAc;YACnE,OAAOtD,IAAIG,MAAM,CAAC,KAAKC,IAAI,CAAC;gBAAEC,OAAO;YAAmB;QAC1D;QACA0F,KAAK,CAAC,aAAa,GAAGzC,cAActE,cAAciD,SAAS,CAAC+D,UAAU,CAACC,MAAM;IAC/E;IACA,MAAMC,UAAU,MAAM3G,UAAU,QAAQ,CAAC,iBAAiB,EAAEwD,OAAOJ,EAAE,EAAE,EAAE;QACvEsC,QAAQ,aACFc,KAAK,CAAC,QAAQ,GAAG;YAAE1C,OAAO9C,OAAOwF,KAAK,CAAC,QAAQ;QAAE,IAAI,CAAC,GACtD,gBAAgB9F,OAAO;YAAE,wBAAwBM,QAAON,mBAAAA,IAAI,CAAC,aAAa,YAAlBA,mBAAsB;QAAI,IAAI,CAAC;IAE/F;IACA,IAAI,CAACiG,QAAQ7B,EAAE,EAAE;QACf,OAAOrE,IAAIG,MAAM,CAAC,KAAKC,IAAI,CAAC;YAAEC,OAAOb,sBAAsB0G,QAAQjG,IAAI,EAAE;QAAoC;IAC/G;IACA,MAAM8B,WAAWpB,MAAML,MAAM,EAAE6B,GAAG,CAACY,OAAOJ,EAAE,EAAEgD,GAAG,CAACI,OAAO;QAAEI,OAAO;IAAK;IACvE,OAAOnG,IAAIG,MAAM,CAAC,KAAKC,IAAI,CAAC;QAAEiE,IAAI;IAAK;AACzC;AAEA,eAAetD,aACbJ,KAAe,EACfV,IAAyB,EACzBD,GAAoC;IAEpC,MAAM+C,SAAS,MAAMnD,oBAAoBe,MAAML,MAAM,EAAEL,IAAI,CAAC,WAAW;IACvE,IAAI,CAAC8C,QAAQ,OAAO/C,IAAIG,MAAM,CAAC,KAAKC,IAAI,CAAC;QAAEC,OAAO;IAAwC;IAC1F,MAAM+F,UAAU,MAAM7G,UAAU,UAAU,CAAC,iBAAiB,EAAEwD,OAAOJ,EAAE,EAAE;IACzE,yEAAyE;IACzE,IAAI,CAACyD,QAAQ/B,EAAE,IAAI+B,QAAQjG,MAAM,KAAK,KAAK;QACzC,OAAOH,IAAIG,MAAM,CAAC,KAAKC,IAAI,CAAC;YAAEC,OAAOb,sBAAsB4G,QAAQnG,IAAI,EAAE;QAAoC;IAC/G;IACA,MAAM8B,WAAWpB,MAAML,MAAM,EAAE6B,GAAG,CAACY,OAAOJ,EAAE,EAAEsD,MAAM;IACpD,MAAML,aAAajF,MAAML,MAAM,EAAEK,MAAMoD,KAAK;IAC5C,OAAO/D,IAAIG,MAAM,CAAC,KAAKC,IAAI,CAAC;QAAEiE,IAAI;IAAK;AACzC;AAEA;;;;CAIC,GACD,eAAeuB,aAAatF,MAAc,EAAEyD,KAAa;IACvD,IAAI;QACF,MAAM,AAAC,CAAA,MAAM,MAAM,CAAC,oBAAgB,EAAGsC,sBAAsB,CAAC;YAAE/F;YAAQyD;QAAM;IAChF,EAAE,OAAO1D,OAAO;QACdc,QAAQd,KAAK,CAAC,+CAA+CC,QAAQD;IACvE;AACF;AAEA;;;;;;CAMC,GACD,eAAeW,eACbL,KAAe,EACfV,IAAyB,EACzBD,GAAoC;QAEVC;IAA1B,MAAMqD,aAAa/C,QAAON,mBAAAA,IAAI,CAAC,aAAa,YAAlBA,mBAAsB;IAChD,IAAI,CAAE,MAAMyD,eAAe/C,MAAML,MAAM,EAAEgD,aAAc;QACrD,OAAOtD,IAAIG,MAAM,CAAC,KAAKC,IAAI,CAAC;YAAEC,OAAO;QAAmB;IAC1D;IACA,MAAM4B,YAAYjD,cAAcgD,GAAG,GAAGC,SAAS;IAC/C,MAAMqE,cAAcrE,UACjBC,UAAU,CAAC,SACXC,GAAG,CAACxB,MAAML,MAAM,EAChB4B,UAAU,CAAC,aACXC,GAAG,CAACmB;IACP,MAAMnE,kBAAkBwB,MAAML,MAAM,EAAEgD;IACtC,MAAMgD,YAAYL,MAAM;IACxB,MAAMM,QAAQ,MAAMxE,WAAWpB,MAAML,MAAM,EAAEkG,KAAK,CAAC,cAAc,MAAMlD,YAAYf,KAAK,CAAC,IAAIC,GAAG;IAChG,MAAMK,QAAQC,GAAG,CACfyD,MAAM9D,IAAI,CAACC,GAAG,CAAC,CAACP,MACdA,IAAIsE,GAAG,CAACd,GAAG,CAAC;YAAErC,YAAYtE,cAAciD,SAAS,CAAC+D,UAAU,CAACC,MAAM;QAAG,GAAG;YAAEE,OAAO;QAAK;IAG3F,OAAOnG,IAAIG,MAAM,CAAC,KAAKC,IAAI,CAAC;QAAEiE,IAAI;IAAK;AACzC"}
@@ -34,6 +34,16 @@ export interface PosReturnSideEffects {
34
34
  lineIndexes: number[];
35
35
  /** The lines this return finished taking back in full. */
36
36
  fullLineIndexes: number[];
37
+ /**
38
+ * Each line taken back, with its units and its share of the refund, for
39
+ * whatever follows a line in particular — a card reader sold in person,
40
+ * whose hardware order is told (AGL-4038).
41
+ */
42
+ lines?: Array<{
43
+ index: number;
44
+ quantity: number;
45
+ refundCents: number;
46
+ }>;
37
47
  }
38
48
  export interface PosReturnDeps extends PosOpsDeps {
39
49
  /** What every refund tells the rest of the workspace, after the money moved. Never throws. */
@@ -29,10 +29,12 @@ import { notifyOrderBuyer } from "./order-notifications.js";
29
29
  import { decidePosRefundAuthority } from "./pos-refund-authority.js";
30
30
  import { authorizePosOps, defaultPosOpsDeps, posOpsBody, posOpsCleanId, posOpsIdempotencyKey, readPosRegister, isPosManager, resolvePosCashier } from "./pos-ops-gate.js";
31
31
  import { createStripeRefund } from "./stripe-refund.js";
32
+ import { parsePosHardwareInPersonConfig } from "../model/pos-hardware.js";
32
33
  export function defaultPosReturnDeps() {
33
34
  const base = defaultPosOpsDeps();
34
35
  return _extends({}, base, {
35
36
  afterRefund: async (input)=>{
37
+ var _input_lines, _parsePosHardwareInPersonConfig;
36
38
  const settle = async (label, work)=>{
37
39
  try {
38
40
  await work();
@@ -102,6 +104,22 @@ export function defaultPosReturnDeps() {
102
104
  }
103
105
  });
104
106
  });
107
+ // A card reader the platform's own store sold in person (AGL-4038):
108
+ // its hardware order and retained sale record take the return too.
109
+ // Answered from the environment for every other store.
110
+ if (((_input_lines = input.lines) == null ? void 0 : _input_lines.length) && ((_parsePosHardwareInPersonConfig = parsePosHardwareInPersonConfig(process.env)) == null ? void 0 : _parsePosHardwareInPersonConfig.sellerHostId) === input.hostId) {
111
+ await settle('hardware return', async ()=>{
112
+ var _input_lines;
113
+ return (await import("./pos-hardware-returns.js")).recordRegisterHardwareReturn({
114
+ config: parsePosHardwareInPersonConfig(process.env),
115
+ hostId: input.hostId,
116
+ registerOrderId: input.orderId,
117
+ returnId: input.returnId,
118
+ refundCents: input.refundCents,
119
+ lines: (_input_lines = input.lines) != null ? _input_lines : []
120
+ });
121
+ });
122
+ }
105
123
  await settle('buyer notice', ()=>notifyOrderBuyer({
106
124
  hostId: input.hostId,
107
125
  orderId: input.orderId
@@ -222,7 +240,9 @@ export async function handlePosReturn(deps, req) {
222
240
  }
223
241
  };
224
242
  const body = posOpsBody(req);
225
- const gate = await authorizePosOps(deps, req, body['hostId']);
243
+ // Finding a sale to take back and refunding it are both the refund key's
244
+ // (AGL-4047).
245
+ const gate = await authorizePosOps(deps, req, body['hostId'], 'posRefund');
226
246
  if ('error' in gate) return {
227
247
  status: gate.status,
228
248
  body: {
@@ -726,6 +746,11 @@ export async function handlePosReturn(deps, req) {
726
746
  ],
727
747
  lineIndexes: picks.map((pick)=>pick.index),
728
748
  fullLineIndexes: reserved.completedLines,
749
+ lines: lines.map((line)=>({
750
+ index: line.index,
751
+ quantity: line.quantity,
752
+ refundCents: line.refundCents
753
+ })),
729
754
  returnId,
730
755
  storeReturn: storeReturn,
731
756
  refundIds: results.flatMap((result)=>result.refundId ? [