@payloadcms/plugin-ecommerce 3.91.0-internal.6e3dc85 → 4.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +1 -1
- package/dist/collections/addresses/createAddressesCollection.d.ts.map +1 -1
- package/dist/collections/addresses/createAddressesCollection.js +1 -0
- package/dist/collections/addresses/createAddressesCollection.js.map +1 -1
- package/dist/collections/addresses/hooks/beforeChange.d.ts.map +1 -1
- package/dist/collections/addresses/hooks/beforeChange.js +3 -2
- package/dist/collections/addresses/hooks/beforeChange.js.map +1 -1
- package/dist/collections/carts/beforeChange.d.ts.map +1 -1
- package/dist/collections/carts/beforeChange.js +2 -0
- package/dist/collections/carts/beforeChange.js.map +1 -1
- package/dist/collections/carts/createCartsCollection.d.ts.map +1 -1
- package/dist/collections/carts/createCartsCollection.js +1 -0
- package/dist/collections/carts/createCartsCollection.js.map +1 -1
- package/dist/collections/orders/createOrdersCollection.d.ts.map +1 -1
- package/dist/collections/orders/createOrdersCollection.js +1 -0
- package/dist/collections/orders/createOrdersCollection.js.map +1 -1
- package/dist/collections/products/createProductsCollection.d.ts.map +1 -1
- package/dist/collections/products/createProductsCollection.js +1 -0
- package/dist/collections/products/createProductsCollection.js.map +1 -1
- package/dist/collections/transactions/createTransactionsCollection.d.ts.map +1 -1
- package/dist/collections/transactions/createTransactionsCollection.js +1 -0
- package/dist/collections/transactions/createTransactionsCollection.js.map +1 -1
- package/dist/collections/variants/createVariantOptionsCollection.d.ts.map +1 -1
- package/dist/collections/variants/createVariantOptionsCollection.js +1 -0
- package/dist/collections/variants/createVariantOptionsCollection.js.map +1 -1
- package/dist/collections/variants/createVariantTypesCollection.d.ts.map +1 -1
- package/dist/collections/variants/createVariantTypesCollection.js +1 -0
- package/dist/collections/variants/createVariantTypesCollection.js.map +1 -1
- package/dist/collections/variants/createVariantsCollection/hooks/beforeChange.d.ts.map +1 -1
- package/dist/collections/variants/createVariantsCollection/hooks/beforeChange.js +2 -0
- package/dist/collections/variants/createVariantsCollection/hooks/beforeChange.js.map +1 -1
- package/dist/collections/variants/createVariantsCollection/hooks/validateOptions.d.ts.map +1 -1
- package/dist/collections/variants/createVariantsCollection/hooks/validateOptions.js +1 -0
- package/dist/collections/variants/createVariantsCollection/hooks/validateOptions.js.map +1 -1
- package/dist/collections/variants/createVariantsCollection/index.d.ts.map +1 -1
- package/dist/collections/variants/createVariantsCollection/index.js +1 -0
- package/dist/collections/variants/createVariantsCollection/index.js.map +1 -1
- package/dist/endpoints/confirmOrder.d.ts.map +1 -1
- package/dist/endpoints/confirmOrder.js +7 -0
- package/dist/endpoints/confirmOrder.js.map +1 -1
- package/dist/endpoints/initiatePayment.d.ts.map +1 -1
- package/dist/endpoints/initiatePayment.js +2 -0
- package/dist/endpoints/initiatePayment.js.map +1 -1
- package/dist/exports/types.d.ts +1 -1
- package/dist/exports/types.d.ts.map +1 -1
- package/dist/exports/types.js.map +1 -1
- package/dist/fields/pricesField.d.ts.map +1 -1
- package/dist/fields/pricesField.js +39 -39
- package/dist/fields/pricesField.js.map +1 -1
- package/dist/fields/variantsFields.js +3 -1
- package/dist/fields/variantsFields.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -24
- package/dist/index.js.map +1 -1
- package/dist/payments/adapters/stripe/confirmOrder.js +1 -0
- package/dist/payments/adapters/stripe/confirmOrder.js.map +1 -1
- package/dist/payments/adapters/stripe/initiatePayment.d.ts.map +1 -1
- package/dist/payments/adapters/stripe/initiatePayment.js +1 -0
- package/dist/payments/adapters/stripe/initiatePayment.js.map +1 -1
- package/dist/react/provider/index.d.ts.map +1 -1
- package/dist/react/provider/index.js.map +1 -1
- package/dist/translations/languages/ar.d.ts.map +1 -1
- package/dist/translations/languages/az.d.ts.map +1 -1
- package/dist/translations/languages/bg.d.ts.map +1 -1
- package/dist/translations/languages/ca.d.ts.map +1 -1
- package/dist/translations/languages/cs.d.ts.map +1 -1
- package/dist/translations/languages/da.d.ts.map +1 -1
- package/dist/translations/languages/de.d.ts.map +1 -1
- package/dist/translations/languages/en.d.ts.map +1 -1
- package/dist/translations/languages/es.d.ts.map +1 -1
- package/dist/translations/languages/et.d.ts.map +1 -1
- package/dist/translations/languages/fa.d.ts.map +1 -1
- package/dist/translations/languages/fr.d.ts.map +1 -1
- package/dist/translations/languages/he.d.ts.map +1 -1
- package/dist/translations/languages/hr.d.ts.map +1 -1
- package/dist/translations/languages/hu.d.ts.map +1 -1
- package/dist/translations/languages/hy.d.ts.map +1 -1
- package/dist/translations/languages/is.d.ts.map +1 -1
- package/dist/translations/languages/it.d.ts.map +1 -1
- package/dist/translations/languages/ja.d.ts.map +1 -1
- package/dist/translations/languages/ko.d.ts.map +1 -1
- package/dist/translations/languages/lt.d.ts.map +1 -1
- package/dist/translations/languages/my.d.ts.map +1 -1
- package/dist/translations/languages/nb.d.ts.map +1 -1
- package/dist/translations/languages/nl.d.ts.map +1 -1
- package/dist/translations/languages/pl.d.ts.map +1 -1
- package/dist/translations/languages/pt.d.ts.map +1 -1
- package/dist/translations/languages/ro.d.ts.map +1 -1
- package/dist/translations/languages/rs.d.ts.map +1 -1
- package/dist/translations/languages/rsLatin.d.ts.map +1 -1
- package/dist/translations/languages/ru.d.ts.map +1 -1
- package/dist/translations/languages/sk.d.ts.map +1 -1
- package/dist/translations/languages/sl.d.ts.map +1 -1
- package/dist/translations/languages/sv.d.ts.map +1 -1
- package/dist/translations/languages/ta.d.ts.map +1 -1
- package/dist/translations/languages/th.d.ts.map +1 -1
- package/dist/translations/languages/tr.d.ts.map +1 -1
- package/dist/translations/languages/uk.d.ts.map +1 -1
- package/dist/translations/languages/vi.d.ts.map +1 -1
- package/dist/translations/languages/zh.d.ts.map +1 -1
- package/dist/translations/languages/zhTw.d.ts.map +1 -1
- package/dist/types/index.d.ts +9 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/ui/PriceInput/FormattedInput.js +2 -2
- package/dist/ui/PriceInput/FormattedInput.js.map +1 -1
- package/dist/ui/PriceInput/index.css +19 -31
- package/dist/ui/PriceInput/index.d.ts.map +1 -1
- package/dist/ui/PriceInput/index.js.map +1 -1
- package/dist/ui/PriceRowLabel/index.css +2 -2
- package/dist/ui/VariantOptionsSelector/index.css +8 -10
- package/dist/ui/VariantOptionsSelector/index.d.ts.map +1 -1
- package/dist/ui/VariantOptionsSelector/index.js +3 -1
- package/dist/ui/VariantOptionsSelector/index.js.map +1 -1
- package/dist/utilities/pushTypeScriptProperties.js +1 -1
- package/dist/utilities/pushTypeScriptProperties.js.map +1 -1
- package/package.json +10 -10
- package/dist/collections/carts/operations/defaultCartItemMatcher.spec.js +0 -358
- package/dist/collections/carts/operations/defaultCartItemMatcher.spec.js.map +0 -1
- package/dist/collections/orders/createOrdersCollection.spec.js +0 -20
- package/dist/collections/orders/createOrdersCollection.spec.js.map +0 -1
- package/dist/endpoints/confirmOrder.spec.js +0 -509
- package/dist/endpoints/confirmOrder.spec.js.map +0 -1
- package/dist/fields/statusField.spec.js +0 -9
- package/dist/fields/statusField.spec.js.map +0 -1
- package/dist/payments/adapters/stripe/confirmOrder.spec.js +0 -255
- package/dist/payments/adapters/stripe/confirmOrder.spec.js.map +0 -1
- package/dist/payments/adapters/stripe/validateSettlement.spec.js +0 -434
- package/dist/payments/adapters/stripe/validateSettlement.spec.js.map +0 -1
- package/dist/utilities/accessComposition.spec.js +0 -765
- package/dist/utilities/accessComposition.spec.js.map +0 -1
- package/dist/utilities/defaultProductsValidation.spec.js +0 -384
- package/dist/utilities/defaultProductsValidation.spec.js.map +0 -1
- package/dist/utilities/getCollectionSlugMap.spec.js +0 -254
- package/dist/utilities/getCollectionSlugMap.spec.js.map +0 -1
- package/dist/utilities/sanitizePluginConfig.spec.js +0 -516
- package/dist/utilities/sanitizePluginConfig.spec.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/collections/variants/createVariantsCollection/index.ts"],"sourcesContent":["import type { CollectionConfig, Field } from 'payload'\n\nimport type { AccessConfig, CurrenciesConfig, InventoryConfig } from '../../../types/index.js'\n\nimport { inventoryField } from '../../../fields/inventoryField.js'\nimport { pricesField } from '../../../fields/pricesField.js'\nimport { variantsCollectionBeforeChange as beforeChange } from './hooks/beforeChange.js'\nimport { validateOptions } from './hooks/validateOptions.js'\n\ntype Props = {\n access: Pick<AccessConfig, 'adminOrPublishedStatus' | 'isAdmin'>\n currenciesConfig?: CurrenciesConfig\n /**\n * Enables inventory tracking for variants. Defaults to true.\n */\n inventory?: boolean | InventoryConfig\n /**\n * Slug of the products collection, defaults to 'products'.\n */\n productsSlug?: string\n /**\n * Slug of the variant options collection, defaults to 'variantOptions'.\n */\n variantOptionsSlug?: string\n /**\n * Slug of the variant types collection, defaults to 'variantTypes'.\n */\n variantTypesSlug?: string\n}\n\nexport const createVariantsCollection: (props: Props) => CollectionConfig = (props) => {\n const {\n access,\n currenciesConfig,\n inventory = true,\n productsSlug = 'products',\n variantOptionsSlug = 'variantOptions',\n variantTypesSlug = 'variantTypes',\n } = props || {}\n const { supportedCurrencies } = currenciesConfig || {}\n\n const fields: Field[] = [\n {\n name: 'title',\n type: 'text',\n admin: {\n description:\n 'Used for administrative purposes, not shown to customers. This is populated by default.',\n },\n },\n {\n name: 'product',\n type: 'relationship',\n admin: {\n position: 'sidebar',\n readOnly: true,\n },\n relationTo: productsSlug,\n required: true,\n },\n {\n // This might need to be a custom component, to show a selector for each variant that is\n // enabled on the parent product\n // - separate select inputs, each showing only a specific variant (w/ options)\n // - it will save data to the DB as IDs in this relationship field\n // and needs a validate function as well which enforces that the options are fully specified, and accurate\n name: 'options',\n type: 'relationship',\n admin: {\n components: {\n Field: {\n path: '@payloadcms/plugin-ecommerce/rsc#VariantOptionsSelector',\n },\n },\n },\n custom: {\n productsSlug,\n variantTypesSlug,\n },\n hasMany: true,\n label: 'Variant options',\n relationTo: variantOptionsSlug,\n required: true,\n validate: validateOptions({ productsCollectionSlug: productsSlug }),\n },\n ...(inventory ? [inventoryField()] : []),\n ]\n\n if (supportedCurrencies?.length && supportedCurrencies.length > 0) {\n const currencyOptions: string[] = []\n\n supportedCurrencies.forEach((currency) => {\n currencyOptions.push(currency.code)\n })\n\n if (currenciesConfig) {\n fields.push(...pricesField({ currenciesConfig }))\n }\n }\n\n const baseConfig: CollectionConfig = {\n slug: 'variants',\n access: {\n create: access.isAdmin,\n delete: access.isAdmin,\n read: access.adminOrPublishedStatus,\n update: access.isAdmin,\n },\n admin: {\n description: ({ t }) =>\n // @ts-expect-error - translations are not typed in plugins yet\n t('plugin-ecommerce:variantsCollectionDescription'),\n group: false,\n useAsTitle: 'title',\n },\n fields,\n hooks: {\n beforeChange: [beforeChange({ productsSlug, variantOptionsSlug })],\n },\n labels: {\n plural: ({ t }) =>\n // @ts-expect-error - translations are not typed in plugins yet\n t('plugin-ecommerce:variants'),\n singular: ({ t }) =>\n // @ts-expect-error - translations are not typed in plugins yet\n t('plugin-ecommerce:variant'),\n },\n trash: true,\n versions: {\n drafts: {\n autosave: true,\n },\n },\n }\n\n return baseConfig\n}\n"],"names":["inventoryField","pricesField","variantsCollectionBeforeChange","beforeChange","validateOptions","createVariantsCollection","props","access","currenciesConfig","inventory","productsSlug","variantOptionsSlug","variantTypesSlug","supportedCurrencies","fields","name","type","admin","description","position","readOnly","relationTo","required","components","Field","path","custom","hasMany","label","validate","productsCollectionSlug","length","currencyOptions","forEach","currency","push","code","baseConfig","slug","create","isAdmin","delete","read","adminOrPublishedStatus","update","t","group","useAsTitle","hooks","labels","plural","singular","trash","versions","drafts","autosave"],"mappings":"AAIA,SAASA,cAAc,QAAQ,oCAAmC;AAClE,SAASC,WAAW,QAAQ,iCAAgC;AAC5D,SAASC,kCAAkCC,YAAY,QAAQ,0BAAyB;AACxF,SAASC,eAAe,QAAQ,6BAA4B;AAuB5D,OAAO,MAAMC,2BAA+D,CAACC;IAC3E,MAAM,EACJC,MAAM,EACNC,gBAAgB,EAChBC,YAAY,IAAI,EAChBC,eAAe,UAAU,EACzBC,qBAAqB,gBAAgB,EACrCC,mBAAmB,cAAc,EAClC,GAAGN,SAAS,CAAC;IACd,MAAM,EAAEO,mBAAmB,EAAE,GAAGL,oBAAoB,CAAC;IAErD,MAAMM,SAAkB;QACtB;YACEC,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLC,aACE;YACJ;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLE,UAAU;gBACVC,UAAU;YACZ;YACAC,YAAYX;YACZY,UAAU;QACZ;QACA;YACE,wFAAwF;YACxF,gCAAgC;YAChC,8EAA8E;YAC9E,kEAAkE;YAClE,0GAA0G;YAC1GP,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLM,YAAY;oBACVC,OAAO;wBACLC,MAAM;oBACR;gBACF;YACF;YACAC,QAAQ;gBACNhB;gBACAE;YACF;YACAe,SAAS;YACTC,OAAO;YACPP,YAAYV;YACZW,UAAU;YACVO,UAAUzB,gBAAgB;gBAAE0B,wBAAwBpB;YAAa;QACnE;WACID,YAAY;YAACT;SAAiB,GAAG,EAAE;KACxC;IAED,IAAIa,qBAAqBkB,UAAUlB,oBAAoBkB,MAAM,GAAG,GAAG;QACjE,MAAMC,kBAA4B,EAAE;QAEpCnB,oBAAoBoB,OAAO,CAAC,CAACC;YAC3BF,gBAAgBG,IAAI,CAACD,SAASE,IAAI;QACpC;QAEA,IAAI5B,kBAAkB;YACpBM,OAAOqB,IAAI,IAAIlC,YAAY;gBAAEO;YAAiB;QAChD;IACF;IAEA,MAAM6B,aAA+B;QACnCC,MAAM;QACN/B,QAAQ;YACNgC,QAAQhC,OAAOiC,OAAO;YACtBC,QAAQlC,OAAOiC,OAAO;YACtBE,MAAMnC,OAAOoC,sBAAsB;YACnCC,QAAQrC,OAAOiC,OAAO;QACxB;QACAvB,OAAO;YACLC,aAAa,CAAC,EAAE2B,CAAC,EAAE,GACjB,+DAA+D;gBAC/DA,EAAE;YACJC,OAAO;YACPC,YAAY;QACd;
|
|
1
|
+
{"version":3,"sources":["../../../../src/collections/variants/createVariantsCollection/index.ts"],"sourcesContent":["import type { CollectionConfig, Field } from 'payload'\n\nimport type { AccessConfig, CurrenciesConfig, InventoryConfig } from '../../../types/index.js'\n\nimport { inventoryField } from '../../../fields/inventoryField.js'\nimport { pricesField } from '../../../fields/pricesField.js'\nimport { variantsCollectionBeforeChange as beforeChange } from './hooks/beforeChange.js'\nimport { validateOptions } from './hooks/validateOptions.js'\n\ntype Props = {\n access: Pick<AccessConfig, 'adminOrPublishedStatus' | 'isAdmin'>\n currenciesConfig?: CurrenciesConfig\n /**\n * Enables inventory tracking for variants. Defaults to true.\n */\n inventory?: boolean | InventoryConfig\n /**\n * Slug of the products collection, defaults to 'products'.\n */\n productsSlug?: string\n /**\n * Slug of the variant options collection, defaults to 'variantOptions'.\n */\n variantOptionsSlug?: string\n /**\n * Slug of the variant types collection, defaults to 'variantTypes'.\n */\n variantTypesSlug?: string\n}\n\nexport const createVariantsCollection: (props: Props) => CollectionConfig = (props) => {\n const {\n access,\n currenciesConfig,\n inventory = true,\n productsSlug = 'products',\n variantOptionsSlug = 'variantOptions',\n variantTypesSlug = 'variantTypes',\n } = props || {}\n const { supportedCurrencies } = currenciesConfig || {}\n\n const fields: Field[] = [\n {\n name: 'title',\n type: 'text',\n admin: {\n description:\n 'Used for administrative purposes, not shown to customers. This is populated by default.',\n },\n },\n {\n name: 'product',\n type: 'relationship',\n admin: {\n position: 'sidebar',\n readOnly: true,\n },\n relationTo: productsSlug,\n required: true,\n },\n {\n // This might need to be a custom component, to show a selector for each variant that is\n // enabled on the parent product\n // - separate select inputs, each showing only a specific variant (w/ options)\n // - it will save data to the DB as IDs in this relationship field\n // and needs a validate function as well which enforces that the options are fully specified, and accurate\n name: 'options',\n type: 'relationship',\n admin: {\n components: {\n Field: {\n path: '@payloadcms/plugin-ecommerce/rsc#VariantOptionsSelector',\n },\n },\n },\n custom: {\n productsSlug,\n variantTypesSlug,\n },\n hasMany: true,\n label: 'Variant options',\n relationTo: variantOptionsSlug,\n required: true,\n validate: validateOptions({ productsCollectionSlug: productsSlug }),\n },\n ...(inventory ? [inventoryField()] : []),\n ]\n\n if (supportedCurrencies?.length && supportedCurrencies.length > 0) {\n const currencyOptions: string[] = []\n\n supportedCurrencies.forEach((currency) => {\n currencyOptions.push(currency.code)\n })\n\n if (currenciesConfig) {\n fields.push(...pricesField({ currenciesConfig }))\n }\n }\n\n const baseConfig: CollectionConfig = {\n slug: 'variants',\n access: {\n create: access.isAdmin,\n delete: access.isAdmin,\n read: access.adminOrPublishedStatus,\n update: access.isAdmin,\n },\n admin: {\n description: ({ t }) =>\n // @ts-expect-error - translations are not typed in plugins yet\n t('plugin-ecommerce:variantsCollectionDescription'),\n group: false,\n useAsTitle: 'title',\n },\n authorship: false,\n fields,\n hooks: {\n beforeChange: [beforeChange({ productsSlug, variantOptionsSlug })],\n },\n labels: {\n plural: ({ t }) =>\n // @ts-expect-error - translations are not typed in plugins yet\n t('plugin-ecommerce:variants'),\n singular: ({ t }) =>\n // @ts-expect-error - translations are not typed in plugins yet\n t('plugin-ecommerce:variant'),\n },\n trash: true,\n versions: {\n drafts: {\n autosave: true,\n },\n },\n }\n\n return baseConfig\n}\n"],"names":["inventoryField","pricesField","variantsCollectionBeforeChange","beforeChange","validateOptions","createVariantsCollection","props","access","currenciesConfig","inventory","productsSlug","variantOptionsSlug","variantTypesSlug","supportedCurrencies","fields","name","type","admin","description","position","readOnly","relationTo","required","components","Field","path","custom","hasMany","label","validate","productsCollectionSlug","length","currencyOptions","forEach","currency","push","code","baseConfig","slug","create","isAdmin","delete","read","adminOrPublishedStatus","update","t","group","useAsTitle","authorship","hooks","labels","plural","singular","trash","versions","drafts","autosave"],"mappings":"AAIA,SAASA,cAAc,QAAQ,oCAAmC;AAClE,SAASC,WAAW,QAAQ,iCAAgC;AAC5D,SAASC,kCAAkCC,YAAY,QAAQ,0BAAyB;AACxF,SAASC,eAAe,QAAQ,6BAA4B;AAuB5D,OAAO,MAAMC,2BAA+D,CAACC;IAC3E,MAAM,EACJC,MAAM,EACNC,gBAAgB,EAChBC,YAAY,IAAI,EAChBC,eAAe,UAAU,EACzBC,qBAAqB,gBAAgB,EACrCC,mBAAmB,cAAc,EAClC,GAAGN,SAAS,CAAC;IACd,MAAM,EAAEO,mBAAmB,EAAE,GAAGL,oBAAoB,CAAC;IAErD,MAAMM,SAAkB;QACtB;YACEC,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLC,aACE;YACJ;QACF;QACA;YACEH,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLE,UAAU;gBACVC,UAAU;YACZ;YACAC,YAAYX;YACZY,UAAU;QACZ;QACA;YACE,wFAAwF;YACxF,gCAAgC;YAChC,8EAA8E;YAC9E,kEAAkE;YAClE,0GAA0G;YAC1GP,MAAM;YACNC,MAAM;YACNC,OAAO;gBACLM,YAAY;oBACVC,OAAO;wBACLC,MAAM;oBACR;gBACF;YACF;YACAC,QAAQ;gBACNhB;gBACAE;YACF;YACAe,SAAS;YACTC,OAAO;YACPP,YAAYV;YACZW,UAAU;YACVO,UAAUzB,gBAAgB;gBAAE0B,wBAAwBpB;YAAa;QACnE;WACID,YAAY;YAACT;SAAiB,GAAG,EAAE;KACxC;IAED,IAAIa,qBAAqBkB,UAAUlB,oBAAoBkB,MAAM,GAAG,GAAG;QACjE,MAAMC,kBAA4B,EAAE;QAEpCnB,oBAAoBoB,OAAO,CAAC,CAACC;YAC3BF,gBAAgBG,IAAI,CAACD,SAASE,IAAI;QACpC;QAEA,IAAI5B,kBAAkB;YACpBM,OAAOqB,IAAI,IAAIlC,YAAY;gBAAEO;YAAiB;QAChD;IACF;IAEA,MAAM6B,aAA+B;QACnCC,MAAM;QACN/B,QAAQ;YACNgC,QAAQhC,OAAOiC,OAAO;YACtBC,QAAQlC,OAAOiC,OAAO;YACtBE,MAAMnC,OAAOoC,sBAAsB;YACnCC,QAAQrC,OAAOiC,OAAO;QACxB;QACAvB,OAAO;YACLC,aAAa,CAAC,EAAE2B,CAAC,EAAE,GACjB,+DAA+D;gBAC/DA,EAAE;YACJC,OAAO;YACPC,YAAY;QACd;QACAC,YAAY;QACZlC;QACAmC,OAAO;YACL9C,cAAc;gBAACA,aAAa;oBAAEO;oBAAcC;gBAAmB;aAAG;QACpE;QACAuC,QAAQ;YACNC,QAAQ,CAAC,EAAEN,CAAC,EAAE,GACZ,+DAA+D;gBAC/DA,EAAE;YACJO,UAAU,CAAC,EAAEP,CAAC,EAAE,GACd,+DAA+D;gBAC/DA,EAAE;QACN;QACAQ,OAAO;QACPC,UAAU;YACRC,QAAQ;gBACNC,UAAU;YACZ;QACF;IACF;IAEA,OAAOnB;AACT,EAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"confirmOrder.d.ts","sourceRoot":"","sources":["../../src/endpoints/confirmOrder.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,QAAQ,EAGd,MAAM,SAAS,CAAA;AAEhB,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"confirmOrder.d.ts","sourceRoot":"","sources":["../../src/endpoints/confirmOrder.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,QAAQ,EAGd,MAAM,SAAS,CAAA;AAEhB,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAEnB,MAAM,mBAAmB,CAAA;AAS1B,KAAK,IAAI,GAAG;IACV;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gBAAgB,EAAE,gBAAgB,CAAA;IAClC;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,cAAc,CAAA;IAC7B;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;OAEG;IACH,kBAAkB,CAAC,EAAE,kBAAkB,CAAA;IACvC;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,KAAK,mBAAmB,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK,QAAQ,CAAC,SAAS,CAAC,CAAA;AAE9D;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,mBAgQ/B,CAAA"}
|
|
@@ -244,6 +244,7 @@ const finalizeTransactionOrder = async ({ cartID, cartsSlug, orderData, ordersSl
|
|
|
244
244
|
id: transactionID,
|
|
245
245
|
collection: transactionsSlug,
|
|
246
246
|
depth: 0,
|
|
247
|
+
overrideAccess: true,
|
|
247
248
|
req
|
|
248
249
|
});
|
|
249
250
|
if (!transaction || getRelationshipID(transaction.id) !== getRelationshipID(transactionID) || transaction.status !== 'processing') {
|
|
@@ -253,6 +254,7 @@ const finalizeTransactionOrder = async ({ cartID, cartsSlug, orderData, ordersSl
|
|
|
253
254
|
collection: ordersSlug,
|
|
254
255
|
depth: 0,
|
|
255
256
|
limit: 1,
|
|
257
|
+
overrideAccess: true,
|
|
256
258
|
pagination: false,
|
|
257
259
|
req,
|
|
258
260
|
where: {
|
|
@@ -272,6 +274,7 @@ const finalizeTransactionOrder = async ({ cartID, cartsSlug, orderData, ordersSl
|
|
|
272
274
|
transactionID
|
|
273
275
|
]
|
|
274
276
|
},
|
|
277
|
+
overrideAccess: true,
|
|
275
278
|
req
|
|
276
279
|
});
|
|
277
280
|
const orderID = requireDocumentID({
|
|
@@ -284,6 +287,7 @@ const finalizeTransactionOrder = async ({ cartID, cartsSlug, orderData, ordersSl
|
|
|
284
287
|
data: {
|
|
285
288
|
purchasedAt: new Date().toISOString()
|
|
286
289
|
},
|
|
290
|
+
overrideAccess: true,
|
|
287
291
|
req
|
|
288
292
|
});
|
|
289
293
|
await decrementInventory({
|
|
@@ -299,6 +303,7 @@ const finalizeTransactionOrder = async ({ cartID, cartsSlug, orderData, ordersSl
|
|
|
299
303
|
order: orderID,
|
|
300
304
|
status: 'succeeded'
|
|
301
305
|
},
|
|
306
|
+
overrideAccess: true,
|
|
302
307
|
req
|
|
303
308
|
});
|
|
304
309
|
return order;
|
|
@@ -338,6 +343,7 @@ const waitForCanonicalOrder = async ({ ordersSlug, req, transactionID, transacti
|
|
|
338
343
|
id: transactionID,
|
|
339
344
|
collection: transactionsSlug,
|
|
340
345
|
depth: 0,
|
|
346
|
+
overrideAccess: true,
|
|
341
347
|
req
|
|
342
348
|
});
|
|
343
349
|
if (!transaction) {
|
|
@@ -370,6 +376,7 @@ const findExactlyLinkedOrder = async ({ orderID, ordersSlug, req, transactionID
|
|
|
370
376
|
collection: ordersSlug,
|
|
371
377
|
depth: 0,
|
|
372
378
|
limit: 2,
|
|
379
|
+
overrideAccess: true,
|
|
373
380
|
pagination: false,
|
|
374
381
|
req,
|
|
375
382
|
where: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/endpoints/confirmOrder.ts"],"sourcesContent":["import {\n addDataAndFileToRequest,\n commitTransaction,\n type DefaultDocumentIDType,\n type Endpoint,\n initTransaction,\n killTransaction,\n} from 'payload'\n\nimport type { CurrenciesConfig, PaymentAdapter, ProductsValidation } from '../types/index.js'\n\ntype ConfirmOrderArgs = Parameters<PaymentAdapter['confirmOrder']>[0]\ntype FinalizeOrder = ConfirmOrderArgs['finalizeOrder']\ntype RecordValue = Record<string, unknown>\n\nconst SETTLEMENT_POLL_INTERVAL_MS = 25\nconst SETTLEMENT_WAIT_TIMEOUT_MS = 500\n\ntype Args = {\n /**\n * The slug of the carts collection, defaults to 'carts'.\n */\n cartsSlug?: string\n currenciesConfig: CurrenciesConfig\n /**\n * The slug of the customers collection, defaults to 'users'.\n */\n customersSlug?: string\n /**\n * The slug of the orders collection, defaults to 'orders'.\n */\n ordersSlug?: string\n paymentMethod: PaymentAdapter\n /**\n * The slug of the products collection, defaults to 'products'.\n */\n productsSlug?: string\n /**\n * Customise the validation used for checking products or variants before a transaction is created.\n */\n productsValidation?: ProductsValidation\n /**\n * The slug of the transactions collection, defaults to 'transactions'.\n */\n transactionsSlug?: string\n /**\n * The slug of the variants collection, defaults to 'variants'.\n */\n variantsSlug?: string\n}\n\ntype ConfirmOrderHandler = (args: Args) => Endpoint['handler']\n\n/**\n * Handles the endpoint for initiating payments. We will handle checking the amount and product and variant prices here before it is sent to the payment provider.\n * This is the first step in the payment process.\n */\nexport const confirmOrderHandler: ConfirmOrderHandler =\n ({\n cartsSlug = 'carts',\n currenciesConfig,\n customersSlug = 'users',\n ordersSlug = 'orders',\n paymentMethod,\n productsSlug = 'products',\n productsValidation,\n transactionsSlug = 'transactions',\n variantsSlug = 'variants',\n }) =>\n async (req) => {\n await addDataAndFileToRequest(req)\n\n const data = req.data\n const payload = req.payload\n const user = req.user\n\n let currency: string = currenciesConfig.defaultCurrency\n let cartID: DefaultDocumentIDType = data?.cartID\n let cart = undefined\n let customerEmail: string = user?.email ?? ''\n const cartSecret = data?.secret\n\n if (user) {\n if (user.cart?.docs && Array.isArray(user.cart.docs) && user.cart.docs.length > 0) {\n if (!cartID && user.cart.docs[0]) {\n // Use the user's cart instead\n if (typeof user.cart.docs[0] === 'object') {\n cartID = user.cart.docs[0].id\n cart = user.cart.docs[0]\n } else {\n cartID = user.cart.docs[0]\n }\n }\n }\n } else {\n // Get the email from the data if user is not available\n if (\n typeof data?.customerEmail === 'string' &&\n normalizeEmail(data.customerEmail).length > 0\n ) {\n customerEmail = data.customerEmail\n } else {\n return Response.json(\n {\n message: 'A customer email is required to make a purchase.',\n },\n {\n status: 400,\n },\n )\n }\n }\n\n if (!cart) {\n if (cartID) {\n // Add cart secret to query for guest cart access control\n if (cartSecret && typeof cartSecret === 'string') {\n req.query = req.query || {}\n req.query.secret = cartSecret\n }\n\n cart = await payload.findByID({\n id: cartID,\n collection: cartsSlug,\n depth: 2,\n overrideAccess: false,\n req,\n select: {\n id: true,\n currency: true,\n customerEmail: true,\n items: true,\n subtotal: true,\n },\n })\n\n if (!cart) {\n return Response.json(\n {\n message: `Cart with ID ${cartID} not found.`,\n },\n {\n status: 404,\n },\n )\n }\n } else {\n return Response.json(\n {\n message: 'Cart ID is required.',\n },\n {\n status: 400,\n },\n )\n }\n }\n\n if (cart.currency && typeof cart.currency === 'string') {\n currency = cart.currency\n }\n\n // Ensure the currency is provided or inferred in some way\n if (!currency) {\n return Response.json(\n {\n message: 'Currency is required.',\n },\n {\n status: 400,\n },\n )\n }\n\n let shouldCommit = false\n\n try {\n const canonicalCartID = cart.id\n if (\n canonicalCartID === null ||\n canonicalCartID === undefined ||\n (typeof canonicalCartID === 'string' && canonicalCartID.trim() === '')\n ) {\n throw new Error('Canonical cart ID is required.')\n }\n\n const cartCustomerEmail = 'customerEmail' in cart ? cart.customerEmail : undefined\n const normalizedCartCustomerEmail = normalizeEmail(cartCustomerEmail)\n const normalizedSubmittedCustomerEmail = normalizeEmail(customerEmail)\n const canonicalEmail = user\n ? normalizeEmail(user.email)\n : normalizedCartCustomerEmail || normalizedSubmittedCustomerEmail\n\n if (\n !user &&\n normalizedCartCustomerEmail &&\n normalizedSubmittedCustomerEmail !== normalizedCartCustomerEmail\n ) {\n throw new Error('Customer email does not match the cart.')\n }\n\n shouldCommit = await initTransaction(req)\n const hadActiveTransaction = Boolean(await req.transactionID)\n let didCallFinalizeOrder = false\n let didFinalizeOrder = false\n let didRecoverTransientConflict = false\n let finalizedTransactionID: DefaultDocumentIDType | undefined\n\n const finalizeOrder: FinalizeOrder = async ({ orderData, transactionID }) => {\n if (didCallFinalizeOrder) {\n throw new Error('Order settlement was already finalized for this request.')\n }\n\n didCallFinalizeOrder = true\n finalizedTransactionID = transactionID\n\n let order: RecordValue\n\n try {\n order = await finalizeTransactionOrder({\n cartID: canonicalCartID,\n cartsSlug,\n orderData,\n ordersSlug,\n productsSlug,\n req,\n transactionID,\n transactionsSlug,\n variantsSlug,\n })\n } catch (error) {\n if (!shouldCommit || !isTransientTransactionConflict(error)) {\n throw error\n }\n\n // MongoDB reports a losing transactional claim as a transient write conflict rather\n // than a null compare-and-set result. Leave the aborted snapshot before polling.\n await killTransaction(req)\n shouldCommit = false\n order = await waitForCanonicalOrder({\n ordersSlug,\n req,\n transactionID,\n transactionsSlug,\n })\n didRecoverTransientConflict = true\n }\n\n didFinalizeOrder = true\n\n return order\n }\n\n const paymentResponse = await paymentMethod.confirmOrder({\n cartsSlug,\n customersSlug,\n data: {\n ...data,\n cartID: canonicalCartID,\n customerEmail: canonicalEmail,\n },\n finalizeOrder,\n ordersSlug,\n req,\n transactionsSlug,\n })\n const hasActiveTransaction = Boolean(await req.transactionID)\n const transactionID = paymentResponse.transactionID\n\n if (!isValidDocumentID(transactionID)) {\n throw new Error('Transaction ID is missing or invalid.')\n }\n\n if (!didCallFinalizeOrder) {\n throw new Error('Payment adapter did not finalize the order.')\n }\n\n if (!didFinalizeOrder) {\n throw new Error('Order settlement did not complete successfully.')\n }\n\n if (\n didFinalizeOrder &&\n getRelationshipID(transactionID) !== getRelationshipID(finalizedTransactionID)\n ) {\n throw new Error('Confirmation response transaction does not match the settlement.')\n }\n\n if (hadActiveTransaction && !hasActiveTransaction && !didRecoverTransientConflict) {\n throw new Error('Order confirmation lost its active transaction.')\n }\n\n if (shouldCommit && hasActiveTransaction) {\n await commitTransaction(req)\n }\n\n return Response.json(paymentResponse)\n } catch (err) {\n if (shouldCommit) {\n await killTransaction(req)\n }\n\n payload.logger.error({ err, msg: 'Error confirming order.' })\n\n return Response.json(\n {\n message: 'Error confirming order.',\n },\n {\n status: 500,\n },\n )\n }\n }\n\nconst normalizeEmail = (email: unknown): string =>\n typeof email === 'string' ? email.trim().toLowerCase() : ''\n\nconst isValidDocumentID = (id: unknown): id is DefaultDocumentIDType =>\n (typeof id === 'number' && Number.isFinite(id)) ||\n (typeof id === 'string' && id.trim().length > 0)\n\nconst finalizeTransactionOrder = async ({\n cartID,\n cartsSlug,\n orderData,\n ordersSlug,\n productsSlug,\n req,\n transactionID,\n transactionsSlug,\n variantsSlug,\n}: {\n cartID: DefaultDocumentIDType\n cartsSlug: string\n orderData: Record<string, unknown>\n ordersSlug: string\n productsSlug: string\n req: ConfirmOrderArgs['req']\n transactionID: DefaultDocumentIDType\n transactionsSlug: string\n variantsSlug: string\n}): Promise<RecordValue> => {\n if (!isValidDocumentID(transactionID)) {\n throw new Error('Transaction ID is missing or invalid.')\n }\n\n if (!isRecord(orderData)) {\n throw new Error('Order data is missing or invalid.')\n }\n\n const claimedTransaction = await req.payload.db.updateOne({\n collection: transactionsSlug,\n data: { status: 'processing' },\n options: { atomic: true },\n req,\n where: {\n and: [\n { id: { equals: transactionID } },\n { status: { equals: 'pending' } },\n { order: { exists: false } },\n ],\n },\n })\n\n if (!claimedTransaction) {\n return waitForCanonicalOrder({ ordersSlug, req, transactionID, transactionsSlug })\n }\n\n if (getRelationshipID(claimedTransaction.id) !== getRelationshipID(transactionID)) {\n throw new Error('Claimed transaction does not match the requested transaction.')\n }\n\n const transaction = await req.payload.findByID({\n id: transactionID,\n collection: transactionsSlug,\n depth: 0,\n req,\n })\n\n if (\n !transaction ||\n getRelationshipID(transaction.id) !== getRelationshipID(transactionID) ||\n transaction.status !== 'processing'\n ) {\n throw new Error('Claimed transaction could not be loaded for settlement.')\n }\n\n const referencedOrders = await req.payload.find({\n collection: ordersSlug,\n depth: 0,\n limit: 1,\n pagination: false,\n req,\n where: { transactions: { equals: transactionID } },\n })\n\n if (referencedOrders.totalDocs !== 0 || referencedOrders.docs.length !== 0) {\n throw new Error('An order already references the claimed transaction.')\n }\n\n const order = (await req.payload.create({\n collection: ordersSlug,\n data: {\n ...orderData,\n transactions: [transactionID],\n },\n req,\n })) as RecordValue\n const orderID = requireDocumentID({ fieldName: 'order ID', value: order.id })\n\n await req.payload.update({\n id: cartID,\n collection: cartsSlug,\n data: { purchasedAt: new Date().toISOString() },\n req,\n })\n\n await decrementInventory({\n items: transaction.items,\n productsSlug,\n req,\n variantsSlug,\n })\n\n await req.payload.update({\n id: transactionID,\n collection: transactionsSlug,\n data: { order: orderID, status: 'succeeded' },\n req,\n })\n\n return order\n}\n\nconst decrementInventory = async ({\n items,\n productsSlug,\n req,\n variantsSlug,\n}: {\n items: unknown\n productsSlug: string\n req: ConfirmOrderArgs['req']\n variantsSlug: string\n}): Promise<void> => {\n if (!Array.isArray(items) || items.length === 0) {\n throw new Error('Inventory transaction items are missing or invalid.')\n }\n\n for (const item of items) {\n if (\n !isRecord(item) ||\n typeof item.quantity !== 'number' ||\n !Number.isFinite(item.quantity) ||\n item.quantity <= 0\n ) {\n throw new Error('Inventory item quantity is missing or invalid.')\n }\n\n const hasVariant = item.variant !== null && item.variant !== undefined\n const id = hasVariant ? item.variant : item.product\n\n if (!isValidDocumentID(id)) {\n throw new Error('Inventory item target is missing or invalid.')\n }\n\n const updatedInventory = await req.payload.db.updateOne({\n id,\n collection: hasVariant ? variantsSlug : productsSlug,\n data: { inventory: { $inc: item.quantity * -1 } },\n req,\n })\n\n if (!updatedInventory) {\n throw new Error('Inventory item could not be updated.')\n }\n }\n}\n\nconst waitForCanonicalOrder = async ({\n ordersSlug,\n req,\n transactionID,\n transactionsSlug,\n}: {\n ordersSlug: string\n req: ConfirmOrderArgs['req']\n transactionID: DefaultDocumentIDType\n transactionsSlug: string\n}): Promise<RecordValue> => {\n const deadline = Date.now() + SETTLEMENT_WAIT_TIMEOUT_MS\n\n do {\n const transaction = await req.payload.findByID({\n id: transactionID,\n collection: transactionsSlug,\n depth: 0,\n req,\n })\n\n if (!transaction) {\n throw new Error('Canonical transaction was not found.')\n }\n\n if (transaction.status === 'succeeded') {\n return findExactlyLinkedOrder({\n orderID: transaction.order,\n ordersSlug,\n req,\n transactionID,\n })\n }\n\n if (transaction.status !== 'pending' && transaction.status !== 'processing') {\n throw new Error('Transaction is not available for settlement.')\n }\n\n if (Date.now() >= deadline) {\n break\n }\n\n await new Promise<void>((resolve) =>\n setTimeout(resolve, Math.min(SETTLEMENT_POLL_INTERVAL_MS, deadline - Date.now())),\n )\n } while (Date.now() <= deadline)\n\n throw new Error('Transaction settlement did not complete in time.')\n}\n\nconst findExactlyLinkedOrder = async ({\n orderID,\n ordersSlug,\n req,\n transactionID,\n}: {\n orderID: unknown\n ordersSlug: string\n req: ConfirmOrderArgs['req']\n transactionID: DefaultDocumentIDType\n}): Promise<RecordValue> => {\n const canonicalOrderID = requireDocumentID({ fieldName: 'order ID', value: orderID })\n const result = await req.payload.find({\n collection: ordersSlug,\n depth: 0,\n limit: 2,\n pagination: false,\n req,\n where: { transactions: { equals: transactionID } },\n })\n\n if (\n result.totalDocs !== 1 ||\n result.docs.length !== 1 ||\n getRelationshipID(result.docs[0]?.id) !== getRelationshipID(canonicalOrderID)\n ) {\n throw new Error('Transaction does not have exactly one canonical linked order.')\n }\n\n return result.docs[0] as RecordValue\n}\n\nconst getRelationshipID = (value: unknown): string | undefined => {\n const id = isRecord(value) ? value.id : value\n\n return isValidDocumentID(id) ? String(id) : undefined\n}\n\nconst requireDocumentID = ({\n fieldName,\n value,\n}: {\n fieldName: string\n value: unknown\n}): DefaultDocumentIDType => {\n const id = isRecord(value) ? value.id : value\n\n if (!isValidDocumentID(id)) {\n throw new Error(`${fieldName} is missing or invalid.`)\n }\n\n return id\n}\n\nconst isRecord = (value: unknown): value is RecordValue =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nconst isTransientTransactionConflict = (error: unknown): boolean => {\n if (!isRecord(error)) {\n return false\n }\n\n return (\n error.code === 112 ||\n error.codeName === 'WriteConflict' ||\n (Array.isArray(error.errorLabels) && error.errorLabels.includes('TransientTransactionError'))\n )\n}\n"],"names":["addDataAndFileToRequest","commitTransaction","initTransaction","killTransaction","SETTLEMENT_POLL_INTERVAL_MS","SETTLEMENT_WAIT_TIMEOUT_MS","confirmOrderHandler","cartsSlug","currenciesConfig","customersSlug","ordersSlug","paymentMethod","productsSlug","productsValidation","transactionsSlug","variantsSlug","req","data","payload","user","currency","defaultCurrency","cartID","cart","undefined","customerEmail","email","cartSecret","secret","docs","Array","isArray","length","id","normalizeEmail","Response","json","message","status","query","findByID","collection","depth","overrideAccess","select","items","subtotal","shouldCommit","canonicalCartID","trim","Error","cartCustomerEmail","normalizedCartCustomerEmail","normalizedSubmittedCustomerEmail","canonicalEmail","hadActiveTransaction","Boolean","transactionID","didCallFinalizeOrder","didFinalizeOrder","didRecoverTransientConflict","finalizedTransactionID","finalizeOrder","orderData","order","finalizeTransactionOrder","error","isTransientTransactionConflict","waitForCanonicalOrder","paymentResponse","confirmOrder","hasActiveTransaction","isValidDocumentID","getRelationshipID","err","logger","msg","toLowerCase","Number","isFinite","isRecord","claimedTransaction","db","updateOne","options","atomic","where","and","equals","exists","transaction","referencedOrders","find","limit","pagination","transactions","totalDocs","create","orderID","requireDocumentID","fieldName","value","update","purchasedAt","Date","toISOString","decrementInventory","item","quantity","hasVariant","variant","product","updatedInventory","inventory","$inc","deadline","now","findExactlyLinkedOrder","Promise","resolve","setTimeout","Math","min","canonicalOrderID","result","String","code","codeName","errorLabels","includes"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/endpoints/confirmOrder.ts"],"sourcesContent":["import {\n addDataAndFileToRequest,\n commitTransaction,\n type DefaultDocumentIDType,\n type Endpoint,\n initTransaction,\n killTransaction,\n} from 'payload'\n\nimport type {\n CurrenciesConfig,\n PaymentAdapter,\n ProductsValidation,\n UserWithCart,\n} from '../types/index.js'\n\ntype ConfirmOrderArgs = Parameters<PaymentAdapter['confirmOrder']>[0]\ntype FinalizeOrder = ConfirmOrderArgs['finalizeOrder']\ntype RecordValue = Record<string, unknown>\n\nconst SETTLEMENT_POLL_INTERVAL_MS = 25\nconst SETTLEMENT_WAIT_TIMEOUT_MS = 500\n\ntype Args = {\n /**\n * The slug of the carts collection, defaults to 'carts'.\n */\n cartsSlug?: string\n currenciesConfig: CurrenciesConfig\n /**\n * The slug of the customers collection, defaults to 'users'.\n */\n customersSlug?: string\n /**\n * The slug of the orders collection, defaults to 'orders'.\n */\n ordersSlug?: string\n paymentMethod: PaymentAdapter\n /**\n * The slug of the products collection, defaults to 'products'.\n */\n productsSlug?: string\n /**\n * Customise the validation used for checking products or variants before a transaction is created.\n */\n productsValidation?: ProductsValidation\n /**\n * The slug of the transactions collection, defaults to 'transactions'.\n */\n transactionsSlug?: string\n /**\n * The slug of the variants collection, defaults to 'variants'.\n */\n variantsSlug?: string\n}\n\ntype ConfirmOrderHandler = (args: Args) => Endpoint['handler']\n\n/**\n * Handles the endpoint for initiating payments. We will handle checking the amount and product and variant prices here before it is sent to the payment provider.\n * This is the first step in the payment process.\n */\nexport const confirmOrderHandler: ConfirmOrderHandler =\n ({\n cartsSlug = 'carts',\n currenciesConfig,\n customersSlug = 'users',\n ordersSlug = 'orders',\n paymentMethod,\n productsSlug = 'products',\n productsValidation,\n transactionsSlug = 'transactions',\n variantsSlug = 'variants',\n }) =>\n async (req) => {\n await addDataAndFileToRequest(req)\n\n const data = req.data\n const payload = req.payload\n const user = req.user as null | UserWithCart\n\n let currency: string = currenciesConfig.defaultCurrency\n let cartID: DefaultDocumentIDType = data?.cartID\n let cart = undefined\n let customerEmail: string = user?.email ?? ''\n const cartSecret = data?.secret\n\n if (user) {\n if (user.cart?.docs && Array.isArray(user.cart.docs) && user.cart.docs.length > 0) {\n if (!cartID && user.cart.docs[0]) {\n // Use the user's cart instead\n if (typeof user.cart.docs[0] === 'object') {\n cartID = user.cart.docs[0].id\n cart = user.cart.docs[0]\n } else {\n cartID = user.cart.docs[0]\n }\n }\n }\n } else {\n // Get the email from the data if user is not available\n if (\n typeof data?.customerEmail === 'string' &&\n normalizeEmail(data.customerEmail).length > 0\n ) {\n customerEmail = data.customerEmail\n } else {\n return Response.json(\n {\n message: 'A customer email is required to make a purchase.',\n },\n {\n status: 400,\n },\n )\n }\n }\n\n if (!cart) {\n if (cartID) {\n // Add cart secret to query for guest cart access control\n if (cartSecret && typeof cartSecret === 'string') {\n req.query = req.query || {}\n req.query.secret = cartSecret\n }\n\n cart = await payload.findByID({\n id: cartID,\n collection: cartsSlug,\n depth: 2,\n overrideAccess: false,\n req,\n select: {\n id: true,\n currency: true,\n customerEmail: true,\n items: true,\n subtotal: true,\n },\n })\n\n if (!cart) {\n return Response.json(\n {\n message: `Cart with ID ${cartID} not found.`,\n },\n {\n status: 404,\n },\n )\n }\n } else {\n return Response.json(\n {\n message: 'Cart ID is required.',\n },\n {\n status: 400,\n },\n )\n }\n }\n\n if (cart.currency && typeof cart.currency === 'string') {\n currency = cart.currency\n }\n\n // Ensure the currency is provided or inferred in some way\n if (!currency) {\n return Response.json(\n {\n message: 'Currency is required.',\n },\n {\n status: 400,\n },\n )\n }\n\n let shouldCommit = false\n\n try {\n const canonicalCartID = cart.id\n if (\n canonicalCartID === null ||\n canonicalCartID === undefined ||\n (typeof canonicalCartID === 'string' && canonicalCartID.trim() === '')\n ) {\n throw new Error('Canonical cart ID is required.')\n }\n\n const cartCustomerEmail = 'customerEmail' in cart ? cart.customerEmail : undefined\n const normalizedCartCustomerEmail = normalizeEmail(cartCustomerEmail)\n const normalizedSubmittedCustomerEmail = normalizeEmail(customerEmail)\n const canonicalEmail = user\n ? normalizeEmail(user.email)\n : normalizedCartCustomerEmail || normalizedSubmittedCustomerEmail\n\n if (\n !user &&\n normalizedCartCustomerEmail &&\n normalizedSubmittedCustomerEmail !== normalizedCartCustomerEmail\n ) {\n throw new Error('Customer email does not match the cart.')\n }\n\n shouldCommit = await initTransaction(req)\n const hadActiveTransaction = Boolean(await req.transactionID)\n let didCallFinalizeOrder = false\n let didFinalizeOrder = false\n let didRecoverTransientConflict = false\n let finalizedTransactionID: DefaultDocumentIDType | undefined\n\n const finalizeOrder: FinalizeOrder = async ({ orderData, transactionID }) => {\n if (didCallFinalizeOrder) {\n throw new Error('Order settlement was already finalized for this request.')\n }\n\n didCallFinalizeOrder = true\n finalizedTransactionID = transactionID\n\n let order: RecordValue\n\n try {\n order = await finalizeTransactionOrder({\n cartID: canonicalCartID,\n cartsSlug,\n orderData,\n ordersSlug,\n productsSlug,\n req,\n transactionID,\n transactionsSlug,\n variantsSlug,\n })\n } catch (error) {\n if (!shouldCommit || !isTransientTransactionConflict(error)) {\n throw error\n }\n\n // MongoDB reports a losing transactional claim as a transient write conflict rather\n // than a null compare-and-set result. Leave the aborted snapshot before polling.\n await killTransaction(req)\n shouldCommit = false\n order = await waitForCanonicalOrder({\n ordersSlug,\n req,\n transactionID,\n transactionsSlug,\n })\n didRecoverTransientConflict = true\n }\n\n didFinalizeOrder = true\n\n return order\n }\n\n const paymentResponse = await paymentMethod.confirmOrder({\n cartsSlug,\n customersSlug,\n data: {\n ...data,\n cartID: canonicalCartID,\n customerEmail: canonicalEmail,\n },\n finalizeOrder,\n ordersSlug,\n req,\n transactionsSlug,\n })\n const hasActiveTransaction = Boolean(await req.transactionID)\n const transactionID = paymentResponse.transactionID\n\n if (!isValidDocumentID(transactionID)) {\n throw new Error('Transaction ID is missing or invalid.')\n }\n\n if (!didCallFinalizeOrder) {\n throw new Error('Payment adapter did not finalize the order.')\n }\n\n if (!didFinalizeOrder) {\n throw new Error('Order settlement did not complete successfully.')\n }\n\n if (\n didFinalizeOrder &&\n getRelationshipID(transactionID) !== getRelationshipID(finalizedTransactionID)\n ) {\n throw new Error('Confirmation response transaction does not match the settlement.')\n }\n\n if (hadActiveTransaction && !hasActiveTransaction && !didRecoverTransientConflict) {\n throw new Error('Order confirmation lost its active transaction.')\n }\n\n if (shouldCommit && hasActiveTransaction) {\n await commitTransaction(req)\n }\n\n return Response.json(paymentResponse)\n } catch (err) {\n if (shouldCommit) {\n await killTransaction(req)\n }\n\n payload.logger.error({ err, msg: 'Error confirming order.' })\n\n return Response.json(\n {\n message: 'Error confirming order.',\n },\n {\n status: 500,\n },\n )\n }\n }\n\nconst normalizeEmail = (email: unknown): string =>\n typeof email === 'string' ? email.trim().toLowerCase() : ''\n\nconst isValidDocumentID = (id: unknown): id is DefaultDocumentIDType =>\n (typeof id === 'number' && Number.isFinite(id)) ||\n (typeof id === 'string' && id.trim().length > 0)\n\nconst finalizeTransactionOrder = async ({\n cartID,\n cartsSlug,\n orderData,\n ordersSlug,\n productsSlug,\n req,\n transactionID,\n transactionsSlug,\n variantsSlug,\n}: {\n cartID: DefaultDocumentIDType\n cartsSlug: string\n orderData: Record<string, unknown>\n ordersSlug: string\n productsSlug: string\n req: ConfirmOrderArgs['req']\n transactionID: DefaultDocumentIDType\n transactionsSlug: string\n variantsSlug: string\n}): Promise<RecordValue> => {\n if (!isValidDocumentID(transactionID)) {\n throw new Error('Transaction ID is missing or invalid.')\n }\n\n if (!isRecord(orderData)) {\n throw new Error('Order data is missing or invalid.')\n }\n\n const claimedTransaction = await req.payload.db.updateOne({\n collection: transactionsSlug,\n data: { status: 'processing' },\n options: { atomic: true },\n req,\n where: {\n and: [\n { id: { equals: transactionID } },\n { status: { equals: 'pending' } },\n { order: { exists: false } },\n ],\n },\n })\n\n if (!claimedTransaction) {\n return waitForCanonicalOrder({ ordersSlug, req, transactionID, transactionsSlug })\n }\n\n if (getRelationshipID(claimedTransaction.id) !== getRelationshipID(transactionID)) {\n throw new Error('Claimed transaction does not match the requested transaction.')\n }\n\n const transaction = await req.payload.findByID({\n id: transactionID,\n collection: transactionsSlug,\n depth: 0,\n overrideAccess: true,\n req,\n })\n\n if (\n !transaction ||\n getRelationshipID(transaction.id) !== getRelationshipID(transactionID) ||\n transaction.status !== 'processing'\n ) {\n throw new Error('Claimed transaction could not be loaded for settlement.')\n }\n\n const referencedOrders = await req.payload.find({\n collection: ordersSlug,\n depth: 0,\n limit: 1,\n overrideAccess: true,\n pagination: false,\n req,\n where: { transactions: { equals: transactionID } },\n })\n\n if (referencedOrders.totalDocs !== 0 || referencedOrders.docs.length !== 0) {\n throw new Error('An order already references the claimed transaction.')\n }\n\n const order = (await req.payload.create({\n collection: ordersSlug,\n data: {\n ...orderData,\n transactions: [transactionID],\n },\n overrideAccess: true,\n req,\n })) as RecordValue\n const orderID = requireDocumentID({ fieldName: 'order ID', value: order.id })\n\n await req.payload.update({\n id: cartID,\n collection: cartsSlug,\n data: { purchasedAt: new Date().toISOString() },\n overrideAccess: true,\n req,\n })\n\n await decrementInventory({\n items: transaction.items,\n productsSlug,\n req,\n variantsSlug,\n })\n\n await req.payload.update({\n id: transactionID,\n collection: transactionsSlug,\n data: { order: orderID, status: 'succeeded' },\n overrideAccess: true,\n req,\n })\n\n return order\n}\n\nconst decrementInventory = async ({\n items,\n productsSlug,\n req,\n variantsSlug,\n}: {\n items: unknown\n productsSlug: string\n req: ConfirmOrderArgs['req']\n variantsSlug: string\n}): Promise<void> => {\n if (!Array.isArray(items) || items.length === 0) {\n throw new Error('Inventory transaction items are missing or invalid.')\n }\n\n for (const item of items) {\n if (\n !isRecord(item) ||\n typeof item.quantity !== 'number' ||\n !Number.isFinite(item.quantity) ||\n item.quantity <= 0\n ) {\n throw new Error('Inventory item quantity is missing or invalid.')\n }\n\n const hasVariant = item.variant !== null && item.variant !== undefined\n const id = hasVariant ? item.variant : item.product\n\n if (!isValidDocumentID(id)) {\n throw new Error('Inventory item target is missing or invalid.')\n }\n\n const updatedInventory = await req.payload.db.updateOne({\n id,\n collection: hasVariant ? variantsSlug : productsSlug,\n data: { inventory: { $inc: item.quantity * -1 } },\n req,\n })\n\n if (!updatedInventory) {\n throw new Error('Inventory item could not be updated.')\n }\n }\n}\n\nconst waitForCanonicalOrder = async ({\n ordersSlug,\n req,\n transactionID,\n transactionsSlug,\n}: {\n ordersSlug: string\n req: ConfirmOrderArgs['req']\n transactionID: DefaultDocumentIDType\n transactionsSlug: string\n}): Promise<RecordValue> => {\n const deadline = Date.now() + SETTLEMENT_WAIT_TIMEOUT_MS\n\n do {\n const transaction = await req.payload.findByID({\n id: transactionID,\n collection: transactionsSlug,\n depth: 0,\n overrideAccess: true,\n req,\n })\n\n if (!transaction) {\n throw new Error('Canonical transaction was not found.')\n }\n\n if (transaction.status === 'succeeded') {\n return findExactlyLinkedOrder({\n orderID: transaction.order,\n ordersSlug,\n req,\n transactionID,\n })\n }\n\n if (transaction.status !== 'pending' && transaction.status !== 'processing') {\n throw new Error('Transaction is not available for settlement.')\n }\n\n if (Date.now() >= deadline) {\n break\n }\n\n await new Promise<void>((resolve) =>\n setTimeout(resolve, Math.min(SETTLEMENT_POLL_INTERVAL_MS, deadline - Date.now())),\n )\n } while (Date.now() <= deadline)\n\n throw new Error('Transaction settlement did not complete in time.')\n}\n\nconst findExactlyLinkedOrder = async ({\n orderID,\n ordersSlug,\n req,\n transactionID,\n}: {\n orderID: unknown\n ordersSlug: string\n req: ConfirmOrderArgs['req']\n transactionID: DefaultDocumentIDType\n}): Promise<RecordValue> => {\n const canonicalOrderID = requireDocumentID({ fieldName: 'order ID', value: orderID })\n const result = await req.payload.find({\n collection: ordersSlug,\n depth: 0,\n limit: 2,\n overrideAccess: true,\n pagination: false,\n req,\n where: { transactions: { equals: transactionID } },\n })\n\n if (\n result.totalDocs !== 1 ||\n result.docs.length !== 1 ||\n getRelationshipID(result.docs[0]?.id) !== getRelationshipID(canonicalOrderID)\n ) {\n throw new Error('Transaction does not have exactly one canonical linked order.')\n }\n\n return result.docs[0] as RecordValue\n}\n\nconst getRelationshipID = (value: unknown): string | undefined => {\n const id = isRecord(value) ? value.id : value\n\n return isValidDocumentID(id) ? String(id) : undefined\n}\n\nconst requireDocumentID = ({\n fieldName,\n value,\n}: {\n fieldName: string\n value: unknown\n}): DefaultDocumentIDType => {\n const id = isRecord(value) ? value.id : value\n\n if (!isValidDocumentID(id)) {\n throw new Error(`${fieldName} is missing or invalid.`)\n }\n\n return id\n}\n\nconst isRecord = (value: unknown): value is RecordValue =>\n typeof value === 'object' && value !== null && !Array.isArray(value)\n\nconst isTransientTransactionConflict = (error: unknown): boolean => {\n if (!isRecord(error)) {\n return false\n }\n\n return (\n error.code === 112 ||\n error.codeName === 'WriteConflict' ||\n (Array.isArray(error.errorLabels) && error.errorLabels.includes('TransientTransactionError'))\n )\n}\n"],"names":["addDataAndFileToRequest","commitTransaction","initTransaction","killTransaction","SETTLEMENT_POLL_INTERVAL_MS","SETTLEMENT_WAIT_TIMEOUT_MS","confirmOrderHandler","cartsSlug","currenciesConfig","customersSlug","ordersSlug","paymentMethod","productsSlug","productsValidation","transactionsSlug","variantsSlug","req","data","payload","user","currency","defaultCurrency","cartID","cart","undefined","customerEmail","email","cartSecret","secret","docs","Array","isArray","length","id","normalizeEmail","Response","json","message","status","query","findByID","collection","depth","overrideAccess","select","items","subtotal","shouldCommit","canonicalCartID","trim","Error","cartCustomerEmail","normalizedCartCustomerEmail","normalizedSubmittedCustomerEmail","canonicalEmail","hadActiveTransaction","Boolean","transactionID","didCallFinalizeOrder","didFinalizeOrder","didRecoverTransientConflict","finalizedTransactionID","finalizeOrder","orderData","order","finalizeTransactionOrder","error","isTransientTransactionConflict","waitForCanonicalOrder","paymentResponse","confirmOrder","hasActiveTransaction","isValidDocumentID","getRelationshipID","err","logger","msg","toLowerCase","Number","isFinite","isRecord","claimedTransaction","db","updateOne","options","atomic","where","and","equals","exists","transaction","referencedOrders","find","limit","pagination","transactions","totalDocs","create","orderID","requireDocumentID","fieldName","value","update","purchasedAt","Date","toISOString","decrementInventory","item","quantity","hasVariant","variant","product","updatedInventory","inventory","$inc","deadline","now","findExactlyLinkedOrder","Promise","resolve","setTimeout","Math","min","canonicalOrderID","result","String","code","codeName","errorLabels","includes"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initiatePayment.d.ts","sourceRoot":"","sources":["../../src/endpoints/initiatePayment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuD,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAA;AAE5F,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,8BAA8B,
|
|
1
|
+
{"version":3,"file":"initiatePayment.d.ts","sourceRoot":"","sources":["../../src/endpoints/initiatePayment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuD,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAA;AAE5F,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,8BAA8B,EAE/B,MAAM,mBAAmB,CAAA;AAI1B,KAAK,IAAI,GAAG;IACV;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gBAAgB,EAAE,gBAAgB,CAAA;IAClC;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;OAGG;IACH,SAAS,CAAC,EAAE,8BAA8B,CAAC,WAAW,CAAC,CAAA;IACvD,aAAa,EAAE,cAAc,CAAA;IAC7B;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;OAEG;IACH,kBAAkB,CAAC,EAAE,kBAAkB,CAAA;IACvC;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,KAAK,eAAe,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK,QAAQ,CAAC,SAAS,CAAC,CAAA;AAE1D;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,eAmSlC,CAAA"}
|
|
@@ -113,6 +113,7 @@ import { defaultProductsValidation } from '../utilities/defaultProductsValidatio
|
|
|
113
113
|
id,
|
|
114
114
|
collection: productsSlug,
|
|
115
115
|
depth: 0,
|
|
116
|
+
overrideAccess: true,
|
|
116
117
|
select: {
|
|
117
118
|
inventory: true,
|
|
118
119
|
[priceField]: true
|
|
@@ -158,6 +159,7 @@ import { defaultProductsValidation } from '../utilities/defaultProductsValidatio
|
|
|
158
159
|
id,
|
|
159
160
|
collection: variantsSlug,
|
|
160
161
|
depth: 0,
|
|
162
|
+
overrideAccess: true,
|
|
161
163
|
select: {
|
|
162
164
|
inventory: true,
|
|
163
165
|
[priceField]: true
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/endpoints/initiatePayment.ts"],"sourcesContent":["import { addDataAndFileToRequest, type DefaultDocumentIDType, type Endpoint } from 'payload'\n\nimport type {\n CurrenciesConfig,\n PaymentAdapter,\n ProductsValidation,\n SanitizedEcommercePluginConfig,\n} from '../types/index.js'\n\nimport { defaultProductsValidation } from '../utilities/defaultProductsValidation.js'\n\ntype Args = {\n /**\n * The slug of the carts collection, defaults to 'carts'.\n */\n cartsSlug?: string\n currenciesConfig: CurrenciesConfig\n /**\n * The slug of the customers collection, defaults to 'users'.\n */\n customersSlug?: string\n /**\n * Track inventory stock for the products and variants.\n * Accepts an object to override the default field name.\n */\n inventory?: SanitizedEcommercePluginConfig['inventory']\n paymentMethod: PaymentAdapter\n /**\n * The slug of the products collection, defaults to 'products'.\n */\n productsSlug?: string\n /**\n * Customise the validation used for checking products or variants before a transaction is created.\n */\n productsValidation?: ProductsValidation\n /**\n * The slug of the transactions collection, defaults to 'transactions'.\n */\n transactionsSlug?: string\n /**\n * The slug of the variants collection, defaults to 'variants'.\n */\n variantsSlug?: string\n}\n\ntype InitiatePayment = (args: Args) => Endpoint['handler']\n\n/**\n * Handles the endpoint for initiating payments. We will handle checking the amount and product and variant prices here before it is sent to the payment provider.\n * This is the first step in the payment process.\n */\nexport const initiatePaymentHandler: InitiatePayment =\n ({\n cartsSlug = 'carts',\n currenciesConfig,\n customersSlug = 'users',\n paymentMethod,\n productsSlug = 'products',\n productsValidation,\n transactionsSlug = 'transactions',\n variantsSlug = 'variants',\n }) =>\n async (req) => {\n await addDataAndFileToRequest(req)\n const data = req.data\n const payload = req.payload\n const user = req.user\n\n let currency: string = currenciesConfig.defaultCurrency\n let cartID: DefaultDocumentIDType = data?.cartID\n let cart = undefined\n const billingAddress = data?.billingAddress\n const shippingAddress = data?.shippingAddress\n const cartSecret = data?.secret\n\n let customerEmail: string = user?.email ?? ''\n\n if (user) {\n if (user.cart?.docs && Array.isArray(user.cart.docs) && user.cart.docs.length > 0) {\n if (!cartID && user.cart.docs[0]) {\n // Use the user's cart instead\n if (typeof user.cart.docs[0] === 'object') {\n cartID = user.cart.docs[0].id\n cart = user.cart.docs[0]\n } else {\n cartID = user.cart.docs[0]\n }\n }\n }\n } else {\n // Get the email from the data if user is not available\n if (data?.customerEmail && typeof data.customerEmail === 'string') {\n customerEmail = data.customerEmail\n } else {\n return Response.json(\n {\n message: 'A customer email is required to make a purchase.',\n },\n {\n status: 400,\n },\n )\n }\n }\n\n if (!cart) {\n if (cartID) {\n // Add cart secret to query for guest cart access control\n if (cartSecret && typeof cartSecret === 'string') {\n req.query = req.query || {}\n req.query.secret = cartSecret\n }\n\n cart = await payload.findByID({\n id: cartID,\n collection: cartsSlug,\n depth: 2,\n overrideAccess: false,\n req,\n select: {\n id: true,\n currency: true,\n customerEmail: true,\n items: true,\n subtotal: true,\n },\n })\n\n if (!cart) {\n return Response.json(\n {\n message: `Cart with ID ${cartID} not found.`,\n },\n {\n status: 404,\n },\n )\n }\n } else {\n return Response.json(\n {\n message: 'Cart ID is required.',\n },\n {\n status: 400,\n },\n )\n }\n }\n\n if (cart.currency && typeof cart.currency === 'string') {\n currency = cart.currency\n }\n\n // Ensure the currency is provided or inferred in some way\n if (!currency) {\n return Response.json(\n {\n message: 'Currency is required.',\n },\n {\n status: 400,\n },\n )\n }\n\n // Ensure the selected currency is supported\n if (\n !currenciesConfig.supportedCurrencies.find(\n (c) => c.code.toLocaleLowerCase() === currency.toLocaleLowerCase(),\n )\n ) {\n return Response.json(\n {\n message: `Currency ${currency} is not supported.`,\n },\n {\n status: 400,\n },\n )\n }\n\n // Verify the cart is available and items are present in an array\n if (!cart || !cart.items || !Array.isArray(cart.items) || cart.items.length === 0) {\n return Response.json(\n {\n message: 'Cart is required and must contain at least one item.',\n },\n {\n status: 400,\n },\n )\n }\n\n for (const item of cart.items) {\n // Target field to check the price based on the currency so we can validate the total\n const priceField = `priceIn${currency.toUpperCase()}`\n const quantity = item.quantity || 1\n\n // If the item has a product but no variant, we assume the product has a price in the specified currency\n if (item.product && !item.variant) {\n const id = typeof item.product === 'object' ? item.product.id : item.product\n\n const product = await payload.findByID({\n id,\n collection: productsSlug,\n depth: 0,\n select: {\n inventory: true,\n [priceField]: true,\n },\n })\n\n if (!product) {\n return Response.json(\n {\n message: `Product with ID ${item.product} not found.`,\n },\n {\n status: 404,\n },\n )\n }\n\n try {\n if (productsValidation) {\n await productsValidation({ currenciesConfig, currency, product, quantity })\n } else {\n await defaultProductsValidation({\n currenciesConfig,\n currency,\n product,\n quantity,\n })\n }\n } catch (error) {\n payload.logger.error(\n error,\n 'Error validating product or variant during payment initiation.',\n )\n\n return Response.json(\n {\n message: error,\n ...(error instanceof Error ? { cause: error.cause } : {}),\n },\n {\n status: 400,\n },\n )\n }\n\n if (item.variant) {\n const id = typeof item.variant === 'object' ? item.variant.id : item.variant\n\n const variant = await payload.findByID({\n id,\n collection: variantsSlug,\n depth: 0,\n select: {\n inventory: true,\n [priceField]: true,\n },\n })\n\n if (!variant) {\n return Response.json(\n {\n message: `Variant with ID ${item.variant} not found.`,\n },\n {\n status: 404,\n },\n )\n }\n\n try {\n if (productsValidation) {\n await productsValidation({\n currenciesConfig,\n currency,\n product: item.product,\n quantity,\n variant,\n })\n } else {\n await defaultProductsValidation({\n currenciesConfig,\n currency,\n product: item.product,\n quantity,\n variant,\n })\n }\n } catch (error) {\n payload.logger.error(\n error,\n 'Error validating product or variant during payment initiation.',\n )\n\n return Response.json(\n {\n message: error,\n },\n {\n status: 400,\n },\n )\n }\n }\n }\n }\n\n try {\n const paymentResponse = await paymentMethod.initiatePayment({\n customersSlug,\n data: {\n billingAddress,\n cart,\n currency,\n customerEmail,\n shippingAddress,\n },\n req,\n transactionsSlug,\n })\n\n return Response.json(paymentResponse)\n } catch (error) {\n payload.logger.error(error, 'Error initiating payment.')\n\n return Response.json(\n {\n message: 'Error initiating payment.',\n },\n {\n status: 500,\n },\n )\n }\n }\n"],"names":["addDataAndFileToRequest","defaultProductsValidation","initiatePaymentHandler","cartsSlug","currenciesConfig","customersSlug","paymentMethod","productsSlug","productsValidation","transactionsSlug","variantsSlug","req","data","payload","user","currency","defaultCurrency","cartID","cart","undefined","billingAddress","shippingAddress","cartSecret","secret","customerEmail","email","docs","Array","isArray","length","id","Response","json","message","status","query","findByID","collection","depth","overrideAccess","select","items","subtotal","supportedCurrencies","find","c","code","toLocaleLowerCase","item","priceField","toUpperCase","quantity","product","variant","inventory","error","logger","Error","cause","paymentResponse","initiatePayment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/endpoints/initiatePayment.ts"],"sourcesContent":["import { addDataAndFileToRequest, type DefaultDocumentIDType, type Endpoint } from 'payload'\n\nimport type {\n CurrenciesConfig,\n PaymentAdapter,\n ProductsValidation,\n SanitizedEcommercePluginConfig,\n UserWithCart,\n} from '../types/index.js'\n\nimport { defaultProductsValidation } from '../utilities/defaultProductsValidation.js'\n\ntype Args = {\n /**\n * The slug of the carts collection, defaults to 'carts'.\n */\n cartsSlug?: string\n currenciesConfig: CurrenciesConfig\n /**\n * The slug of the customers collection, defaults to 'users'.\n */\n customersSlug?: string\n /**\n * Track inventory stock for the products and variants.\n * Accepts an object to override the default field name.\n */\n inventory?: SanitizedEcommercePluginConfig['inventory']\n paymentMethod: PaymentAdapter\n /**\n * The slug of the products collection, defaults to 'products'.\n */\n productsSlug?: string\n /**\n * Customise the validation used for checking products or variants before a transaction is created.\n */\n productsValidation?: ProductsValidation\n /**\n * The slug of the transactions collection, defaults to 'transactions'.\n */\n transactionsSlug?: string\n /**\n * The slug of the variants collection, defaults to 'variants'.\n */\n variantsSlug?: string\n}\n\ntype InitiatePayment = (args: Args) => Endpoint['handler']\n\n/**\n * Handles the endpoint for initiating payments. We will handle checking the amount and product and variant prices here before it is sent to the payment provider.\n * This is the first step in the payment process.\n */\nexport const initiatePaymentHandler: InitiatePayment =\n ({\n cartsSlug = 'carts',\n currenciesConfig,\n customersSlug = 'users',\n paymentMethod,\n productsSlug = 'products',\n productsValidation,\n transactionsSlug = 'transactions',\n variantsSlug = 'variants',\n }) =>\n async (req) => {\n await addDataAndFileToRequest(req)\n const data = req.data\n const payload = req.payload\n const user = req.user as null | UserWithCart\n\n let currency: string = currenciesConfig.defaultCurrency\n let cartID: DefaultDocumentIDType = data?.cartID\n let cart: any = undefined\n const billingAddress = data?.billingAddress\n const shippingAddress = data?.shippingAddress\n const cartSecret = data?.secret\n\n let customerEmail: string = user?.email ?? ''\n\n if (user) {\n if (user.cart?.docs && Array.isArray(user.cart.docs) && user.cart.docs.length > 0) {\n if (!cartID && user.cart.docs[0]) {\n // Use the user's cart instead\n if (typeof user.cart.docs[0] === 'object') {\n cartID = user.cart.docs[0].id\n cart = user.cart.docs[0]\n } else {\n cartID = user.cart.docs[0]\n }\n }\n }\n } else {\n // Get the email from the data if user is not available\n if (data?.customerEmail && typeof data.customerEmail === 'string') {\n customerEmail = data.customerEmail\n } else {\n return Response.json(\n {\n message: 'A customer email is required to make a purchase.',\n },\n {\n status: 400,\n },\n )\n }\n }\n\n if (!cart) {\n if (cartID) {\n // Add cart secret to query for guest cart access control\n if (cartSecret && typeof cartSecret === 'string') {\n req.query = req.query || {}\n req.query.secret = cartSecret\n }\n\n cart = await payload.findByID({\n id: cartID,\n collection: cartsSlug,\n depth: 2,\n overrideAccess: false,\n req,\n select: {\n id: true,\n currency: true,\n customerEmail: true,\n items: true,\n subtotal: true,\n },\n })\n\n if (!cart) {\n return Response.json(\n {\n message: `Cart with ID ${cartID} not found.`,\n },\n {\n status: 404,\n },\n )\n }\n } else {\n return Response.json(\n {\n message: 'Cart ID is required.',\n },\n {\n status: 400,\n },\n )\n }\n }\n\n if (cart.currency && typeof cart.currency === 'string') {\n currency = cart.currency\n }\n\n // Ensure the currency is provided or inferred in some way\n if (!currency) {\n return Response.json(\n {\n message: 'Currency is required.',\n },\n {\n status: 400,\n },\n )\n }\n\n // Ensure the selected currency is supported\n if (\n !currenciesConfig.supportedCurrencies.find(\n (c) => c.code.toLocaleLowerCase() === currency.toLocaleLowerCase(),\n )\n ) {\n return Response.json(\n {\n message: `Currency ${currency} is not supported.`,\n },\n {\n status: 400,\n },\n )\n }\n\n // Verify the cart is available and items are present in an array\n if (!cart || !cart.items || !Array.isArray(cart.items) || cart.items.length === 0) {\n return Response.json(\n {\n message: 'Cart is required and must contain at least one item.',\n },\n {\n status: 400,\n },\n )\n }\n\n for (const item of cart.items) {\n // Target field to check the price based on the currency so we can validate the total\n const priceField = `priceIn${currency.toUpperCase()}`\n const quantity = item.quantity || 1\n\n // If the item has a product but no variant, we assume the product has a price in the specified currency\n if (item.product && !item.variant) {\n const id = typeof item.product === 'object' ? item.product.id : item.product\n\n const product = await payload.findByID({\n id,\n collection: productsSlug,\n depth: 0,\n overrideAccess: true,\n select: {\n inventory: true,\n [priceField]: true,\n },\n })\n\n if (!product) {\n return Response.json(\n {\n message: `Product with ID ${item.product} not found.`,\n },\n {\n status: 404,\n },\n )\n }\n\n try {\n if (productsValidation) {\n await productsValidation({ currenciesConfig, currency, product, quantity })\n } else {\n await defaultProductsValidation({\n currenciesConfig,\n currency,\n product,\n quantity,\n })\n }\n } catch (error) {\n payload.logger.error(\n error,\n 'Error validating product or variant during payment initiation.',\n )\n\n return Response.json(\n {\n message: error,\n ...(error instanceof Error ? { cause: error.cause } : {}),\n },\n {\n status: 400,\n },\n )\n }\n\n if (item.variant) {\n const id = typeof item.variant === 'object' ? item.variant.id : item.variant\n\n const variant = await payload.findByID({\n id,\n collection: variantsSlug,\n depth: 0,\n overrideAccess: true,\n select: {\n inventory: true,\n [priceField]: true,\n },\n })\n\n if (!variant) {\n return Response.json(\n {\n message: `Variant with ID ${item.variant} not found.`,\n },\n {\n status: 404,\n },\n )\n }\n\n try {\n if (productsValidation) {\n await productsValidation({\n currenciesConfig,\n currency,\n product: item.product,\n quantity,\n variant,\n })\n } else {\n await defaultProductsValidation({\n currenciesConfig,\n currency,\n product: item.product,\n quantity,\n variant,\n })\n }\n } catch (error) {\n payload.logger.error(\n error,\n 'Error validating product or variant during payment initiation.',\n )\n\n return Response.json(\n {\n message: error,\n },\n {\n status: 400,\n },\n )\n }\n }\n }\n }\n\n try {\n const paymentResponse = await paymentMethod.initiatePayment({\n customersSlug,\n data: {\n billingAddress,\n cart,\n currency,\n customerEmail,\n shippingAddress,\n },\n req,\n transactionsSlug,\n })\n\n return Response.json(paymentResponse)\n } catch (error) {\n payload.logger.error(error, 'Error initiating payment.')\n\n return Response.json(\n {\n message: 'Error initiating payment.',\n },\n {\n status: 500,\n },\n )\n }\n }\n"],"names":["addDataAndFileToRequest","defaultProductsValidation","initiatePaymentHandler","cartsSlug","currenciesConfig","customersSlug","paymentMethod","productsSlug","productsValidation","transactionsSlug","variantsSlug","req","data","payload","user","currency","defaultCurrency","cartID","cart","undefined","billingAddress","shippingAddress","cartSecret","secret","customerEmail","email","docs","Array","isArray","length","id","Response","json","message","status","query","findByID","collection","depth","overrideAccess","select","items","subtotal","supportedCurrencies","find","c","code","toLocaleLowerCase","item","priceField","toUpperCase","quantity","product","variant","inventory","error","logger","Error","cause","paymentResponse","initiatePayment"],"mappings":"AAAA,SAASA,uBAAuB,QAAmD,UAAS;AAU5F,SAASC,yBAAyB,QAAQ,4CAA2C;AAsCrF;;;CAGC,GACD,OAAO,MAAMC,yBACX,CAAC,EACCC,YAAY,OAAO,EACnBC,gBAAgB,EAChBC,gBAAgB,OAAO,EACvBC,aAAa,EACbC,eAAe,UAAU,EACzBC,kBAAkB,EAClBC,mBAAmB,cAAc,EACjCC,eAAe,UAAU,EAC1B,GACD,OAAOC;QACL,MAAMX,wBAAwBW;QAC9B,MAAMC,OAAOD,IAAIC,IAAI;QACrB,MAAMC,UAAUF,IAAIE,OAAO;QAC3B,MAAMC,OAAOH,IAAIG,IAAI;QAErB,IAAIC,WAAmBX,iBAAiBY,eAAe;QACvD,IAAIC,SAAgCL,MAAMK;QAC1C,IAAIC,OAAYC;QAChB,MAAMC,iBAAiBR,MAAMQ;QAC7B,MAAMC,kBAAkBT,MAAMS;QAC9B,MAAMC,aAAaV,MAAMW;QAEzB,IAAIC,gBAAwBV,MAAMW,SAAS;QAE3C,IAAIX,MAAM;YACR,IAAIA,KAAKI,IAAI,EAAEQ,QAAQC,MAAMC,OAAO,CAACd,KAAKI,IAAI,CAACQ,IAAI,KAAKZ,KAAKI,IAAI,CAACQ,IAAI,CAACG,MAAM,GAAG,GAAG;gBACjF,IAAI,CAACZ,UAAUH,KAAKI,IAAI,CAACQ,IAAI,CAAC,EAAE,EAAE;oBAChC,8BAA8B;oBAC9B,IAAI,OAAOZ,KAAKI,IAAI,CAACQ,IAAI,CAAC,EAAE,KAAK,UAAU;wBACzCT,SAASH,KAAKI,IAAI,CAACQ,IAAI,CAAC,EAAE,CAACI,EAAE;wBAC7BZ,OAAOJ,KAAKI,IAAI,CAACQ,IAAI,CAAC,EAAE;oBAC1B,OAAO;wBACLT,SAASH,KAAKI,IAAI,CAACQ,IAAI,CAAC,EAAE;oBAC5B;gBACF;YACF;QACF,OAAO;YACL,uDAAuD;YACvD,IAAId,MAAMY,iBAAiB,OAAOZ,KAAKY,aAAa,KAAK,UAAU;gBACjEA,gBAAgBZ,KAAKY,aAAa;YACpC,OAAO;gBACL,OAAOO,SAASC,IAAI,CAClB;oBACEC,SAAS;gBACX,GACA;oBACEC,QAAQ;gBACV;YAEJ;QACF;QAEA,IAAI,CAAChB,MAAM;YACT,IAAID,QAAQ;gBACV,yDAAyD;gBACzD,IAAIK,cAAc,OAAOA,eAAe,UAAU;oBAChDX,IAAIwB,KAAK,GAAGxB,IAAIwB,KAAK,IAAI,CAAC;oBAC1BxB,IAAIwB,KAAK,CAACZ,MAAM,GAAGD;gBACrB;gBAEAJ,OAAO,MAAML,QAAQuB,QAAQ,CAAC;oBAC5BN,IAAIb;oBACJoB,YAAYlC;oBACZmC,OAAO;oBACPC,gBAAgB;oBAChB5B;oBACA6B,QAAQ;wBACNV,IAAI;wBACJf,UAAU;wBACVS,eAAe;wBACfiB,OAAO;wBACPC,UAAU;oBACZ;gBACF;gBAEA,IAAI,CAACxB,MAAM;oBACT,OAAOa,SAASC,IAAI,CAClB;wBACEC,SAAS,CAAC,aAAa,EAAEhB,OAAO,WAAW,CAAC;oBAC9C,GACA;wBACEiB,QAAQ;oBACV;gBAEJ;YACF,OAAO;gBACL,OAAOH,SAASC,IAAI,CAClB;oBACEC,SAAS;gBACX,GACA;oBACEC,QAAQ;gBACV;YAEJ;QACF;QAEA,IAAIhB,KAAKH,QAAQ,IAAI,OAAOG,KAAKH,QAAQ,KAAK,UAAU;YACtDA,WAAWG,KAAKH,QAAQ;QAC1B;QAEA,0DAA0D;QAC1D,IAAI,CAACA,UAAU;YACb,OAAOgB,SAASC,IAAI,CAClB;gBACEC,SAAS;YACX,GACA;gBACEC,QAAQ;YACV;QAEJ;QAEA,4CAA4C;QAC5C,IACE,CAAC9B,iBAAiBuC,mBAAmB,CAACC,IAAI,CACxC,CAACC,IAAMA,EAAEC,IAAI,CAACC,iBAAiB,OAAOhC,SAASgC,iBAAiB,KAElE;YACA,OAAOhB,SAASC,IAAI,CAClB;gBACEC,SAAS,CAAC,SAAS,EAAElB,SAAS,kBAAkB,CAAC;YACnD,GACA;gBACEmB,QAAQ;YACV;QAEJ;QAEA,iEAAiE;QACjE,IAAI,CAAChB,QAAQ,CAACA,KAAKuB,KAAK,IAAI,CAACd,MAAMC,OAAO,CAACV,KAAKuB,KAAK,KAAKvB,KAAKuB,KAAK,CAACZ,MAAM,KAAK,GAAG;YACjF,OAAOE,SAASC,IAAI,CAClB;gBACEC,SAAS;YACX,GACA;gBACEC,QAAQ;YACV;QAEJ;QAEA,KAAK,MAAMc,QAAQ9B,KAAKuB,KAAK,CAAE;YAC7B,qFAAqF;YACrF,MAAMQ,aAAa,CAAC,OAAO,EAAElC,SAASmC,WAAW,IAAI;YACrD,MAAMC,WAAWH,KAAKG,QAAQ,IAAI;YAElC,wGAAwG;YACxG,IAAIH,KAAKI,OAAO,IAAI,CAACJ,KAAKK,OAAO,EAAE;gBACjC,MAAMvB,KAAK,OAAOkB,KAAKI,OAAO,KAAK,WAAWJ,KAAKI,OAAO,CAACtB,EAAE,GAAGkB,KAAKI,OAAO;gBAE5E,MAAMA,UAAU,MAAMvC,QAAQuB,QAAQ,CAAC;oBACrCN;oBACAO,YAAY9B;oBACZ+B,OAAO;oBACPC,gBAAgB;oBAChBC,QAAQ;wBACNc,WAAW;wBACX,CAACL,WAAW,EAAE;oBAChB;gBACF;gBAEA,IAAI,CAACG,SAAS;oBACZ,OAAOrB,SAASC,IAAI,CAClB;wBACEC,SAAS,CAAC,gBAAgB,EAAEe,KAAKI,OAAO,CAAC,WAAW,CAAC;oBACvD,GACA;wBACElB,QAAQ;oBACV;gBAEJ;gBAEA,IAAI;oBACF,IAAI1B,oBAAoB;wBACtB,MAAMA,mBAAmB;4BAAEJ;4BAAkBW;4BAAUqC;4BAASD;wBAAS;oBAC3E,OAAO;wBACL,MAAMlD,0BAA0B;4BAC9BG;4BACAW;4BACAqC;4BACAD;wBACF;oBACF;gBACF,EAAE,OAAOI,OAAO;oBACd1C,QAAQ2C,MAAM,CAACD,KAAK,CAClBA,OACA;oBAGF,OAAOxB,SAASC,IAAI,CAClB;wBACEC,SAASsB;wBACT,GAAIA,iBAAiBE,QAAQ;4BAAEC,OAAOH,MAAMG,KAAK;wBAAC,IAAI,CAAC,CAAC;oBAC1D,GACA;wBACExB,QAAQ;oBACV;gBAEJ;gBAEA,IAAIc,KAAKK,OAAO,EAAE;oBAChB,MAAMvB,KAAK,OAAOkB,KAAKK,OAAO,KAAK,WAAWL,KAAKK,OAAO,CAACvB,EAAE,GAAGkB,KAAKK,OAAO;oBAE5E,MAAMA,UAAU,MAAMxC,QAAQuB,QAAQ,CAAC;wBACrCN;wBACAO,YAAY3B;wBACZ4B,OAAO;wBACPC,gBAAgB;wBAChBC,QAAQ;4BACNc,WAAW;4BACX,CAACL,WAAW,EAAE;wBAChB;oBACF;oBAEA,IAAI,CAACI,SAAS;wBACZ,OAAOtB,SAASC,IAAI,CAClB;4BACEC,SAAS,CAAC,gBAAgB,EAAEe,KAAKK,OAAO,CAAC,WAAW,CAAC;wBACvD,GACA;4BACEnB,QAAQ;wBACV;oBAEJ;oBAEA,IAAI;wBACF,IAAI1B,oBAAoB;4BACtB,MAAMA,mBAAmB;gCACvBJ;gCACAW;gCACAqC,SAASJ,KAAKI,OAAO;gCACrBD;gCACAE;4BACF;wBACF,OAAO;4BACL,MAAMpD,0BAA0B;gCAC9BG;gCACAW;gCACAqC,SAASJ,KAAKI,OAAO;gCACrBD;gCACAE;4BACF;wBACF;oBACF,EAAE,OAAOE,OAAO;wBACd1C,QAAQ2C,MAAM,CAACD,KAAK,CAClBA,OACA;wBAGF,OAAOxB,SAASC,IAAI,CAClB;4BACEC,SAASsB;wBACX,GACA;4BACErB,QAAQ;wBACV;oBAEJ;gBACF;YACF;QACF;QAEA,IAAI;YACF,MAAMyB,kBAAkB,MAAMrD,cAAcsD,eAAe,CAAC;gBAC1DvD;gBACAO,MAAM;oBACJQ;oBACAF;oBACAH;oBACAS;oBACAH;gBACF;gBACAV;gBACAF;YACF;YAEA,OAAOsB,SAASC,IAAI,CAAC2B;QACvB,EAAE,OAAOJ,OAAO;YACd1C,QAAQ2C,MAAM,CAACD,KAAK,CAACA,OAAO;YAE5B,OAAOxB,SAASC,IAAI,CAClB;gBACEC,SAAS;YACX,GACA;gBACEC,QAAQ;YACV;QAEJ;IACF,EAAC"}
|
package/dist/exports/types.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export type { CollectionOverride, CollectionSlugMap, ContextProps, CountryType, CurrenciesConfig, Currency, EcommerceCollections, EcommerceConfig, EcommerceContextType, EcommercePluginConfig, PaymentAdapter, PaymentAdapterArgs, PaymentAdapterClient, PaymentAdapterClientArgs, ProductsValidation, SanitizedEcommercePluginConfig, } from '../types/index.js';
|
|
1
|
+
export type { CollectionOverride, CollectionSlugMap, ContextProps, CountryType, CurrenciesConfig, Currency, EcommerceCollections, EcommerceConfig, EcommerceContextType, EcommercePluginConfig, PaymentAdapter, PaymentAdapterArgs, PaymentAdapterClient, PaymentAdapterClientArgs, ProductsValidation, SanitizedEcommercePluginConfig, UserWithCart, } from '../types/index.js';
|
|
2
2
|
export type { TypedEcommerce } from '../types/utilities.js';
|
|
3
3
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/exports/types.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,QAAQ,EACR,oBAAoB,EACpB,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EACrB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,wBAAwB,EACxB,kBAAkB,EAClB,8BAA8B,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/exports/types.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,QAAQ,EACR,oBAAoB,EACpB,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EACrB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,wBAAwB,EACxB,kBAAkB,EAClB,8BAA8B,EAC9B,YAAY,GACb,MAAM,mBAAmB,CAAA;AAE1B,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/exports/types.ts"],"sourcesContent":["export type {\n CollectionOverride,\n CollectionSlugMap,\n ContextProps,\n CountryType,\n CurrenciesConfig,\n Currency,\n EcommerceCollections,\n EcommerceConfig,\n EcommerceContextType,\n EcommercePluginConfig,\n PaymentAdapter,\n PaymentAdapterArgs,\n PaymentAdapterClient,\n PaymentAdapterClientArgs,\n ProductsValidation,\n SanitizedEcommercePluginConfig,\n} from '../types/index.js'\n\nexport type { TypedEcommerce } from '../types/utilities.js'\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/exports/types.ts"],"sourcesContent":["export type {\n CollectionOverride,\n CollectionSlugMap,\n ContextProps,\n CountryType,\n CurrenciesConfig,\n Currency,\n EcommerceCollections,\n EcommerceConfig,\n EcommerceContextType,\n EcommercePluginConfig,\n PaymentAdapter,\n PaymentAdapterArgs,\n PaymentAdapterClient,\n PaymentAdapterClientArgs,\n ProductsValidation,\n SanitizedEcommercePluginConfig,\n UserWithCart,\n} from '../types/index.js'\n\nexport type { TypedEcommerce } from '../types/utilities.js'\n"],"names":[],"mappings":"AAoBA,WAA2D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pricesField.d.ts","sourceRoot":"","sources":["../../src/fields/pricesField.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"pricesField.d.ts","sourceRoot":"","sources":["../../src/fields/pricesField.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAY,MAAM,SAAS,CAAA;AAEnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAIzD,KAAK,KAAK,GAAG;IACX;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,gBAAgB,EAAE,gBAAgB,CAAA;CACnC,CAAA;AAED,eAAO,MAAM,WAAW,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,UAAU,EAuDrD,CAAA"}
|
|
@@ -1,54 +1,54 @@
|
|
|
1
1
|
import { amountField } from './amountField.js';
|
|
2
2
|
export const pricesField = ({ conditionalPath, currenciesConfig })=>{
|
|
3
3
|
const currencies = currenciesConfig.supportedCurrencies;
|
|
4
|
-
const
|
|
4
|
+
const rows = currencies.map((currency)=>{
|
|
5
5
|
const name = `priceIn${currency.code}`;
|
|
6
6
|
const path = conditionalPath ? `${conditionalPath}.${name}Enabled` : `${name}Enabled`;
|
|
7
7
|
return {
|
|
8
|
-
type: '
|
|
9
|
-
admin: {
|
|
10
|
-
description: 'Prices for this product in different currencies.'
|
|
11
|
-
},
|
|
8
|
+
type: 'row',
|
|
12
9
|
fields: [
|
|
13
10
|
{
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
label: ({ t })=>// @ts-expect-error - translations are not typed in plugins yet
|
|
26
|
-
t('plugin-ecommerce:enableCurrencyPrice', {
|
|
27
|
-
currency: currency.code
|
|
28
|
-
})
|
|
29
|
-
},
|
|
30
|
-
amountField({
|
|
31
|
-
currenciesConfig,
|
|
32
|
-
currency,
|
|
33
|
-
overrides: {
|
|
34
|
-
name,
|
|
35
|
-
admin: {
|
|
36
|
-
condition: (_, siblingData)=>Boolean(siblingData?.[path]),
|
|
37
|
-
description: ({ t })=>// @ts-expect-error - translations are not typed in plugins yet
|
|
38
|
-
t('plugin-ecommerce:productPriceDescription')
|
|
39
|
-
},
|
|
40
|
-
// @ts-expect-error - translations are not typed in plugins yet
|
|
41
|
-
label: ({ t })=>t('plugin-ecommerce:priceIn', {
|
|
42
|
-
currency: currency.code
|
|
43
|
-
})
|
|
44
|
-
}
|
|
11
|
+
name: `${name}Enabled`,
|
|
12
|
+
type: 'checkbox',
|
|
13
|
+
admin: {
|
|
14
|
+
style: {
|
|
15
|
+
alignSelf: 'baseline',
|
|
16
|
+
flex: '0 0 auto'
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
label: ({ t })=>// @ts-expect-error - translations are not typed in plugins yet
|
|
20
|
+
t('plugin-ecommerce:enableCurrencyPrice', {
|
|
21
|
+
currency: currency.code
|
|
45
22
|
})
|
|
46
|
-
|
|
47
|
-
|
|
23
|
+
},
|
|
24
|
+
amountField({
|
|
25
|
+
currenciesConfig,
|
|
26
|
+
currency,
|
|
27
|
+
overrides: {
|
|
28
|
+
name,
|
|
29
|
+
admin: {
|
|
30
|
+
condition: (_, siblingData)=>Boolean(siblingData?.[path]),
|
|
31
|
+
description: ({ t })=>// @ts-expect-error - translations are not typed in plugins yet
|
|
32
|
+
t('plugin-ecommerce:productPriceDescription')
|
|
33
|
+
},
|
|
34
|
+
// @ts-expect-error - translations are not typed in plugins yet
|
|
35
|
+
label: ({ t })=>t('plugin-ecommerce:priceIn', {
|
|
36
|
+
currency: currency.code
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
})
|
|
48
40
|
]
|
|
49
41
|
};
|
|
50
42
|
});
|
|
51
|
-
return
|
|
43
|
+
return [
|
|
44
|
+
{
|
|
45
|
+
type: 'group',
|
|
46
|
+
admin: {
|
|
47
|
+
description: 'Prices for this product in different currencies.'
|
|
48
|
+
},
|
|
49
|
+
fields: rows
|
|
50
|
+
}
|
|
51
|
+
];
|
|
52
52
|
};
|
|
53
53
|
|
|
54
54
|
//# sourceMappingURL=pricesField.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/fields/pricesField.ts"],"sourcesContent":["import type { GroupField } from 'payload'\n\nimport type { CurrenciesConfig } from '../types/index.js'\n\nimport { amountField } from './amountField.js'\n\ntype Props = {\n /**\n * Use this to specify a path for the condition.\n */\n conditionalPath?: string\n currenciesConfig: CurrenciesConfig\n}\n\nexport const pricesField: (props: Props) => GroupField[] = ({\n conditionalPath,\n currenciesConfig,\n}) => {\n const currencies = currenciesConfig.supportedCurrencies\n\n const
|
|
1
|
+
{"version":3,"sources":["../../src/fields/pricesField.ts"],"sourcesContent":["import type { GroupField, RowField } from 'payload'\n\nimport type { CurrenciesConfig } from '../types/index.js'\n\nimport { amountField } from './amountField.js'\n\ntype Props = {\n /**\n * Use this to specify a path for the condition.\n */\n conditionalPath?: string\n currenciesConfig: CurrenciesConfig\n}\n\nexport const pricesField: (props: Props) => GroupField[] = ({\n conditionalPath,\n currenciesConfig,\n}) => {\n const currencies = currenciesConfig.supportedCurrencies\n\n const rows: RowField[] = currencies.map((currency) => {\n const name = `priceIn${currency.code}`\n\n const path = conditionalPath ? `${conditionalPath}.${name}Enabled` : `${name}Enabled`\n\n return {\n type: 'row',\n fields: [\n {\n name: `${name}Enabled`,\n type: 'checkbox',\n admin: {\n style: {\n alignSelf: 'baseline',\n flex: '0 0 auto',\n },\n },\n label: ({ t }) =>\n // @ts-expect-error - translations are not typed in plugins yet\n t('plugin-ecommerce:enableCurrencyPrice', { currency: currency.code }),\n },\n amountField({\n currenciesConfig,\n currency,\n overrides: {\n name,\n admin: {\n condition: (_, siblingData) => Boolean(siblingData?.[path]),\n description: ({ t }) =>\n // @ts-expect-error - translations are not typed in plugins yet\n t('plugin-ecommerce:productPriceDescription'),\n },\n // @ts-expect-error - translations are not typed in plugins yet\n label: ({ t }) => t('plugin-ecommerce:priceIn', { currency: currency.code }),\n },\n }),\n ],\n }\n })\n\n return [\n {\n type: 'group',\n admin: {\n description: 'Prices for this product in different currencies.',\n },\n fields: rows,\n },\n ]\n}\n"],"names":["amountField","pricesField","conditionalPath","currenciesConfig","currencies","supportedCurrencies","rows","map","currency","name","code","path","type","fields","admin","style","alignSelf","flex","label","t","overrides","condition","_","siblingData","Boolean","description"],"mappings":"AAIA,SAASA,WAAW,QAAQ,mBAAkB;AAU9C,OAAO,MAAMC,cAA8C,CAAC,EAC1DC,eAAe,EACfC,gBAAgB,EACjB;IACC,MAAMC,aAAaD,iBAAiBE,mBAAmB;IAEvD,MAAMC,OAAmBF,WAAWG,GAAG,CAAC,CAACC;QACvC,MAAMC,OAAO,CAAC,OAAO,EAAED,SAASE,IAAI,EAAE;QAEtC,MAAMC,OAAOT,kBAAkB,GAAGA,gBAAgB,CAAC,EAAEO,KAAK,OAAO,CAAC,GAAG,GAAGA,KAAK,OAAO,CAAC;QAErF,OAAO;YACLG,MAAM;YACNC,QAAQ;gBACN;oBACEJ,MAAM,GAAGA,KAAK,OAAO,CAAC;oBACtBG,MAAM;oBACNE,OAAO;wBACLC,OAAO;4BACLC,WAAW;4BACXC,MAAM;wBACR;oBACF;oBACAC,OAAO,CAAC,EAAEC,CAAC,EAAE,GACX,+DAA+D;wBAC/DA,EAAE,wCAAwC;4BAAEX,UAAUA,SAASE,IAAI;wBAAC;gBACxE;gBACAV,YAAY;oBACVG;oBACAK;oBACAY,WAAW;wBACTX;wBACAK,OAAO;4BACLO,WAAW,CAACC,GAAGC,cAAgBC,QAAQD,aAAa,CAACZ,KAAK;4BAC1Dc,aAAa,CAAC,EAAEN,CAAC,EAAE,GACjB,+DAA+D;gCAC/DA,EAAE;wBACN;wBACA,+DAA+D;wBAC/DD,OAAO,CAAC,EAAEC,CAAC,EAAE,GAAKA,EAAE,4BAA4B;gCAAEX,UAAUA,SAASE,IAAI;4BAAC;oBAC5E;gBACF;aACD;QACH;IACF;IAEA,OAAO;QACL;YACEE,MAAM;YACNE,OAAO;gBACLW,aAAa;YACf;YACAZ,QAAQP;QACV;KACD;AACH,EAAC"}
|
|
@@ -33,7 +33,9 @@ export const variantsFields = ({ variantsSlug = 'variants', variantTypesSlug = '
|
|
|
33
33
|
'prices',
|
|
34
34
|
'_status'
|
|
35
35
|
],
|
|
36
|
-
|
|
36
|
+
disabled: {
|
|
37
|
+
column: true
|
|
38
|
+
}
|
|
37
39
|
},
|
|
38
40
|
collection: variantsSlug,
|
|
39
41
|
label: ({ t })=>// @ts-expect-error - translations are not typed in plugins yet
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/fields/variantsFields.ts"],"sourcesContent":["import type { Field } from 'payload'\n\ntype Props = {\n /**\n * Slug of the variants collection, defaults to 'variants'.\n */\n variantsSlug?: string\n /**\n * Slug of the variant types collection, defaults to 'variantTypes'.\n */\n variantTypesSlug?: string\n}\n\nexport const variantsFields: (props: Props) => Field[] = ({\n variantsSlug = 'variants',\n variantTypesSlug = 'variantTypes',\n}) => {\n const fields: Field[] = [\n {\n name: 'enableVariants',\n type: 'checkbox',\n label: ({ t }) =>\n // @ts-expect-error - translations are not typed in plugins yet\n t('plugin-ecommerce:enableVariants'),\n },\n {\n name: 'variantTypes',\n type: 'relationship',\n admin: {\n condition: ({ enableVariants }) => Boolean(enableVariants),\n },\n hasMany: true,\n label: ({ t }) =>\n // @ts-expect-error - translations are not typed in plugins yet\n t('plugin-ecommerce:variantTypes'),\n relationTo: variantTypesSlug,\n },\n {\n name: 'variants',\n type: 'join',\n admin: {\n condition: ({ enableVariants, variantTypes }) => {\n const enabledVariants = Boolean(enableVariants)\n const hasManyVariantTypes = Array.isArray(variantTypes) && variantTypes.length > 0\n\n return enabledVariants && hasManyVariantTypes\n },\n defaultColumns: ['title', 'options', 'inventory', 'prices', '_status'],\n
|
|
1
|
+
{"version":3,"sources":["../../src/fields/variantsFields.ts"],"sourcesContent":["import type { Field } from 'payload'\n\ntype Props = {\n /**\n * Slug of the variants collection, defaults to 'variants'.\n */\n variantsSlug?: string\n /**\n * Slug of the variant types collection, defaults to 'variantTypes'.\n */\n variantTypesSlug?: string\n}\n\nexport const variantsFields: (props: Props) => Field[] = ({\n variantsSlug = 'variants',\n variantTypesSlug = 'variantTypes',\n}) => {\n const fields: Field[] = [\n {\n name: 'enableVariants',\n type: 'checkbox',\n label: ({ t }) =>\n // @ts-expect-error - translations are not typed in plugins yet\n t('plugin-ecommerce:enableVariants'),\n },\n {\n name: 'variantTypes',\n type: 'relationship',\n admin: {\n condition: ({ enableVariants }) => Boolean(enableVariants),\n },\n hasMany: true,\n label: ({ t }) =>\n // @ts-expect-error - translations are not typed in plugins yet\n t('plugin-ecommerce:variantTypes'),\n relationTo: variantTypesSlug,\n },\n {\n name: 'variants',\n type: 'join',\n admin: {\n condition: ({ enableVariants, variantTypes }) => {\n const enabledVariants = Boolean(enableVariants)\n const hasManyVariantTypes = Array.isArray(variantTypes) && variantTypes.length > 0\n\n return enabledVariants && hasManyVariantTypes\n },\n defaultColumns: ['title', 'options', 'inventory', 'prices', '_status'],\n disabled: { column: true },\n },\n collection: variantsSlug,\n label: ({ t }) =>\n // @ts-expect-error - translations are not typed in plugins yet\n t('plugin-ecommerce:availableVariants'),\n maxDepth: 2,\n on: 'product',\n },\n ]\n\n return fields\n}\n"],"names":["variantsFields","variantsSlug","variantTypesSlug","fields","name","type","label","t","admin","condition","enableVariants","Boolean","hasMany","relationTo","variantTypes","enabledVariants","hasManyVariantTypes","Array","isArray","length","defaultColumns","disabled","column","collection","maxDepth","on"],"mappings":"AAaA,OAAO,MAAMA,iBAA4C,CAAC,EACxDC,eAAe,UAAU,EACzBC,mBAAmB,cAAc,EAClC;IACC,MAAMC,SAAkB;QACtB;YACEC,MAAM;YACNC,MAAM;YACNC,OAAO,CAAC,EAAEC,CAAC,EAAE,GACX,+DAA+D;gBAC/DA,EAAE;QACN;QACA;YACEH,MAAM;YACNC,MAAM;YACNG,OAAO;gBACLC,WAAW,CAAC,EAAEC,cAAc,EAAE,GAAKC,QAAQD;YAC7C;YACAE,SAAS;YACTN,OAAO,CAAC,EAAEC,CAAC,EAAE,GACX,+DAA+D;gBAC/DA,EAAE;YACJM,YAAYX;QACd;QACA;YACEE,MAAM;YACNC,MAAM;YACNG,OAAO;gBACLC,WAAW,CAAC,EAAEC,cAAc,EAAEI,YAAY,EAAE;oBAC1C,MAAMC,kBAAkBJ,QAAQD;oBAChC,MAAMM,sBAAsBC,MAAMC,OAAO,CAACJ,iBAAiBA,aAAaK,MAAM,GAAG;oBAEjF,OAAOJ,mBAAmBC;gBAC5B;gBACAI,gBAAgB;oBAAC;oBAAS;oBAAW;oBAAa;oBAAU;iBAAU;gBACtEC,UAAU;oBAAEC,QAAQ;gBAAK;YAC3B;YACAC,YAAYtB;YACZK,OAAO,CAAC,EAAEC,CAAC,EAAE,GACX,+DAA+D;gBAC/DA,EAAE;YACJiB,UAAU;YACVC,IAAI;QACN;KACD;IAED,OAAOtB;AACT,EAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { Config } from 'payload';
|
|
2
1
|
import type { EcommercePluginConfig } from './types/index.js';
|
|
3
2
|
import { createAddressesCollection } from './collections/addresses/createAddressesCollection.js';
|
|
4
3
|
import { createCartsCollection } from './collections/carts/createCartsCollection.js';
|
|
@@ -8,7 +7,7 @@ import { createTransactionsCollection } from './collections/transactions/createT
|
|
|
8
7
|
import { createVariantOptionsCollection } from './collections/variants/createVariantOptionsCollection.js';
|
|
9
8
|
import { createVariantsCollection } from './collections/variants/createVariantsCollection/index.js';
|
|
10
9
|
import { createVariantTypesCollection } from './collections/variants/createVariantTypesCollection.js';
|
|
11
|
-
export declare const ecommercePlugin: (
|
|
10
|
+
export declare const ecommercePlugin: (options?: EcommercePluginConfig | undefined) => import("payload").Plugin;
|
|
12
11
|
export { createAddressesCollection, createCartsCollection, createOrdersCollection, createProductsCollection, createTransactionsCollection, createVariantOptionsCollection, createVariantsCollection, createVariantTypesCollection, };
|
|
13
12
|
export { addItem } from './collections/carts/operations/addItem.js';
|
|
14
13
|
export { clearCart } from './collections/carts/operations/clearCart.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,qBAAqB,EAAkC,MAAM,kBAAkB,CAAA;AAE7F,OAAO,EAAE,yBAAyB,EAAE,MAAM,sDAAsD,CAAA;AAChG,OAAO,EAAE,qBAAqB,EAAE,MAAM,8CAA8C,CAAA;AACpF,OAAO,EAAE,sBAAsB,EAAE,MAAM,gDAAgD,CAAA;AACvF,OAAO,EAAE,wBAAwB,EAAE,MAAM,oDAAoD,CAAA;AAC7F,OAAO,EAAE,4BAA4B,EAAE,MAAM,4DAA4D,CAAA;AACzG,OAAO,EAAE,8BAA8B,EAAE,MAAM,0DAA0D,CAAA;AACzG,OAAO,EAAE,wBAAwB,EAAE,MAAM,0DAA0D,CAAA;AACnG,OAAO,EAAE,4BAA4B,EAAE,MAAM,wDAAwD,CAAA;AAQrG,eAAO,MAAM,eAAe,2EAmV1B,CAAA;AAEF,OAAO,EACL,yBAAyB,EACzB,qBAAqB,EACrB,sBAAsB,EACtB,wBAAwB,EACxB,4BAA4B,EAC5B,8BAA8B,EAC9B,wBAAwB,EACxB,4BAA4B,GAC7B,CAAA;AAED,OAAO,EAAE,OAAO,EAAE,MAAM,2CAA2C,CAAA;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,6CAA6C,CAAA;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0DAA0D,CAAA;AACjG,OAAO,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAA;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAA;AAC3E,YAAY,EACV,WAAW,EACX,YAAY,EACZ,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,eAAe,EACf,cAAc,EACd,cAAc,GACf,MAAM,yCAAyC,CAAA;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAA;AACzE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAA;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA"}
|