@payloadcms/storage-r2 0.0.1-beta.0 → 3.58.0-canary.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/handleDelete.d.ts +8 -0
- package/dist/handleDelete.d.ts.map +1 -0
- package/dist/handleDelete.js +8 -0
- package/dist/handleDelete.js.map +1 -0
- package/dist/handleUpload.d.ts +11 -0
- package/dist/handleUpload.d.ts.map +1 -0
- package/dist/handleUpload.js +13 -0
- package/dist/handleUpload.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +59 -0
- package/dist/index.js.map +1 -0
- package/dist/staticHandler.d.ts +11 -0
- package/dist/staticHandler.d.ts.map +1 -0
- package/dist/staticHandler.js +29 -0
- package/dist/staticHandler.js.map +1 -0
- package/dist/types.d.ts +16 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +57 -1
- package/.prettierignore +0 -12
- package/.swcrc +0 -24
- package/README.md +0 -3
- package/eslint.config.js +0 -18
- package/src/addresses/addressesCollection.ts +0 -76
- package/src/addresses/defaultAddressFields.ts +0 -83
- package/src/addresses/defaultCountries.ts +0 -50
- package/src/carts/beforeChange.ts +0 -51
- package/src/carts/cartsCollection.ts +0 -146
- package/src/currencies/index.ts +0 -29
- package/src/endpoints/confirmOrder.ts +0 -312
- package/src/endpoints/initiatePayment.ts +0 -322
- package/src/exports/addresses.ts +0 -2
- package/src/exports/currencies.ts +0 -1
- package/src/exports/fields.ts +0 -5
- package/src/exports/orders.ts +0 -1
- package/src/exports/payments/stripe.ts +0 -1
- package/src/exports/plugin.ts +0 -1
- package/src/exports/products.ts +0 -1
- package/src/exports/react.ts +0 -8
- package/src/exports/transactions.ts +0 -1
- package/src/exports/translations.ts +0 -1
- package/src/exports/types.ts +0 -7
- package/src/exports/ui.ts +0 -3
- package/src/exports/variants.ts +0 -5
- package/src/fields/amountField.ts +0 -43
- package/src/fields/cartItemsField.ts +0 -84
- package/src/fields/currencyField.ts +0 -39
- package/src/fields/inventoryField.ts +0 -22
- package/src/fields/pricesField.ts +0 -65
- package/src/fields/statusField.ts +0 -57
- package/src/fields/variantsFields.ts +0 -56
- package/src/index.ts +0 -275
- package/src/orders/ordersCollection.ts +0 -157
- package/src/payments/adapters/stripe/confirmOrder.ts +0 -123
- package/src/payments/adapters/stripe/endpoints/webhooks.ts +0 -69
- package/src/payments/adapters/stripe/index.ts +0 -135
- package/src/payments/adapters/stripe/initiatePayment.ts +0 -131
- package/src/products/productsCollection.ts +0 -78
- package/src/react/provider/index.tsx +0 -893
- package/src/react/provider/types.ts +0 -184
- package/src/react/provider/utilities.ts +0 -22
- package/src/transactions/transactionsCollection.ts +0 -166
- package/src/translations/en.ts +0 -64
- package/src/translations/index.ts +0 -11
- package/src/translations/translation-schema.json +0 -35
- package/src/types.ts +0 -403
- package/src/ui/PriceInput/FormattedInput.tsx +0 -134
- package/src/ui/PriceInput/index.scss +0 -28
- package/src/ui/PriceInput/index.tsx +0 -43
- package/src/ui/PriceInput/utilities.ts +0 -46
- package/src/ui/PriceRowLabel/index.css +0 -13
- package/src/ui/PriceRowLabel/index.tsx +0 -56
- package/src/ui/VariantOptionsSelector/ErrorBox.tsx +0 -27
- package/src/ui/VariantOptionsSelector/OptionsSelect.tsx +0 -78
- package/src/ui/VariantOptionsSelector/index.css +0 -37
- package/src/ui/VariantOptionsSelector/index.tsx +0 -83
- package/src/utilities/defaultProductsValidation.ts +0 -42
- package/src/utilities/errorCodes.ts +0 -14
- package/src/utilities/getCollectionSlugMap.ts +0 -84
- package/src/utilities/sanitizePluginConfig.ts +0 -80
- package/src/variants/variantOptionsCollection.ts +0 -59
- package/src/variants/variantTypesCollection.ts +0 -55
- package/src/variants/variantsCollection/hooks/beforeChange.ts +0 -47
- package/src/variants/variantsCollection/hooks/validateOptions.ts +0 -72
- package/src/variants/variantsCollection/index.ts +0 -119
- package/tsconfig.json +0 -7
- 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
|
-
}
|