@asteby/storefront-react 0.28.0 → 0.28.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/payments.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { isSafeCssValue } from './chunk-672OTUM2.js';
2
2
  import { useModalDialog } from './chunk-ZBH7JYU4.js';
3
3
  import { findBrand, BrandMark } from './chunk-JNUJGPJC.js';
4
- import { paymentRecoveryMessages } from './chunk-MNLROALF.js';
5
- export { buildPayChoices, cashProviderData, checkoutToAttempt, choiceValue, parseChoice, payErrorResponse, paymentCsp, paymentCspHeaderName, paymentCspHeaders, paymentCspMode, paymentNonce, paymentNonceFromHeaders, paymentRecoveryMessages, safeHttpStatus, voucherRows } from './chunk-MNLROALF.js';
4
+ import { paymentRecoveryMessages } from './chunk-4DZW3R33.js';
5
+ export { buildPayChoices, cashProviderData, checkoutToAttempt, choiceValue, parseChoice, payErrorResponse, paymentCsp, paymentCspHeaderName, paymentCspHeaders, paymentCspMode, paymentNonce, paymentNonceFromHeaders, paymentRecoveryMessages, safeHttpStatus, voucherRows } from './chunk-4DZW3R33.js';
6
6
  import { useResolvedLocale } from './chunk-T52H5HL3.js';
7
7
  import './chunk-DQBL2DFJ.js';
8
8
  import { forwardRef, useImperativeHandle, useRef, useEffect, useMemo, useId, useState, useCallback, useSyncExternalStore } from 'react';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asteby/storefront-react",
3
- "version": "0.28.0",
3
+ "version": "0.28.1",
4
4
  "description": "React bindings for @asteby/storefront — SSR-safe provider, optimistic cart, Money, responsive Image, prices, variant selection, SEO meta and JSON-LD, section registry and server-rendered theme CSS.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -184,7 +184,7 @@
184
184
  "react": "^19.0.0"
185
185
  },
186
186
  "dependencies": {
187
- "@asteby/storefront": "0.18.0"
187
+ "@asteby/storefront": "0.18.1"
188
188
  },
