@payloadcms/storage-r2 0.0.1-beta.0 → 3.58.0-internal.8775d75

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/dist/handleDelete.d.ts +8 -0
  2. package/dist/handleDelete.d.ts.map +1 -0
  3. package/dist/handleDelete.js +8 -0
  4. package/dist/handleDelete.js.map +1 -0
  5. package/dist/handleUpload.d.ts +11 -0
  6. package/dist/handleUpload.d.ts.map +1 -0
  7. package/dist/handleUpload.js +13 -0
  8. package/dist/handleUpload.js.map +1 -0
  9. package/dist/index.d.ts +15 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +59 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/staticHandler.d.ts +11 -0
  14. package/dist/staticHandler.d.ts.map +1 -0
  15. package/dist/staticHandler.js +29 -0
  16. package/dist/staticHandler.js.map +1 -0
  17. package/dist/types.d.ts +16 -0
  18. package/dist/types.d.ts.map +1 -0
  19. package/dist/types.js +3 -0
  20. package/dist/types.js.map +1 -0
  21. package/package.json +57 -1
  22. package/.prettierignore +0 -12
  23. package/.swcrc +0 -24
  24. package/README.md +0 -3
  25. package/eslint.config.js +0 -18
  26. package/src/addresses/addressesCollection.ts +0 -76
  27. package/src/addresses/defaultAddressFields.ts +0 -83
  28. package/src/addresses/defaultCountries.ts +0 -50
  29. package/src/carts/beforeChange.ts +0 -51
  30. package/src/carts/cartsCollection.ts +0 -146
  31. package/src/currencies/index.ts +0 -29
  32. package/src/endpoints/confirmOrder.ts +0 -312
  33. package/src/endpoints/initiatePayment.ts +0 -322
  34. package/src/exports/addresses.ts +0 -2
  35. package/src/exports/currencies.ts +0 -1
  36. package/src/exports/fields.ts +0 -5
  37. package/src/exports/orders.ts +0 -1
  38. package/src/exports/payments/stripe.ts +0 -1
  39. package/src/exports/plugin.ts +0 -1
  40. package/src/exports/products.ts +0 -1
  41. package/src/exports/react.ts +0 -8
  42. package/src/exports/transactions.ts +0 -1
  43. package/src/exports/translations.ts +0 -1
  44. package/src/exports/types.ts +0 -7
  45. package/src/exports/ui.ts +0 -3
  46. package/src/exports/variants.ts +0 -5
  47. package/src/fields/amountField.ts +0 -43
  48. package/src/fields/cartItemsField.ts +0 -84
  49. package/src/fields/currencyField.ts +0 -39
  50. package/src/fields/inventoryField.ts +0 -22
  51. package/src/fields/pricesField.ts +0 -65
  52. package/src/fields/statusField.ts +0 -57
  53. package/src/fields/variantsFields.ts +0 -56
  54. package/src/index.ts +0 -275
  55. package/src/orders/ordersCollection.ts +0 -157
  56. package/src/payments/adapters/stripe/confirmOrder.ts +0 -123
  57. package/src/payments/adapters/stripe/endpoints/webhooks.ts +0 -69
  58. package/src/payments/adapters/stripe/index.ts +0 -135
  59. package/src/payments/adapters/stripe/initiatePayment.ts +0 -131
  60. package/src/products/productsCollection.ts +0 -78
  61. package/src/react/provider/index.tsx +0 -893
  62. package/src/react/provider/types.ts +0 -184
  63. package/src/react/provider/utilities.ts +0 -22
  64. package/src/transactions/transactionsCollection.ts +0 -166
  65. package/src/translations/en.ts +0 -64
  66. package/src/translations/index.ts +0 -11
  67. package/src/translations/translation-schema.json +0 -35
  68. package/src/types.ts +0 -403
  69. package/src/ui/PriceInput/FormattedInput.tsx +0 -134
  70. package/src/ui/PriceInput/index.scss +0 -28
  71. package/src/ui/PriceInput/index.tsx +0 -43
  72. package/src/ui/PriceInput/utilities.ts +0 -46
  73. package/src/ui/PriceRowLabel/index.css +0 -13
  74. package/src/ui/PriceRowLabel/index.tsx +0 -56
  75. package/src/ui/VariantOptionsSelector/ErrorBox.tsx +0 -27
  76. package/src/ui/VariantOptionsSelector/OptionsSelect.tsx +0 -78
  77. package/src/ui/VariantOptionsSelector/index.css +0 -37
  78. package/src/ui/VariantOptionsSelector/index.tsx +0 -83
  79. package/src/utilities/defaultProductsValidation.ts +0 -42
  80. package/src/utilities/errorCodes.ts +0 -14
  81. package/src/utilities/getCollectionSlugMap.ts +0 -84
  82. package/src/utilities/sanitizePluginConfig.ts +0 -80
  83. package/src/variants/variantOptionsCollection.ts +0 -59
  84. package/src/variants/variantTypesCollection.ts +0 -55
  85. package/src/variants/variantsCollection/hooks/beforeChange.ts +0 -47
  86. package/src/variants/variantsCollection/hooks/validateOptions.ts +0 -72
  87. package/src/variants/variantsCollection/index.ts +0 -119
  88. package/tsconfig.json +0 -7
  89. package/tsconfig.tsbuildinfo +0 -1