189
189
  "devDependencies": {
190
190
  "@testing-library/react": "^16.3.2",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/payments/recovery-messages.ts","../src/payments/csp.ts","../src/payments/choices.ts"],"names":[],"mappings":";;;AA+BA,IAAM,EAAA,GAA8B;AAAA,EAClC,iBAAA,EAAmB,mGAAA;AAAA,EACnB,mBAAA,EAAqB,2FAAA;AAAA,EACrB,oBAAA,EAAsB,gFAAA;AAAA,EACtB,uBAAA,EAAyB,gHAAA;AAAA,EACzB,yBAAA,EAA2B,wHAAA;AAAA,EAC3B,sBAAA,EAAwB,2GAAA;AAAA,EACxB,eAAA,EAAiB,oDAAA;AAAA,EACjB,sBAAA,EAAwB,6DAAA;AAAA,EACxB,oBAAA,EAAsB,oEAAA;AAAA,EACtB,kBAAA,EAAoB,+BAAA;AAAA,EACpB,aAAA,EAAe,gDAAA;AAAA,EACf,yBAAA,EAA2B,mCAAA;AAAA,EAC3B,wBAAA,EAA0B,sGAAA;AAAA,EAC1B,0BAAA,EAA4B,4CAAA;AAAA,EAC5B,yBAAA,EAA2B,+EAAA;AAAA,EAC3B,uBAAA,EAAyB,4BAAA;AAAA,EACzB,sBAAA,EAAwB,2FAAA;AAAA,EACxB,gCAAA,EAAkC,6CAAA;AAAA,EAClC,+BAAA,EAAiC,kGAAA;AAAA,EACjC,8BAAA,EAAgC,yCAAA;AAAA,EAChC,6BAAA,EAA+B,2FAAA;AAAA,EAC/B,6BAAA,EAA+B,kCAAA;AAAA,EAC/B,4BAAA,EAA8B,8GAAA;AAAA,EAC9B,oBAAA,EAAsB,6BAAA;AAAA,EACtB,mBAAA,EAAqB,+DAAA;AAAA,EACrB,cAAA,EAAgB,iBAAA;AAAA,EAChB,mBAAA,EAAqB,YAAA;AAAA,EACrB,gBAAA,EAAkB,sBAAA;AAAA,EAClB,oBAAA,EAAsB;AACxB,CAAA;AAEA,IAAM,EAAA,GAA8B;AAAA,EAClC,iBAAA,EAAmB,0GAAA;AAAA,EACnB,mBAAA,EAAqB,uFAAA;AAAA,EACrB,oBAAA,EAAsB,+DAAA;AAAA,EACtB,uBAAA,EAAyB,oGAAA;AAAA,EACzB,yBAAA,EAA2B,iHAAA;AAAA,EAC3B,sBAAA,EAAwB,uGAAA;AAAA,EACxB,eAAA,EAAiB,uCAAA;AAAA,EACjB,sBAAA,EAAwB,uDAAA;AAAA,EACxB,oBAAA,EAAsB,0DAAA;AAAA,EACtB,kBAAA,EAAoB,6BAAA;AAAA,EACpB,aAAA,EAAe,8CAAA;AAAA,EACf,yBAAA,EAA2B,qCAAA;AAAA,EAC3B,wBAAA,EAA0B,4FAAA;AAAA,EAC1B,0BAAA,EAA4B,gCAAA;AAAA,EAC5B,yBAAA,EAA2B,8DAAA;AAAA,EAC3B,uBAAA,EAAyB,8BAAA;AAAA,EACzB,sBAAA,EAAwB,sEAAA;AAAA,EACxB,gCAAA,EAAkC,iDAAA;AAAA,EAClC,+BAAA,EAAiC,wEAAA;AAAA,EACjC,8BAAA,EAAgC,iCAAA;AAAA,EAChC,6BAAA,EAA+B,+EAAA;AAAA,EAC/B,6BAAA,EAA+B,kCAAA;AAAA,EAC/B,4BAAA,EAA8B,2GAAA;AAAA,EAC9B,oBAAA,EAAsB,kCAAA;AAAA,EACtB,mBAAA,EAAqB,yDAAA;AAAA,EACrB,cAAA,EAAgB,eAAA;AAAA,EAChB,mBAAA,EAAqB,OAAA;AAAA,EACrB,gBAAA,EAAkB,kBAAA;AAAA,EAClB,oBAAA,EAAsB;AACxB,CAAA;AAGO,SAAS,uBAAA,CAAwB,QAAwB,SAAA,EAA8E;AAC5I,EAAA,MAAM,IAAA,GAAA,CAAQ,UAAU,OAAA,EAAS,WAAA,GAAc,UAAA,CAAW,IAAI,IAAI,EAAA,GAAK,EAAA;AACvE,EAAA,OAAO,YAAY,EAAE,GAAG,IAAA,EAAM,GAAG,WAAU,GAAI,IAAA;AACjD;;;ACnFA,IAAM,MAAA,GAAS,gGAAA;AAEf,SAAS,WAAW,KAAA,EAAoD;AACtE,EAAA,MAAM,GAAA,uBAAU,GAAA,EAAY;AAC5B,EAAA,KAAA,MAAW,IAAA,IAAQ,KAAA,EAAO,KAAA,MAAW,CAAA,IAAK,QAAQ,EAAC,EAAG,IAAI,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,EAAG,GAAA,CAAI,IAAI,CAAC,CAAA;AACnF,EAAA,OAAO,CAAC,GAAG,GAAG,CAAA;AAChB;AASO,SAAS,UAAA,CAAW,OAAA,EAAwD,OAAA,GAA6B,EAAC,EAAW;AAC1H,EAAA,MAAM,OAAO,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAA0B,CAAC,CAAC,CAAC,CAAA;AAC1D,EAAA,MAAM,IAAA,GAAO,CAAC,CAAA,KAA+C,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,GAAA,GAAM,CAAC,CAAC,CAAA;AACvF,EAAA,MAAM,KAAA,GAAQ,QAAQ,KAAA,IAAS,qBAAA,CAAsB,KAAK,OAAA,CAAQ,KAAK,CAAA,GAAI,OAAA,CAAQ,KAAA,GAAQ,MAAA;AAC3F,EAAA,MAAM,UAAA,GAAa,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAA,KAAM;AACrC,IAAA,IAAI;AACF,MAAA,MAAM,CAAA,GAAI,IAAI,GAAA,CAAI,CAAA,CAAE,OAAO,CAAA;AAC3B,MAAA,OAAO,EAAE,QAAA,KAAa,QAAA,GAAW,CAAC,CAAA,CAAE,MAAM,IAAI,EAAC;AAAA,IACjD,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,EAAC;AAAA,IACV;AAAA,EACF,CAAC,CAAA;AACD,EAAA,MAAM,GAAA,GAAM,CAAC,IAAA,EAAc,MAAA,KAAqB,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,MAAA,CAAO,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA;AAC3E,EAAA,MAAM,KAAA,GAAQ;AAAA,IACZ,oBAAA;AAAA,IACA,IAAI,YAAA,EAAc,CAAC,QAAA,EAAU,GAAA,CAAI,QAAQ,YAAA,IAAgB,EAAC,EAAG,MAAA,CAAO,CAAC,CAAA,KAAM,sCAAA,CAAuC,IAAA,CAAK,CAAC,CAAC,CAAA,EAAG,GAAI,KAAA,GAAQ,CAAC,UAAU,KAAK,CAAA,CAAA,CAAG,CAAA,GAAI,IAAK,GAAG,OAAA,CAAQ,UAAA,EAAY,GAAG,KAAK,QAAQ,CAAA,EAAG,QAAQ,KAAA,EAAO,MAAM,CAAC,CAAC,CAAA;AAAA,IACrO,GAAA,CAAI,aAAa,OAAA,CAAQ,GAAG,KAAK,OAAO,CAAA,EAAG,OAAA,CAAQ,KAAA,EAAO,KAAK,CAAA,CAAE,SAAS,OAAA,CAAQ,GAAG,IAAA,CAAK,OAAO,CAAA,EAAG,OAAA,CAAQ,OAAO,KAAK,CAAA,GAAI,CAAC,QAAQ,CAAC,CAAA;AAAA,IACtI,GAAA,CAAI,aAAA,EAAe,CAAC,QAAA,EAAU,GAAG,OAAA,CAAQ,GAAG,IAAA,CAAK,SAAS,CAAA,EAAG,OAAA,CAAQ,KAAA,EAAO,OAAO,CAAC,CAAC,CAAA;AAAA,IACrF,GAAA,CAAI,WAAW,CAAC,QAAA,EAAU,SAAS,GAAI,OAAA,CAAQ,QAAA,GAAW,CAAC,QAAQ,CAAA,GAAI,EAAC,EAAI,GAAG,OAAA,CAAQ,GAAG,IAAA,CAAK,KAAK,GAAG,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAC,CAAC,CAAA;AAAA,IAC3H,kCAAA;AAAA,IACA,GAAA,CAAI,aAAA,EAAe,CAAC,QAAA,EAAU,GAAG,OAAA,CAAQ,GAAG,IAAA,CAAK,MAAM,CAAA,EAAG,OAAA,CAAQ,KAAA,EAAO,IAAI,CAAC,CAAC,CAAA;AAAA,IAC/E,wBAAA;AAAA,IACA,iBAAA;AAAA,IACA;AAAA,GACF;AACA,EAAA,IAAI,OAAA,CAAQ,SAAA,IAAa,2BAAA,CAA4B,IAAA,CAAK,OAAA,CAAQ,SAAS,CAAA,EAAG,KAAA,CAAM,IAAA,CAAK,CAAA,WAAA,EAAc,OAAA,CAAQ,SAAS,CAAA,CAAE,CAAA;AAC1H,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB;AAGO,SAAS,qBAAqB,UAAA,EAA6B;AAChE,EAAA,OAAO,aAAa,qCAAA,GAAwC,yBAAA;AAC9D;AAKO,SAAS,cAAA,CAAe,OAAkC,UAAA,EAAqC;AACpG,EAAA,MAAM,GAAA,GAAA,CAAO,KAAA,IAAS,EAAA,EAAI,IAAA,GAAO,WAAA,EAAY;AAC7C,EAAA,IAAI,QAAQ,KAAA,IAAS,GAAA,KAAQ,aAAA,IAAiB,GAAA,KAAQ,WAAW,OAAO,GAAA;AACxE,EAAA,OAAO,aAAa,aAAA,GAAgB,KAAA;AACtC;AAGO,SAAS,YAAA,GAAuB;AACrC,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,EAAE,CAAA;AAC/B,EAAA,MAAA,CAAO,gBAAgB,KAAK,CAAA;AAC5B,EAAA,IAAI,GAAA,GAAM,EAAA;AACV,EAAA,KAAA,MAAW,CAAA,IAAK,KAAA,EAAO,GAAA,IAAO,MAAA,CAAO,aAAa,CAAC,CAAA;AACnD,EAAA,OAAO,KAAK,GAAG,CAAA;AACjB;AAGO,SAAS,iBAAA,CACd,SACA,OAAA,EACwB;AACxB,EAAA,IAAI,OAAA,CAAQ,IAAA,KAAS,KAAA,EAAO,OAAO,EAAC;AACpC,EAAA,OAAO,EAAE,CAAC,oBAAA,CAAqB,OAAA,CAAQ,IAAA,KAAS,aAAa,CAAC,GAAG,UAAA,CAAW,OAAA,EAAS,OAAO,CAAA,EAAE;AAChG;AAGO,SAAS,wBAAwB,OAAA,EAAsC;AAC5E,EAAA,MAAM,GAAA,GAAM,QAAQ,GAAA,CAAI,yBAAyB,KAAK,OAAA,CAAQ,GAAA,CAAI,qCAAqC,CAAA,IAAK,EAAA;AAC5G,EAAA,OAAO,6BAAA,CAA8B,IAAA,CAAK,GAAG,CAAA,GAAI,CAAC,CAAA;AACpD;AC7CA,IAAM,GAAA,GAAM,GAAA;AAEL,SAAS,WAAA,CAAY,WAAmB,MAAA,EAAyC;AACtF,EAAA,OAAO,SAAS,CAAA,EAAG,SAAS,GAAG,GAAG,CAAA,EAAG,MAAM,CAAA,CAAA,GAAK,SAAA;AAClD;AAGO,SAAS,YAAY,KAAA,EAAiG;AAC3H,EAAA,MAAM,GAAA,GAAA,CAAO,KAAA,IAAS,EAAA,EAAI,IAAA,EAAK;AAC/B,EAAA,IAAI,CAAC,KAAK,OAAO,IAAA;AACjB,EAAA,MAAM,CAAA,GAAI,GAAA,CAAI,WAAA,CAAY,GAAG,CAAA;AAC7B,EAAA,IAAI,MAAM,EAAA,EAAI,OAAO,EAAE,SAAA,EAAW,GAAA,EAAK,QAAQ,IAAA,EAAK;AACpD,EAAA,MAAM,MAAA,GAAS,GAAA,CAAI,KAAA,CAAM,CAAA,GAAI,CAAC,CAAA;AAC9B,EAAA,IAAI,MAAA,KAAW,UAAU,MAAA,KAAW,MAAA,IAAU,WAAW,QAAA,IAAY,MAAA,KAAW,WAAW,OAAO,IAAA;AAClG,EAAA,OAAO,EAAE,SAAA,EAAW,GAAA,CAAI,MAAM,CAAA,EAAG,CAAC,GAAG,MAAA,EAAO;AAC9C;AAEA,SAAS,OAAO,MAAA,EAA0C;AACxD,EAAA,IAAI,MAAA,CAAO,YAAY,MAAA,CAAO,GAAA,KAAQ,YAAY,MAAA,CAAO,GAAA,KAAQ,WAAW,OAAO,UAAA;AACnF,EAAA,OAAO,MAAA,CAAO,GAAA,KAAQ,MAAA,GAAS,MAAA,GAAS,MAAA;AAC1C;AAMO,SAAS,eAAA,CAAgB,OAAA,EAAmC,OAAA,GAAkC,EAAC,EAAe;AACnH,EAAA,MAAM,SAAS,IAAI,GAAA,CAAI,OAAA,CAAQ,IAAA,IAAQ,EAAE,CAAA;AACzC,EAAA,MAAM,UAAuB,EAAC;AAC9B,EAAA,IAAI,UAAA,GAAmC,IAAA;AACvC,EAAA,IAAI,YAAA,GAA8B,IAAA;AAClC,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,IAAI,MAAA,CAAO,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,EAAG;AAC5B,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,OAAA,IAAW,EAAC;AAChC,IAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,MAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,MAAA,CAAO,GAAA,EAAK,IAAI,CAAA;AAC1C,MAAA,OAAA,CAAQ,KAAK,EAAE,KAAA,EAAO,SAAA,EAAW,MAAA,CAAO,KAAK,MAAA,EAAQ,IAAA,EAAM,IAAA,EAAM,OAAA,EAAS,OAAO,IAAA,EAAM,MAAA,EAAQ,EAAC,EAAG,eAAA,EAAiB,MAAM,CAAA;AAC1H,MAAA,IAAI,MAAA,CAAO,OAAA,IAAW,CAAC,YAAA,EAAc,YAAA,GAAe,KAAA;AACpD,MAAA;AAAA,IACF;AACA,IAAA,IAAA,CAAK,OAAA,CAAQ,CAAC,MAAA,EAAQ,CAAA,KAAM;AAC1B,MAAA,MAAM,IAAA,GAAO,OAAO,MAAM,CAAA;AAC1B,MAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,MAAA,CAAO,GAAA,EAAK,OAAO,GAAG,CAAA;AAChD,MAAA,OAAA,CAAQ,IAAA,CAAK;AAAA,QACX,KAAA;AAAA,QACA,WAAW,MAAA,CAAO,GAAA;AAAA,QAClB,QAAQ,MAAA,CAAO,GAAA;AAAA,QACf,IAAA;AAAA,QACA,KAAA,EAAO,MAAA,CAAO,KAAA,EAAO,IAAA,EAAK,IAAK,IAAA;AAAA,QAC/B,MAAA,EAAQ,OAAO,GAAA,KAAQ,MAAA,GAAU,OAAO,MAAA,IAAU,KAAM,EAAC;AAAA,QACzD,eAAA,EAAiB,OAAO,gBAAA,IAAoB;AAAA,OAC7C,CAAA;AACD,MAAA,IAAI,SAAS,MAAA,IAAU,MAAA,CAAO,UAAU,CAAC,UAAA,eAAyB,MAAA,CAAO,MAAA;AACzE,MAAA,IAAI,OAAO,OAAA,IAAW,CAAA,KAAM,CAAA,IAAK,CAAC,cAAc,YAAA,GAAe,KAAA;AAAA,IACjE,CAAC,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,SAAS,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAA,KAAO,EAAE,IAAA,KAAS,MAAA,IAAU,CAAC,UAAA,GAAa,EAAE,GAAG,CAAA,EAAG,IAAA,EAAM,UAAA,KAAwB,CAAE,CAAA;AAC9G,EAAA,OAAO,EAAE,OAAA,EAAS,MAAA,EAAQ,UAAA,EAAY,YAAA,EAAc,gBAAgB,MAAA,CAAO,CAAC,CAAA,EAAG,KAAA,IAAS,IAAA,EAAK;AAC/F;AAGO,SAAS,gBAAA,CAAiB,QAAiC,OAAA,EAAmE;AACnI,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,OAAO,CAAA,KAAM,OAAA,GAAU,IAAA,GAAO,MAAA,CAAO,CAAC,CAAA,CAAA;AAChF,EAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AACnB,EAAA,OAAO;AAAA,IACL,mBAAmB,KAAA,CAAM,iBAAA;AAAA,IACzB,GAAI,MAAM,aAAA,GAAgB,EAAE,eAAe,KAAA,CAAM,aAAA,KAAkB;AAAC,GACtE;AACF;AAMO,SAAS,kBAAkB,MAAA,EAA8C;AAC9E,EAAA,MAAM,EAAE,QAAA,EAAU,OAAA,EAAS,KAAA,EAAM,GAAI,MAAA;AACrC,EAAA,MAAM,MAAA,GAAS,QAAQ,MAAA,IAAU,IAAA;AACjC,EAAA,MAAM,IAAA,GAAO,EAAE,QAAA,EAAU,GAAI,QAAQ,EAAE,KAAA,EAAM,GAAI,EAAC,EAAG;AACrD,EAAA,MAAM,MAAA,GAAA,CAAU,QAAA,CAAS,MAAA,IAAU,EAAA,EAAI,WAAA,EAAY;AACnD,EAAA,IAAI,WAAW,MAAA,IAAU,MAAA,KAAW,WAAA,EAAa,OAAO,EAAE,GAAG,IAAA,EAAM,OAAA,EAAS,EAAE,UAAU,OAAA,CAAQ,QAAA,EAAU,QAAQ,MAAA,EAAQ,OAAA,EAAS,YAAW,EAAE;AAChJ,EAAA,IAAI,MAAA,KAAW,WAAA,IAAe,MAAA,KAAW,UAAA,SAAmB,EAAE,GAAG,IAAA,EAAM,OAAA,EAAS,EAAE,QAAA,EAAU,OAAA,CAAQ,QAAA,EAAU,MAAA,EAAQ,aAAY,EAAE;AACpI,EAAA,IAAI,MAAA,KAAW,SAAA,EAAW,OAAO,EAAE,GAAG,IAAA,EAAM,OAAA,EAAS,EAAE,QAAA,EAAU,OAAA,CAAQ,QAAA,EAAU,MAAA,EAAQ,WAAU,EAAE;AACvG,EAAA,IAAI,WAAW,QAAA,EAAU;AACvB,IAAA,MAAM,OAAA,GAAW,QAA+E,YAAA,IAAgB,UAAA;AAChH,IAAA,OAAO,EAAE,GAAG,IAAA,EAAM,OAAA,EAAS,EAAE,UAAU,OAAA,CAAQ,QAAA,EAAU,MAAA,EAAQ,QAAA,EAAU,SAAS,UAAA,EAAY,YAAA,EAAc,OAAA,EAAS,SAAA,EAAW,MAAK,EAAE;AAAA,EAC3I;AAEA,EAAA,IAAI,QAAQ,IAAA,KAAS,WAAA,EAAa,OAAO,EAAE,GAAG,IAAA,EAAM,OAAA,EAAS,EAAE,QAAA,EAAU,QAAQ,QAAA,EAAU,MAAA,EAAQ,mBAAmB,OAAA,EAAS,WAAA,EAAa,QAAO,EAAE;AACrJ,EAAA,OAAO,EAAE,GAAG,IAAA,EAAM,SAAS,EAAE,QAAA,EAAU,QAAQ,QAAA,EAAU,MAAA,EAAQ,SAAA,EAAW,OAAA,EAAS,WAAW,MAAA,EAAQ,MAAA,IAAU,EAAE,IAAA,EAAM,MAAA,IAAS,EAAE;AACvI;AAqCO,SAAS,eAAe,MAAA,EAAwB;AACrD,EAAA,OAAO,WAAW,GAAA,IAAO,MAAA,KAAW,GAAA,IAAO,MAAA,KAAW,MAAM,GAAA,GAAM,MAAA;AACpE;AAOO,SAAS,gBAAA,CAAiB,GAAA,EAAgB,OAAA,GAA2B,EAAC,EAA2C;AACtH,EAAA,MAAM,MAAA,GAAS,OAAO,GAAA,CAAI,MAAA,KAAW,YAAY,GAAA,CAAI,MAAA,IAAU,GAAA,GAAM,GAAA,CAAI,MAAA,GAAS,GAAA;AAClF,EAAA,MAAM,EAAE,IAAA,EAAM,UAAA,EAAY,SAAA,KAAc,oBAAA,CAAqB,EAAE,GAAG,GAAA,EAAK,MAAA,EAAQ,UAAA,EAAY,GAAA,CAAI,UAAA,IAAc,MAAM,CAAA;AACnH,EAAA,MAAM,IAAA,GAAO,QAAQ,IAAA,IAAQ,UAAA;AAC7B,EAAA,IAAI,IAAA,GAAO,GAAA,CAAI,IAAA,KAAS,IAAA,KAAS,cAAc,aAAA,GAAgB,cAAA,CAAA;AAC/D,EAAA,IAAI,MAAA,KAAW,GAAA,IAAO,GAAA,CAAI,KAAA,KAAU,uBAAuB,IAAA,GAAO,qBAAA;AAClE,EAAA,IAAI,MAAA,KAAW,KAAK,IAAA,GAAO,mBAAA;AAC3B,EAAA,IAAI,MAAA,KAAW,GAAA,IAAO,GAAA,CAAI,KAAA,KAAU,kBAAkB,IAAA,GAAO,gBAAA;AAG7D,EAAA,MAAM,GAAA,GAAA,CAAO,OAAA,CAAQ,UAAA,IAAc,IAAA,KAAS,YAAA,IAAgB,IAAA,KAAS,SAAA,IAAa,IAAA,KAAS,gBAAA,IAAqB,IAAA,KAAS,OAAA,IAAW,MAAA,GAAS,QAAS,GAAA,CAAI,OAAA;AAC1J,EAAA,MAAM,OAAA,GAAU,GAAA,IAAO,uBAAA,CAAwB,OAAA,CAAQ,MAAA,EAAQ,QAAQ,QAAQ,CAAA,CAAE,CAAA,MAAA,EAAS,IAAI,CAAA,CAAE,CAAA;AAChG,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,eAAe,MAAM,CAAA;AAAA,IAC7B,IAAA,EAAM;AAAA,MACJ,KAAA,EAAO;AAAA,QACL,IAAA;AAAA,QACA,OAAA;AAAA,QACA,SAAA,EAAW,OAAA,CAAQ,IAAA,GAAO,OAAA,CAAQ,IAAA,KAAS,WAAA,IAAe,OAAA,CAAQ,IAAA,KAAS,aAAA,IAAiB,OAAA,CAAQ,IAAA,KAAS,cAAA,GAAiB,SAAA;AAAA,QAC9H,IAAA;AAAA,QACA,GAAI,IAAI,KAAA,GAAQ,EAAE,OAAO,GAAA,CAAI,KAAA,KAAU,EAAC;AAAA,QACxC,GAAI,IAAI,UAAA,GAAa,EAAE,aAAa,GAAA,CAAI,UAAA,KAAe,EAAC;AAAA,QACxD,GAAI,IAAI,OAAA,KAAY,MAAA,GAAY,EAAE,OAAA,EAAS,GAAA,CAAI,OAAA,EAAQ,GAAI;AAAC;AAC9D;AACF,GACF;AACF;AAKO,SAAS,WAAA,CACd,OAAA,EACA,MAAA,EACA,MAAA,EACkC;AAClC,EAAA,IAAI,CAAC,OAAA,EAAS,OAAO,EAAC;AACtB,EAAA,MAAM,OAA2B,EAAC;AAClC,EAAA,IAAI,OAAA,CAAQ,aAAA,EAAe,IAAA,CAAK,IAAA,CAAK,CAAC,MAAA,CAAO,KAAA,EAAO,MAAA,CAAO,OAAA,CAAQ,aAAa,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAC,CAAA;AAC/F,EAAA,IAAI,OAAA,CAAQ,SAAA,EAAW,IAAA,CAAK,IAAA,CAAK,CAAC,MAAA,CAAO,SAAA,EAAW,MAAA,CAAO,OAAA,CAAQ,SAAS,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAC,CAAA;AAC3F,EAAA,IAAI,OAAA,CAAQ,KAAA,EAAO,IAAA,CAAK,IAAA,CAAK,CAAC,MAAA,CAAO,KAAA,EAAO,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAC,CAAA;AAC/E,EAAA,IAAI,OAAA,CAAQ,OAAA,EAAS,IAAA,CAAK,IAAA,CAAK,CAAC,MAAA,CAAO,OAAA,EAAS,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,EAAE,CAAC,CAAC,CAAA;AACrF,EAAA,IAAI,QAAQ,UAAA,EAAY;AACtB,IAAA,MAAM,CAAA,GAAI,IAAI,IAAA,CAAK,OAAA,CAAQ,UAAU,CAAA;AACrC,IAAA,IAAI,CAAC,MAAA,CAAO,KAAA,CAAM,CAAA,CAAE,OAAA,EAAS,CAAA,EAAG;AAC9B,MAAA,IAAA,CAAK,IAAA,CAAK,CAAC,MAAA,CAAO,OAAA,EAAS,IAAI,IAAA,CAAK,cAAA,CAAe,QAAQ,EAAE,SAAA,EAAW,QAAQ,SAAA,EAAW,OAAA,EAAS,UAAU,KAAA,EAAO,EAAE,MAAA,CAAO,CAAC,CAAA,GAAI,MAAM,CAAC,CAAA;AAAA,IAC5I;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT","file":"chunk-MNLROALF.js","sourcesContent":["import type { PaymentErrorClassKind } from '@asteby/storefront'\n\n/** The notices `<PaymentRecovery>` can show. */\nexport type PaymentNoticeKind =\n /** Confirming the payment (automatic retry or status check). */\n | 'confirming'\n /** The secure card form did not load after the automatic retries. */\n | 'form_failed'\n /** The bank or provider rejected the charge (definitive): another card can be tried. */\n | 'rejected'\n /** The provider refused the charge at API level (definitive, nothing charged). */\n | 'provider_declined'\n /** Credentials or configuration of the merchant with the provider. */\n | 'merchant_config'\n /** The cart already became an order and the payment could not be reopened. */\n | 'stale_checkout'\n /** Another definitive error. */\n | 'other'\n\nexport type PaymentRecoveryMessageKey =\n | `error.${PaymentErrorClassKind}`\n | `notice.${PaymentNoticeKind}.title`\n | `notice.${PaymentNoticeKind}.body`\n | 'action.retry'\n | 'action.retry_form'\n | 'action.refresh'\n /** `{label}` is the name of the alternative payment choice. */\n | 'action.alternative'\n\nexport type PaymentRecoveryMessages = Record<PaymentRecoveryMessageKey, string>\n\nconst ES: PaymentRecoveryMessages = {\n 'error.transient': 'Estamos verificando tu pago. Si el cargo se hizo, lo veremos aquí; no te cobraremos dos veces.',\n 'error.in_progress': 'Ya hay un pago en proceso para este pedido. Estamos verificándolo; no vuelvas a pagar.',\n 'error.rate_limited': 'Hiciste varios intentos seguidos. Espera unos minutos e inténtalo de nuevo.',\n 'error.merchant_config': 'Por ahora no podemos procesar pagos con tarjeta. No es un problema con tu tarjeta: puedes pagar de otra forma.',\n 'error.provider_declined': 'No pudimos procesar tu pago con esa tarjeta. Revisa los datos o prueba con otro método; no se hizo ningún cobro.',\n 'error.stale_checkout': 'Este pedido ya quedó registrado y no se pudo reabrir el pago. Actualiza para ver cómo va tu pedido.',\n 'error.expired': 'Tu carrito venció. Vuelve a armarlo para pagar.',\n 'error.price_mismatch': 'El total cambió. Revisa el nuevo total y vuelve a pagar.',\n 'error.store_closed': 'Esta tienda aún no está abierta para compras. Vuelve pronto.',\n 'error.validation': 'Completa los campos marcados.',\n 'error.other': 'No pudimos procesar tu pago. Intenta de nuevo.',\n 'notice.confirming.title': 'Estamos confirmando tu pago…',\n 'notice.confirming.body': 'No cierres esta página ni vuelvas a pagar. Si el cargo ya se hizo, lo verás reflejado aquí.',\n 'notice.form_failed.title': 'No pudimos cargar el formulario de tarjeta',\n 'notice.form_failed.body': 'Suele resolverse al intentar de nuevo. También puedes pagar de otra forma.',\n 'notice.rejected.title': 'El cargo no se completó',\n 'notice.rejected.body': 'No se hizo ningún cobro. Puedes intentar con otra tarjeta o elegir otra forma de pago.',\n 'notice.provider_declined.title': 'No pudimos procesar tu pago con esa tarjeta',\n 'notice.provider_declined.body': 'No se hizo ningún cobro. Revisa los datos o prueba con otra tarjeta u otro método de pago.',\n 'notice.merchant_config.title': 'Por ahora no podemos cobrar con tarjeta',\n 'notice.merchant_config.body': 'No es un problema con tu tarjeta: es un tema de nuestro lado. Puedes pagar de otra forma.',\n 'notice.stale_checkout.title': 'Tu pedido ya quedó registrado',\n 'notice.stale_checkout.body': 'No pudimos reabrir el pago de este pedido. Actualiza para ver cómo va tu pedido; no se cobró de nuevo.',\n 'notice.other.title': 'No pudimos procesar tu pago',\n 'notice.other.body': 'Intenta de nuevo; si sigue igual, puedes pagar de otra forma.',\n 'action.retry': 'Reintentar pago',\n 'action.retry_form': 'Reintentar',\n 'action.refresh': 'Actualizar mi pedido',\n 'action.alternative': 'Pagar con {label}',\n}\n\nconst EN: PaymentRecoveryMessages = {\n 'error.transient': \"We're verifying your payment. If the charge went through we'll show it here; you won't be charged twice.\",\n 'error.in_progress': \"A payment is already in progress for this order. We're verifying it; don't pay again.\",\n 'error.rate_limited': 'Too many attempts in a row. Wait a few minutes and try again.',\n 'error.merchant_config': \"We can't take card payments right now. It isn't a problem with your card: you can pay another way.\",\n 'error.provider_declined': \"We couldn't process your payment with that card. Check the details or try another method; you were not charged.\",\n 'error.stale_checkout': \"This order is already registered and the payment couldn't be reopened. Refresh to see how it's going.\",\n 'error.expired': 'Your cart expired. Rebuild it to pay.',\n 'error.price_mismatch': 'The total changed. Check the new total and pay again.',\n 'error.store_closed': \"This store isn't open for purchases yet. Come back soon.\",\n 'error.validation': 'Complete the marked fields.',\n 'error.other': \"We couldn't process your payment. Try again.\",\n 'notice.confirming.title': \"We're confirming your payment…\",\n 'notice.confirming.body': \"Don't close this page or pay again. If the charge already went through you'll see it here.\",\n 'notice.form_failed.title': \"We couldn't load the card form\",\n 'notice.form_failed.body': 'Trying again usually fixes it. You can also pay another way.',\n 'notice.rejected.title': \"The charge didn't go through\",\n 'notice.rejected.body': 'You were not charged. Try another card or choose another way to pay.',\n 'notice.provider_declined.title': \"We couldn't process your payment with that card\",\n 'notice.provider_declined.body': 'You were not charged. Check the details or try another card or method.',\n 'notice.merchant_config.title': \"We can't charge cards right now\",\n 'notice.merchant_config.body': \"It isn't a problem with your card: it's on our side. You can pay another way.\",\n 'notice.stale_checkout.title': 'Your order is already registered',\n 'notice.stale_checkout.body': \"We couldn't reopen the payment for this order. Refresh to see how it's going; you were not charged again.\",\n 'notice.other.title': \"We couldn't process your payment\",\n 'notice.other.body': 'Try again; if it keeps failing you can pay another way.',\n 'action.retry': 'Retry payment',\n 'action.retry_form': 'Retry',\n 'action.refresh': 'Refresh my order',\n 'action.alternative': 'Pay with {label}',\n}\n\n/** Texts for a locale (`es*` default, `en*`), with optional overrides. Nothing here names a provider or a brand. */\nexport function paymentRecoveryMessages(locale?: string | null, overrides?: Partial<PaymentRecoveryMessages> | null): PaymentRecoveryMessages {\n const base = (locale ?? 'es-MX').toLowerCase().startsWith('en') ? EN : ES\n return overrides ? { ...base, ...overrides } : base\n}\n","import type { PaymentClient } from '@asteby/storefront'\n\nexport type PaymentCspOptions = {\n /** Per-request nonce; also set it on the inserted `<script>` and on `<Scripts nonce>`. */\n nonce?: string\n /** Extra origins by directive (e.g. your image CDN). */\n extra?: { script?: string[]; frame?: string[]; connect?: string[]; img?: string[]; form?: string[] }\n /** `report-uri` / `report-to` target for the report-only rollout. */\n reportUri?: string\n /** Inline scripts allowed by hash (`'sha256-…'`), e.g. a theme bootstrap that runs before paint. */\n scriptHashes?: string[]\n /** Allow any https image source (product photos from a CDN). */\n imgHttps?: boolean\n}\n\n/** One origin source: `https://host`, `https://*.host`, optional port. Anything else (`;`, spaces, `'unsafe-eval'`) is dropped. */\nconst ORIGIN = /^https:\\/\\/(\\*\\.)?[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*(:\\d{1,5})?$/i\n\nfunction origins(...lists: (readonly string[] | undefined)[]): string[] {\n const out = new Set<string>()\n for (const list of lists) for (const o of list ?? []) if (ORIGIN.test(o)) out.add(o)\n return [...out]\n}\n\n/**\n * Builds the Content-Security-Policy for the payment routes from what each provider declares\n * (`PaymentClient.csp`), so the shop never hard-codes provider hosts. Meant for `/pagar` only,\n * never for the whole site. Roll out as `Content-Security-Policy-Report-Only` first.\n *\n * No SRI on purpose: provider SDK URLs are unversioned and a hash would break payments on any update.\n */\nexport function paymentCsp(clients: readonly (PaymentClient | null | undefined)[], options: PaymentCspOptions = {}): string {\n const list = clients.filter((c): c is PaymentClient => !!c)\n const pick = (k: keyof NonNullable<PaymentClient['csp']>) => list.map((c) => c.csp?.[k])\n const nonce = options.nonce && /^[A-Za-z0-9+/=_-]+$/.test(options.nonce) ? options.nonce : undefined\n const sdkOrigins = list.flatMap((c) => {\n try {\n const u = new URL(c.sdk_url)\n return u.protocol === 'https:' ? [u.origin] : []\n } catch {\n return []\n }\n })\n const dir = (name: string, values: string[]) => `${name} ${values.join(' ')}`\n const parts = [\n \"default-src 'self'\",\n dir('script-src', [\"'self'\", ...(options.scriptHashes ?? []).filter((h) => /^'sha(256|384|512)-[A-Za-z0-9+/=]+'$/.test(h)), ...(nonce ? [`'nonce-${nonce}'`] : []), ...origins(sdkOrigins, ...pick('script'), options.extra?.script)]),\n dir('frame-src', origins(...pick('frame'), options.extra?.frame).length ? origins(...pick('frame'), options.extra?.frame) : [\"'none'\"]),\n dir('connect-src', [\"'self'\", ...origins(...pick('connect'), options.extra?.connect)]),\n dir('img-src', [\"'self'\", 'data:', ...(options.imgHttps ? ['https:'] : []), ...origins(...pick('img'), options.extra?.img)]),\n \"style-src 'self' 'unsafe-inline'\",\n dir('form-action', [\"'self'\", ...origins(...pick('form'), options.extra?.form)]),\n \"frame-ancestors 'none'\",\n \"base-uri 'self'\",\n \"object-src 'none'\",\n ]\n if (options.reportUri && /^(https:\\/\\/|\\/)[^\\s;,]+$/.test(options.reportUri)) parts.push(`report-uri ${options.reportUri}`)\n return parts.join('; ')\n}\n\n/** `Content-Security-Policy` or, during the rollout week, `Content-Security-Policy-Report-Only`. */\nexport function paymentCspHeaderName(reportOnly: boolean): string {\n return reportOnly ? 'Content-Security-Policy-Report-Only' : 'Content-Security-Policy'\n}\n\nexport type PaymentCspMode = 'off' | 'report-only' | 'enforce'\n\n/** `PAYMENT_CSP`-style value: `off`, `report-only` or `enforce`. Unset: report-only in production, off elsewhere (dev servers inject scripts). */\nexport function paymentCspMode(value: string | null | undefined, production: boolean): PaymentCspMode {\n const raw = (value ?? '').trim().toLowerCase()\n if (raw === 'off' || raw === 'report-only' || raw === 'enforce') return raw\n return production ? 'report-only' : 'off'\n}\n\n/** Fresh per-request nonce (128 bits, base64). Works in Node, edge and browsers. */\nexport function paymentNonce(): string {\n const bytes = new Uint8Array(16)\n crypto.getRandomValues(bytes)\n let bin = ''\n for (const b of bytes) bin += String.fromCharCode(b)\n return btoa(bin)\n}\n\n/** Header ready for the response (`{}` when `off`): policy from the providers' `client.csp`, never the whole site. */\nexport function paymentCspHeaders(\n clients: readonly (PaymentClient | null | undefined)[],\n options: PaymentCspOptions & { mode: PaymentCspMode },\n): Record<string, string> {\n if (options.mode === 'off') return {}\n return { [paymentCspHeaderName(options.mode === 'report-only')]: paymentCsp(clients, options) }\n}\n\n/** The nonce the route left in the CSP header, to hand to `ServerRouter` / `<Scripts>`. */\nexport function paymentNonceFromHeaders(headers: Headers): string | undefined {\n const csp = headers.get('Content-Security-Policy') ?? headers.get('Content-Security-Policy-Report-Only') ?? ''\n return /'nonce-([A-Za-z0-9+/=_-]+)'/.exec(csp)?.[1]\n}\n","/**\n * \"Payment method\" rows for a hybrid checkout: pure functions, no DOM and no server, so the loader, the action and the\n * browser share them.\n *\n * Rules (embedded-payment contract 1.2):\n * - Rows come ONLY from what the server publishes (`payment-methods[].options` and `.client`). No provider names and no\n * amounts live here.\n * - Card and cash are paid in the page; `wallet` and `credits` redirect to the provider.\n * - Without `client`, or with the card flagged `redirect: true`, the server does not offer `embedded`: the shop falls\n * back to the usual redirect flow.\n */\nimport { classifyPaymentError } from '@asteby/storefront'\nimport type {\n CheckoutResult,\n PaymentAttemptResult,\n PaymentClient,\n PaymentErrorClassKind,\n PaymentMethod,\n PaymentOption,\n PaymentOptionKey,\n PaymentPoint,\n} from '@asteby/storefront'\nimport { paymentRecoveryMessages, type PaymentRecoveryMessages } from './recovery-messages.js'\n\n/** One row of \"Payment method\". `value` is what travels in the form (`payment_choice`). */\nexport type PayChoice = {\n value: string\n /** Server method key (`payment_method` of the checkout). */\n methodKey: string\n /** Provider option; `null` for a method without options (the plain flow). */\n option: PaymentOptionKey | null\n /** `card` (form in the page), `cash` (voucher), `redirect` (leaves to the gateway) or `plain`. */\n mode: 'card' | 'cash' | 'redirect' | 'plain'\n /** The provider's own text (`option.label`); the shop supplies its own when missing. */\n label: string | null\n points: PaymentPoint[]\n maxInstallments: number | null\n}\n\nexport type PayChoices = {\n choices: PayChoice[]\n /** Public data to mount the card form; `null` when the server does not offer `embedded`. */\n cardClient: PaymentClient | null\n defaultValue: string | null\n}\n\nexport type BuildPayChoicesOptions = {\n /** Method keys this shop never offers even when the server publishes them (e.g. a manual transfer). */\n hide?: Iterable<string>\n}\n\nconst SEP = '|'\n\nexport function choiceValue(methodKey: string, option: PaymentOptionKey | null): string {\n return option ? `${methodKey}${SEP}${option}` : methodKey\n}\n\n/** `\"mercadopago|card\"` becomes method and option. A value without `|` is a method without options. */\nexport function parseChoice(value: string | null | undefined): { methodKey: string; option: PaymentOptionKey | null } | null {\n const raw = (value ?? '').trim()\n if (!raw) return null\n const i = raw.lastIndexOf(SEP)\n if (i === -1) return { methodKey: raw, option: null }\n const option = raw.slice(i + 1)\n if (option !== 'card' && option !== 'cash' && option !== 'wallet' && option !== 'credits') return null\n return { methodKey: raw.slice(0, i), option }\n}\n\nfunction modeOf(option: PaymentOption): PayChoice['mode'] {\n if (option.redirect || option.key === 'wallet' || option.key === 'credits') return 'redirect'\n return option.key === 'cash' ? 'cash' : 'card'\n}\n\n/**\n * Rows from `GET payment-methods`. A method with `options` unfolds into one row per option (server order); one without\n * is a single plain row. `cardClient` only exists when the card is paid in the page.\n */\nexport function buildPayChoices(methods: readonly PaymentMethod[], options: BuildPayChoicesOptions = {}): PayChoices {\n const hidden = new Set(options.hide ?? [])\n const choices: PayChoice[] = []\n let cardClient: PaymentClient | null = null\n let defaultValue: string | null = null\n for (const method of methods) {\n if (hidden.has(method.key)) continue\n const opts = method.options ?? []\n if (opts.length === 0) {\n const value = choiceValue(method.key, null)\n choices.push({ value, methodKey: method.key, option: null, mode: 'plain', label: null, points: [], maxInstallments: null })\n if (method.default && !defaultValue) defaultValue = value\n continue\n }\n opts.forEach((option, i) => {\n const mode = modeOf(option)\n const value = choiceValue(method.key, option.key)\n choices.push({\n value,\n methodKey: method.key,\n option: option.key,\n mode,\n label: option.label?.trim() || null,\n points: option.key === 'cash' ? (option.points ?? []) : [],\n maxInstallments: option.max_installments ?? null,\n })\n if (mode === 'card' && method.client && !cardClient) cardClient = method.client\n if (method.default && i === 0 && !defaultValue) defaultValue = value\n })\n }\n // A card meant for the page but without `client` cannot be mounted: it is paid by redirect.\n const usable = choices.map((c) => (c.mode === 'card' && !cardClient ? { ...c, mode: 'redirect' as const } : c))\n return { choices: usable, cardClient, defaultValue: defaultValue ?? usable[0]?.value ?? null }\n}\n\n/** Chosen cash point becomes the cash `provider_data`, built on the server from the provider's list. */\nexport function cashProviderData(points: readonly PaymentPoint[], pointId: string | null | undefined): Record<string, string> | null {\n const point = points.find((p) => p.id === pointId) ?? (pointId ? null : points[0])\n if (!point) return null\n return {\n payment_method_id: point.payment_method_id,\n ...(point.payment_point ? { payment_point: point.payment_point } : {}),\n }\n}\n\n/**\n * A checkout (`GET checkouts/:id`) as an attempt result, for polling a 3DS challenge or a payment under review.\n * It only translates server states: it never decides a payment.\n */\nexport function checkoutToAttempt(result: CheckoutResult): PaymentAttemptResult {\n const { checkout, payment, order } = result\n const action = payment.action ?? null\n const base = { checkout, ...(order ? { order } : {}) }\n const status = (checkout.status ?? '').toLowerCase()\n if (status === 'paid' || status === 'converted') return { ...base, payment: { provider: payment.provider, status: 'paid', outcome: 'approved' } }\n if (status === 'cancelled' || status === 'canceled') return { ...base, payment: { provider: payment.provider, status: 'cancelled' } }\n if (status === 'expired') return { ...base, payment: { provider: payment.provider, status: 'expired' } }\n if (status === 'failed') {\n const decline = (payment as { decline_code?: PaymentAttemptResult['payment']['decline_code'] }).decline_code ?? 'declined'\n return { ...base, payment: { provider: payment.provider, status: 'failed', outcome: 'rejected', decline_code: decline, retryable: true } }\n }\n // Still pending: same as the last attempt left it (challenge or review), so the screen does not change.\n if (action?.type === 'challenge') return { ...base, payment: { provider: payment.provider, status: 'requires_action', outcome: 'challenge', action } }\n return { ...base, payment: { provider: payment.provider, status: 'pending', outcome: 'pending', action: action ?? { type: 'none' } } }\n}\n\n/**\n * Body `{ error: { code, message, retryable, kind, ... } }` that `createFetchTransport` and `createResilientTransport`\n * understand. `retryable` and `kind` come from `classifyPaymentError`: the browser never guesses them from the status.\n */\nexport type PayErrorBody = {\n error: { code: string; message: string; retryable: boolean; kind: PaymentErrorClassKind; field?: string; retry_after?: number; details?: unknown }\n}\n\ntype ErrorLike = {\n status?: number\n code?: string\n field?: string\n message?: string\n details?: unknown\n /** `StorefrontError.retryable`: what OPS declared. */\n retryable?: boolean | undefined\n checkoutId?: string | undefined\n retryAfter?: number | undefined\n}\n\nexport type PayErrorOptions = {\n locale?: string\n /** Replaces the default texts (`error.<kind>`). */\n messages?: Partial<PaymentRecoveryMessages>\n /** Forces the classification (for refusals the shop itself makes). */\n kind?: PaymentErrorClassKind\n /** `err.message` was written by the shop itself (a refusal it makes, such as `tooManyRequests`): always kept. */\n ownMessage?: boolean\n}\n\n/**\n * 502-504 never leave the shop's pay routes: the proxy (Traefik's `errors` middleware, a CDN) replaces them with an HTML\n * page, and the browser loses the JSON and the `Set-Cookie` of the payment session. They are answered as 500; the\n * body (`retryable`, `kind`) is what decides.\n */\nexport function safeHttpStatus(status: number): number {\n return status === 502 || status === 503 || status === 504 ? 500 : status\n}\n\n/**\n * Server error becomes a JSON response for the browser. Keeps the codes the SDK knows how to read (`price_mismatch`,\n * `payment_in_progress`, `expired`, `too_many_attempts`); the mock sends \"in progress\" in `field`, so that is checked too.\n * Always JSON, never 502-504 (see `safeHttpStatus`), always with `retryable` and `kind`.\n */\nexport function payErrorResponse(err: ErrorLike, options: PayErrorOptions = {}): { status: number; body: PayErrorBody } {\n const status = typeof err.status === 'number' && err.status >= 400 ? err.status : 503\n const { kind: classified, retryable } = classifyPaymentError({ ...err, status, checkoutId: err.checkoutId ?? null })\n const kind = options.kind ?? classified\n let code = err.code ?? (kind === 'transient' ? 'unavailable' : 'server_error')\n if (status === 409 && err.field === 'payment_in_progress') code = 'payment_in_progress'\n if (status === 429) code = 'too_many_attempts'\n if (status === 422 && err.field === 'expected_total') code = 'price_mismatch'\n // Texts the shop wrote itself (missing fields, expired cart, a row it does not offer) are kept; OPS' own message,\n // often technical or in English, is replaced by the catalog text for the kind.\n const own = (options.ownMessage || kind === 'validation' || kind === 'expired' || kind === 'price_mismatch' || (kind === 'other' && status < 500)) && err.message\n const message = own || paymentRecoveryMessages(options.locale, options.messages)[`error.${kind}`]\n return {\n status: safeHttpStatus(status),\n body: {\n error: {\n code,\n message,\n retryable: options.kind ? options.kind === 'transient' || options.kind === 'in_progress' || options.kind === 'rate_limited' : retryable,\n kind,\n ...(err.field ? { field: err.field } : {}),\n ...(err.retryAfter ? { retry_after: err.retryAfter } : {}),\n ...(err.details !== undefined ? { details: err.details } : {}),\n },\n },\n }\n}\n\nexport type VoucherRowLabels = { point: string; reference: string; clabe: string; barcode: string; expires: string }\n\n/** Cookie receipt rows for a payment under review or with a voucher (shown on the thank-you page). */\nexport function voucherRows(\n voucher: NonNullable<NonNullable<PaymentAttemptResult['payment']['action']>['voucher']> | null | undefined,\n labels: VoucherRowLabels,\n locale: string,\n): [label: string, value: string][] {\n if (!voucher) return []\n const rows: [string, string][] = []\n if (voucher.payment_point) rows.push([labels.point, String(voucher.payment_point).slice(0, 60)])\n if (voucher.reference) rows.push([labels.reference, String(voucher.reference).slice(0, 80)])\n if (voucher.clabe) rows.push([labels.clabe, String(voucher.clabe).slice(0, 40)])\n if (voucher.barcode) rows.push([labels.barcode, String(voucher.barcode).slice(0, 80)])\n if (voucher.expires_at) {\n const d = new Date(voucher.expires_at)\n if (!Number.isNaN(d.getTime())) {\n rows.push([labels.expires, new Intl.DateTimeFormat(locale, { dateStyle: 'long', timeStyle: 'short', timeZone: 'UTC' }).format(d) + ' UTC'])\n }\n }\n return rows\n}\n"]}