@@ -1,56 +0,0 @@
1
- import type { Field } from 'payload'
2
-
3
- type Props = {
4
- /**
5
- * Slug of the variants collection, defaults to 'variants'.
6
- */
7
- variantsSlug?: string
8
- /**
9
- * Slug of the variant types collection, defaults to 'variantTypes'.
10
- */
11
- variantTypesSlug?: string
12
- }
13
-
14
- export const variantsFields: (props: Props) => Field[] = ({
15
- variantsSlug = 'variants',
16
- variantTypesSlug = 'variantTypes',
17
- }) => {
18
- const fields: Field[] = [
19
- {
20
- name: 'enableVariants',
21
- type: 'checkbox',
22
- label: ({ t }) =>
23
- // @ts-expect-error - translations are not typed in plugins yet
24
- t('plugin-ecommerce:enableVariants'),
25
- },
26
- {
27
- name: 'variantTypes',
28
- type: 'relationship',
29
- admin: {
30
- condition: ({ enableVariants }) => Boolean(enableVariants),
31
- },
32
- hasMany: true,
33
- label: ({ t }) =>
34
- // @ts-expect-error - translations are not typed in plugins yet
35
- t('plugin-ecommerce:variantTypes'),
36
- relationTo: variantTypesSlug,
37
- },
38
- {
39
- name: 'variants',
40
- type: 'join',
41
- admin: {
42
- condition: ({ enableVariants }) => Boolean(enableVariants),
43
- defaultColumns: ['title', 'options', 'inventory', 'prices'],
44
- disableListColumn: true,
45
- },
46
- collection: variantsSlug,
47
- label: ({ t }) =>
48
- // @ts-expect-error - translations are not typed in plugins yet
49
- t('plugin-ecommerce:availableVariants'),
50
- maxDepth: 2,
51
- on: 'product',
52
- },
53
- ]
54
-
55
- return fields
56
- }
package/src/index.ts DELETED
@@ -1,275 +0,0 @@
1
- import type { Config, Endpoint } from 'payload'
2
-
3
- import { deepMergeSimple } from 'payload/shared'
4
-
5
- import type { EcommercePluginConfig, SanitizedEcommercePluginConfig } from './types.js'
6
-
7
- import { addressesCollection } from './addresses/addressesCollection.js'
8
- import { cartsCollection } from './carts/cartsCollection.js'
9
- import { confirmOrderHandler } from './endpoints/confirmOrder.js'
10
- import { initiatePaymentHandler } from './endpoints/initiatePayment.js'
11
- import { ordersCollection } from './orders/ordersCollection.js'
12
- import { productsCollection } from './products/productsCollection.js'
13
- import { transactionsCollection } from './transactions/transactionsCollection.js'
14
- import { translations } from './translations/index.js'
15
- import { getCollectionSlugMap } from './utilities/getCollectionSlugMap.js'
16
- import { sanitizePluginConfig } from './utilities/sanitizePluginConfig.js'
17
- import { variantOptionsCollection } from './variants/variantOptionsCollection.js'
18
- import { variantsCollection } from './variants/variantsCollection/index.js'
19
- import { variantTypesCollection } from './variants/variantTypesCollection.js'
20
-
21
- export const ecommercePlugin =
22
- (pluginConfig?: EcommercePluginConfig) =>
23
- (incomingConfig: Config): Config => {
24
- if (!pluginConfig) {
25
- return incomingConfig
26
- }
27
-
28
- const sanitizedPluginConfig = sanitizePluginConfig({ pluginConfig })
29
- /**
30
- * Used to keep track of the slugs of collections in case they are overridden by the user.
31
- */
32
- const collectionSlugMap = getCollectionSlugMap({ sanitizedPluginConfig })
33
-
34
- // Ensure collections exists
35
- if (!incomingConfig.collections) {
36
- incomingConfig.collections = []
37
- }
38
-
39
- // Controls whether variants are enabled in the plugin. This is toggled to true under products config
40
- let enableVariants = false
41
-
42
- const currenciesConfig: Required<SanitizedEcommercePluginConfig['currencies']> =
43
- sanitizedPluginConfig.currencies
44
-
45
- let addressFields
46
-
47
- if (sanitizedPluginConfig.addresses) {
48
- const collectionOverrides =
49
- typeof sanitizedPluginConfig.addresses === 'object'
50
- ? sanitizedPluginConfig.addresses.collectionOverride
51
- : undefined
52
-
53
- addressFields = sanitizedPluginConfig.addresses.addressFields
54
-
55
- const supportedCountries = sanitizedPluginConfig.addresses.supportedCountries
56
-
57
- const addresses = addressesCollection({
58
- addressFields,
59
- customersSlug: collectionSlugMap.customers,
60
- overrides: collectionOverrides,
61
- supportedCountries,
62
- })
63
-
64
- incomingConfig.collections.push(addresses)
65
- }
66
-
67
- if (sanitizedPluginConfig.products) {
68
- const productsConfig =
69
- typeof sanitizedPluginConfig.products === 'boolean'
70
- ? {
71
- variants: true,
72
- }
73
- : sanitizedPluginConfig.products
74
-
75
- enableVariants = Boolean(productsConfig.variants)
76
-
77
- if (productsConfig.variants) {
78
- const overrides =
79
- typeof productsConfig.variants === 'boolean' ? undefined : productsConfig.variants
80
-
81
- const variants = variantsCollection({
82
- currenciesConfig,
83
- inventory: sanitizedPluginConfig.inventory,
84
- overrides: overrides?.variantsCollection,
85
- productsSlug: collectionSlugMap.products,
86
- variantOptionsSlug: collectionSlugMap.variantOptions,
87
- })
88
-
89
- const variantTypes = variantTypesCollection({
90
- overrides: overrides?.variantTypesCollection,
91
- variantOptionsSlug: collectionSlugMap.variantOptions,
92
- })
93
-
94
- const variantOptions = variantOptionsCollection({
95
- overrides: overrides?.variantOptionsCollection,
96
- variantTypesSlug: collectionSlugMap.variantTypes,
97
- })
98
-
99
- incomingConfig.collections.push(variants, variantTypes, variantOptions)
100
- }
101
-
102
- const products = productsCollection({
103
- currenciesConfig,
104
- enableVariants,
105
- inventory: sanitizedPluginConfig.inventory,
106
- variantsSlug: collectionSlugMap.variants,
107
- variantTypesSlug: collectionSlugMap.variantTypes,
108
- ...('productsCollection' in productsConfig && productsConfig.productsCollection
109
- ? { overrides: productsConfig.productsCollection }
110
- : {}),
111
- })
112
-
113
- incomingConfig.collections.push(products)
114
-
115
- if (sanitizedPluginConfig.carts) {
116
- const carts = cartsCollection({
117
- currenciesConfig,
118
- customersSlug: collectionSlugMap.customers,
119
- enableVariants: Boolean(productsConfig.variants),
120
- overrides:
121
- sanitizedPluginConfig.carts === true
122
- ? undefined
123
- : sanitizedPluginConfig.carts.cartsCollection,
124
- productsSlug: collectionSlugMap.products,
125
- variantsSlug: collectionSlugMap.variants,
126
- })
127
-
128
- incomingConfig.collections.push(carts)
129
- }
130
- }
131
-
132
- if (sanitizedPluginConfig.orders) {
133
- const orders = ordersCollection({
134
- addressFields,
135
- currenciesConfig,
136
- customersSlug: collectionSlugMap.customers,
137
- enableVariants,
138
- overrides:
139
- sanitizedPluginConfig.orders === true
140
- ? undefined
141
- : sanitizedPluginConfig.orders.ordersCollection,
142
- productsSlug: collectionSlugMap.products,
143
- variantsSlug: collectionSlugMap.variants,
144
- })
145
- incomingConfig.collections.push(orders)
146
- }
147
-
148
- const paymentMethods = sanitizedPluginConfig.payments.paymentMethods
149
-
150
- if (sanitizedPluginConfig.payments) {
151
- if (paymentMethods.length) {
152
- if (!Array.isArray(incomingConfig.endpoints)) {
153
- incomingConfig.endpoints = []
154
- }
155
-
156
- const productsValidation =
157
- (typeof sanitizedPluginConfig.products === 'object' &&
158
- sanitizedPluginConfig.products.validation) ||
159
- undefined
160
-
161
- paymentMethods.forEach((paymentMethod) => {
162
- const methodPath = `/payments/${paymentMethod.name}`
163
- const endpoints: Endpoint[] = []
164
-
165
- const initiatePayment: Endpoint = {
166
- handler: initiatePaymentHandler({
167
- currenciesConfig,
168
- inventory: sanitizedPluginConfig.inventory,
169
- paymentMethod,
170
- productsSlug: collectionSlugMap.products,
171
- productsValidation,
172
- transactionsSlug: collectionSlugMap.transactions,
173
- variantsSlug: collectionSlugMap.variants,
174
- }),
175
- method: 'post',
176
- path: `${methodPath}/initiate`,
177
- }
178
-
179
- const confirmOrder: Endpoint = {
180
- handler: confirmOrderHandler({
181
- cartsSlug: collectionSlugMap.carts,
182
- currenciesConfig,
183
- ordersSlug: collectionSlugMap.orders,
184
- paymentMethod,
185
- productsValidation,
186
- transactionsSlug: collectionSlugMap.transactions,
187
- }),
188
- method: 'post',
189
- path: `${methodPath}/confirm-order`,
190
- }
191
-
192
- endpoints.push(initiatePayment, confirmOrder)
193
-
194
- // Attach any additional endpoints defined in the payment method
195
- if (paymentMethod.endpoints && paymentMethod.endpoints.length > 0) {
196
- const methodEndpoints = paymentMethod.endpoints.map((endpoint) => {
197
- const path = endpoint.path.startsWith('/') ? endpoint.path : `/${endpoint.path}`
198
-
199
- return {
200
- ...endpoint,
201
- path: `${methodPath}${path}`,
202
- }
203
- })
204
-
205
- endpoints.push(...methodEndpoints)
206
- }
207
-
208
- incomingConfig.endpoints!.push(...endpoints)
209
- })
210
- }
211
- }
212
-
213
- if (sanitizedPluginConfig.transactions) {
214
- const transactions = transactionsCollection({
215
- addressFields,
216
- cartsSlug: collectionSlugMap.carts,
217
- currenciesConfig,
218
- customersSlug: collectionSlugMap.customers,
219
- enableVariants,
220
- ordersSlug: collectionSlugMap.orders,
221
- paymentMethods,
222
- productsSlug: collectionSlugMap.products,
223
- variantsSlug: collectionSlugMap.variants,
224
- })
225
-
226
- incomingConfig.collections.push(transactions)
227
- }
228
-
229
- if (!incomingConfig.i18n) {
230
- incomingConfig.i18n = {}
231
- }
232
-
233
- if (!incomingConfig.i18n?.translations) {
234
- incomingConfig.i18n.translations = {}
235
- }
236
-
237
- incomingConfig.i18n.translations = deepMergeSimple(
238
- translations,
239
- incomingConfig.i18n?.translations,
240
- )
241
-
242
- // incomingConfig.typescript = {
243
- // ...incomingConfig.typescript,
244
- // schema: [
245
- // ({ jsonSchema }) => {
246
- // if (jsonSchema.definitions) {
247
- // const supportedCurrencies = pluginConfig.currencies?.supportedCurrencies || []
248
- // const defaultCurrency = pluginConfig.currencies?.defaultCurrency || 'USD'
249
-
250
- // // Generate JSON Schema4 for supported currencies
251
-
252
- // const currenciesSchema = {
253
- // type: 'array',
254
- // description: 'A list of supported currency codes.',
255
- // items: {
256
- // type: 'string',
257
- // enum: (supportedCurrencies || []).map((currency) => currency.code),
258
- // },
259
- // title: 'Supported Currencies',
260
- // }
261
-
262
- // console.log({ defs: jsonSchema.definitions })
263
-
264
- // jsonSchema.definitions.SupportedCurrencies = currenciesSchema
265
- // }
266
-
267
- // return jsonSchema
268
- // },
269
- // ],
270
- // }
271
-
272
- return {
273
- ...incomingConfig,
274
- }
275
- }
@@ -1,157 +0,0 @@
1
- import type { CollectionConfig, Field } from 'payload'
2
-
3
- import type { CurrenciesConfig, FieldsOverride } from '../types.js'
4
-
5
- import { amountField } from '../fields/amountField.js'
6
- import { cartItemsField } from '../fields/cartItemsField.js'
7
- import { currencyField } from '../fields/currencyField.js'
8
-
9
- type Props = {
10
- /**
11
- * Array of fields used for capturing the shipping address data.
12
- */
13
- addressFields?: Field[]
14
- currenciesConfig?: CurrenciesConfig
15
- /**
16
- * Slug of the customers collection, defaults to 'users'.
17
- */
18
- customersSlug?: string
19
- enableVariants?: boolean
20
- overrides?: { fields?: FieldsOverride } & Partial<Omit<CollectionConfig, 'fields'>>
21
- /**
22
- * Slug of the products collection, defaults to 'products'.
23
- */
24
- productsSlug?: string
25
- /**
26
- * Slug of the transactions collection, defaults to 'transactions'.
27
- */
28
- transactionsSlug?: string
29
- /**
30
- * Slug of the variants collection, defaults to 'variants'.
31
- */
32
- variantsSlug?: string
33
- }
34
-
35
- export const ordersCollection: (props?: Props) => CollectionConfig = (props) => {
36
- const {
37
- addressFields,
38
- currenciesConfig,
39
- customersSlug = 'users',
40
- enableVariants = false,
41
- overrides,
42
- productsSlug = 'products',
43
- transactionsSlug = 'transactions',
44
- variantsSlug = 'variants',
45
- } = props || {}
46
- const fieldsOverride = overrides?.fields
47
-
48
- const defaultFields: Field[] = [
49
- {
50
- name: 'customer',
51
- type: 'relationship',
52
- label: ({ t }) =>
53
- // @ts-expect-error - translations are not typed in plugins yet
54
- t('plugin-ecommerce:customer'),
55
- relationTo: customersSlug,
56
- },
57
- {
58
- name: 'customerEmail',
59
- type: 'email',
60
- label: ({ t }) =>
61
- // @ts-expect-error - translations are not typed in plugins yet
62
- t('plugin-ecommerce:customerEmail'),
63
- },
64
- {
65
- name: 'transactions',
66
- type: 'relationship',
67
- hasMany: true,
68
- label: ({ t }) =>
69
- // @ts-expect-error - translations are not typed in plugins yet
70
- t('plugin-ecommerce:transactions'),
71
- relationTo: transactionsSlug,
72
- },
73
- {
74
- name: 'status',
75
- type: 'select',
76
- defaultValue: 'processing',
77
- interfaceName: 'OrderStatus',
78
- label: ({ t }) =>
79
- // @ts-expect-error - translations are not typed in plugins yet
80
- t('plugin-ecommerce:status'),
81
- options: [
82
- {
83
- // @ts-expect-error - translations are not typed in plugins yet
84
- label: ({ t }) => t('plugin-ecommerce:processing'),
85
- value: 'processing',
86
- },
87
- {
88
- // @ts-expect-error - translations are not typed in plugins yet
89
- label: ({ t }) => t('plugin-ecommerce:completed'),
90
- value: 'completed',
91
- },
92
- {
93
- // @ts-expect-error - translations are not typed in plugins yet
94
- label: ({ t }) => t('plugin-ecommerce:cancelled'),
95
- value: 'cancelled',
96
- },
97
- {
98
- // @ts-expect-error - translations are not typed in plugins yet
99
- label: ({ t }) => t('plugin-ecommerce:refunded'),
100
- value: 'refunded',
101
- },
102
- ],
103
- },
104
- ...(addressFields
105
- ? [
106
- {
107
- name: 'shippingAddress',
108
- type: 'group',
109
- fields: addressFields,
110
- label: ({ t }) =>
111
- // @ts-expect-error - translations are not typed in plugins yet
112
- t('plugin-ecommerce:shippingAddress'),
113
- } as Field,
114
- ]
115
- : []),
116
- ...(currenciesConfig
117
- ? [amountField({ currenciesConfig }), currencyField({ currenciesConfig })]
118
- : []),
119
- cartItemsField({
120
- enableVariants,
121
- overrides: {
122
- name: 'items',
123
- label: ({ t }) =>
124
- // @ts-expect-error - translations are not typed in plugins yet
125
- t('plugin-ecommerce:items'),
126
- labels: {
127
- plural: ({ t }) =>
128
- // @ts-expect-error - translations are not typed in plugins yet
129
- t('plugin-ecommerce:items'),
130
- singular: ({ t }) =>
131
- // @ts-expect-error - translations are not typed in plugins yet
132
- t('plugin-ecommerce:item'),
133
- },
134
- },
135
- productsSlug,
136
- variantsSlug,
137
- }),
138
- ]
139
-
140
- const fields =
141
- fieldsOverride && typeof fieldsOverride === 'function'
142
- ? fieldsOverride({ defaultFields })
143
- : defaultFields
144
-
145
- const baseConfig: CollectionConfig = {
146
- slug: 'orders',
147
- timestamps: true,
148
- ...overrides,
149
- admin: {
150
- useAsTitle: 'createdAt',
151
- ...overrides?.admin,
152
- },
153
- fields,
154
- }
155
-
156
- return { ...baseConfig }
157
- }
@@ -1,123 +0,0 @@
1
- import Stripe from 'stripe'
2
-
3
- import type { PaymentAdapter } from '../../../types.js'
4
- import type { StripeAdapterArgs } from './index.js'
5
-
6
- type Props = {
7
- apiVersion?: Stripe.StripeConfig['apiVersion']
8
- appInfo?: Stripe.StripeConfig['appInfo']
9
- secretKey: StripeAdapterArgs['secretKey']
10
- }
11
-
12
- export const confirmOrder: (props: Props) => NonNullable<PaymentAdapter>['confirmOrder'] =
13
- (props) =>
14
- async ({ data, ordersSlug = 'orders', req, transactionsSlug = 'transactions' }) => {
15
- const payload = req.payload
16
- const { apiVersion, appInfo, secretKey } = props || {}
17
-
18
- const customerEmail = data.customerEmail
19
- const user = req.user
20
-
21
- const paymentIntentID = data.paymentIntentID as string
22
-
23
- if (!secretKey) {
24
- throw new Error('Stripe secret key is required')
25
- }
26
-
27
- if (!paymentIntentID) {
28
- throw new Error('PaymentIntent ID is required')
29
- }
30
-
31
- const stripe = new Stripe(secretKey, {
32
- // API version can only be the latest, stripe recommends ts ignoring it
33
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
34
- // @ts-ignore - ignoring since possible versions are not type safe, only the latest version is recognised
35
- apiVersion: apiVersion || '2025-03-31.basil',
36
- appInfo: appInfo || {
37
- name: 'Stripe Payload Plugin',
38
- url: 'https://payloadcms.com',
39
- },
40
- })
41
-
42
- try {
43
- let customer = (
44
- await stripe.customers.list({
45
- email: customerEmail,
46
- })
47
- ).data[0]
48
-
49
- if (!customer?.id) {
50
- customer = await stripe.customers.create({
51
- email: customerEmail,
52
- })
53
- }
54
-
55
- // Find our existing transaction by the payment intent ID
56
- const transactionsResults = await payload.find({
57
- collection: transactionsSlug,
58
- where: {
59
- 'stripe.paymentIntentID': {
60
- equals: paymentIntentID,
61
- },
62
- },
63
- })
64
-
65
- const transaction = transactionsResults.docs[0]
66
-
67
- if (!transactionsResults.totalDocs || !transaction) {
68
- throw new Error('No transaction found for the provided PaymentIntent ID')
69
- }
70
-
71
- // Verify the payment intent exists and retrieve it
72
- const paymentIntent = await stripe.paymentIntents.retrieve(paymentIntentID)
73
-
74
- const cartID = paymentIntent.metadata.cartID
75
- const cartItemsSnapshot = paymentIntent.metadata.cartItemsSnapshot
76
- ? JSON.parse(paymentIntent.metadata.cartItemsSnapshot)
77
- : undefined
78
-
79
- const shippingAddress = paymentIntent.metadata.shippingAddress
80
- ? JSON.parse(paymentIntent.metadata.shippingAddress)
81
- : undefined
82
-
83
- if (!cartID) {
84
- throw new Error('Cart ID not found in the PaymentIntent metadata')
85
- }
86
-
87
- if (!cartItemsSnapshot || !Array.isArray(cartItemsSnapshot)) {
88
- throw new Error('Cart items snapshot not found or invalid in the PaymentIntent metadata')
89
- }
90
-
91
- const order = await payload.create({
92
- collection: ordersSlug,
93
- data: {
94
- amount: paymentIntent.amount,
95
- currency: paymentIntent.currency.toUpperCase(),
96
- ...(req.user ? { customer: req.user.id } : { customerEmail }),
97
- items: cartItemsSnapshot,
98
- shippingAddress,
99
- status: 'processing',
100
- transactions: [transaction.id],
101
- },
102
- })
103
-
104
- await payload.update({
105
- id: transaction.id,
106
- collection: transactionsSlug,
107
- data: {
108
- order: order.id,
109
- status: 'succeeded',
110
- },
111
- })
112
-
113
- return {
114
- message: 'Payment initiated successfully',
115
- order,
116
- orderID: order.id,
117
- }
118
- } catch (error) {
119
- payload.logger.error(error, 'Error initiating payment with Stripe')
120
-
121
- throw new Error(error instanceof Error ? error.message : 'Unknown error initiating payment')
122
- }
123
- }
@@ -1,69 +0,0 @@
1
- import type { Endpoint } from 'payload'
2
-
3
- import Stripe from 'stripe'
4
-
5
- import type { StripeAdapterArgs } from '../index.js'
6
-
7
- type Props = {
8
- apiVersion?: Stripe.StripeConfig['apiVersion']
9
- appInfo?: Stripe.StripeConfig['appInfo']
10
- secretKey: StripeAdapterArgs['secretKey']
11
- webhooks?: StripeAdapterArgs['webhooks']
12
- webhookSecret: StripeAdapterArgs['webhookSecret']
13
- }
14
-
15
- export const webhooksEndpoint: (props: Props) => Endpoint = (props) => {
16
- const { apiVersion, appInfo, secretKey, webhooks, webhookSecret } = props || {}
17
-
18
- const handler: Endpoint['handler'] = async (req) => {
19
- let returnStatus = 200
20
-
21
- if (webhookSecret && secretKey && req.text) {
22
- const stripe = new Stripe(secretKey, {
23
- // API version can only be the latest, stripe recommends ts ignoring it
24
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
25
- // @ts-ignore - ignoring since possible versions are not type safe, only the latest version is recognised
26
- apiVersion: apiVersion || '2025-03-31.basil',
27
- appInfo: appInfo || {
28
- name: 'Stripe Payload Plugin',
29
- url: 'https://payloadcms.com',
30
- },
31
- })
32
-
33
- const body = await req.text()
34
- const stripeSignature = req.headers.get('stripe-signature')
35
-
36
- if (stripeSignature) {
37
- let event: Stripe.Event | undefined
38
-
39
- try {
40
- event = stripe.webhooks.constructEvent(body, stripeSignature, webhookSecret)
41
- } catch (err: unknown) {
42
- const msg: string = err instanceof Error ? err.message : JSON.stringify(err)
43
- req.payload.logger.error(`Error constructing Stripe event: ${msg}`)
44
- returnStatus = 400
45
- }
46
-
47
- if (typeof webhooks === 'object' && event) {
48
- const webhookEventHandler = webhooks[event.type]
49
-
50
- if (typeof webhookEventHandler === 'function') {
51
- await webhookEventHandler({
52
- event,
53
- req,
54
- stripe,
55
- })
56
- }
57
- }
58
- }
59
- }
60
-
61
- return Response.json({ received: true }, { status: returnStatus })
62
- }
63
-
64
- return {
65
- handler,
66
- method: 'post',
67
- path: '/webhooks',
68
- }
69
- }