mirror of
https://github.com/xtr-dev/payload-billing.git
synced 2025-12-13 04:13:24 +00:00
feat: Add Mollie payment provider support
- Introduce `mollieProvider` for handling Mollie payments - Add configurable payment hooks for initialization and processing - Implement `initPayment` logic to create Mollie payments and update metadata - Include types for Mollie integration in payments and refunds - Update `package.json` to include `@mollie/api-client` dependency - Refactor existing payment-related types into modular files for better maintainability
This commit is contained in:
11
src/collections/hooks.ts
Normal file
11
src/collections/hooks.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import type { Payment } from '@/plugin/types'
|
||||
import type { Payload } from 'payload'
|
||||
import { useBillingPlugin } from '@/plugin'
|
||||
|
||||
export const initProviderPayment = (payload: Payload, payment: Partial<Payment>) => {
|
||||
const billing = useBillingPlugin(payload)
|
||||
if (!payment.provider || !billing.providerConfig[payment.provider]) {
|
||||
throw new Error(`Provider ${payment.provider} not found.`)
|
||||
}
|
||||
return billing.providerConfig[payment.provider].initPayment(payload, payment)
|
||||
}
|
||||
@@ -5,9 +5,10 @@ import {
|
||||
CollectionBeforeValidateHook,
|
||||
CollectionConfig, Field,
|
||||
} from 'payload'
|
||||
import { BillingPluginConfig, CustomerInfoExtractor, defaults } from '@/plugin/config'
|
||||
import { Invoice } from '@/plugin/types'
|
||||
import type { BillingPluginConfig} from '@/plugin/config';
|
||||
import { defaults } from '@/plugin/config'
|
||||
import { extractSlug } from '@/plugin/utils'
|
||||
import type { Invoice } from '@/plugin/types/invoices'
|
||||
|
||||
export function createInvoicesCollection(pluginConfig: BillingPluginConfig): CollectionConfig {
|
||||
const {customerRelationSlug, customerInfoExtractor} = pluginConfig
|
||||
@@ -31,7 +32,7 @@ export function createInvoicesCollection(pluginConfig: BillingPluginConfig): Col
|
||||
position: 'sidebar' as const,
|
||||
description: 'Link to customer record (optional)',
|
||||
},
|
||||
relationTo: pluginConfig.customerRelationSlug as never,
|
||||
relationTo: extractSlug(customerRelationSlug),
|
||||
required: false,
|
||||
}] : []),
|
||||
// Basic customer info fields (embedded)
|
||||
@@ -275,7 +276,7 @@ export function createInvoicesCollection(pluginConfig: BillingPluginConfig): Col
|
||||
condition: (data) => data.status === 'paid',
|
||||
position: 'sidebar',
|
||||
},
|
||||
relationTo: 'payments',
|
||||
relationTo: extractSlug(pluginConfig.collections?.payments || defaults.paymentsCollection),
|
||||
},
|
||||
{
|
||||
name: 'notes',
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import type { AccessArgs, CollectionBeforeChangeHook, CollectionConfig, Field } from 'payload'
|
||||
import type { Payment } from '@/plugin/types'
|
||||
import type { AccessArgs, CollectionBeforeChangeHook, CollectionConfig, CollectionSlug, Field } from 'payload'
|
||||
import type { BillingPluginConfig} from '@/plugin/config';
|
||||
import { defaults } from '@/plugin/config'
|
||||
import { extractSlug } from '@/plugin/utils'
|
||||
import { Payment } from '@/plugin/types/payments'
|
||||
import { initProviderPayment } from '@/collections/hooks'
|
||||
|
||||
export function createPaymentsCollection(pluginConfig: BillingPluginConfig): CollectionConfig {
|
||||
const overrides = typeof pluginConfig.collections?.payments === 'object' ? pluginConfig.collections?.payments : {}
|
||||
@@ -27,7 +28,6 @@ export function createPaymentsCollection(pluginConfig: BillingPluginConfig): Col
|
||||
description: 'The payment ID from the payment provider',
|
||||
},
|
||||
label: 'Provider Payment ID',
|
||||
required: true,
|
||||
unique: true,
|
||||
},
|
||||
{
|
||||
@@ -78,7 +78,7 @@ export function createPaymentsCollection(pluginConfig: BillingPluginConfig): Col
|
||||
admin: {
|
||||
position: 'sidebar',
|
||||
},
|
||||
relationTo: 'invoices',
|
||||
relationTo: extractSlug(pluginConfig.collections?.invoices || defaults.invoicesCollection) as CollectionSlug,
|
||||
},
|
||||
{
|
||||
name: 'metadata',
|
||||
@@ -103,7 +103,7 @@ export function createPaymentsCollection(pluginConfig: BillingPluginConfig): Col
|
||||
readOnly: true,
|
||||
},
|
||||
hasMany: true,
|
||||
relationTo: 'refunds',
|
||||
relationTo: extractSlug(pluginConfig.collections?.refunds || defaults.refundsCollection) as CollectionSlug,
|
||||
},
|
||||
]
|
||||
if (overrides?.fields) {
|
||||
@@ -126,7 +126,7 @@ export function createPaymentsCollection(pluginConfig: BillingPluginConfig): Col
|
||||
fields,
|
||||
hooks: {
|
||||
beforeChange: [
|
||||
({ data, operation }) => {
|
||||
async ({ data, operation, req }) => {
|
||||
if (operation === 'create') {
|
||||
// Validate amount format
|
||||
if (data.amount && !Number.isInteger(data.amount)) {
|
||||
@@ -140,6 +140,8 @@ export function createPaymentsCollection(pluginConfig: BillingPluginConfig): Col
|
||||
throw new Error('Currency must be a 3-letter ISO code')
|
||||
}
|
||||
}
|
||||
|
||||
await initProviderPayment(req.payload, data)
|
||||
}
|
||||
},
|
||||
] satisfies CollectionBeforeChangeHook<Payment>[],
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { AccessArgs, CollectionConfig } from 'payload'
|
||||
import { BillingPluginConfig, defaults } from '@/plugin/config'
|
||||
import { extractSlug } from '@/plugin/utils'
|
||||
import { Payment } from '@/plugin/types'
|
||||
|
||||
export function createRefundsCollection(pluginConfig: BillingPluginConfig): CollectionConfig {
|
||||
const overrides = typeof pluginConfig.collections?.invoices === 'object' ? pluginConfig.collections?.invoices : {}
|
||||
// TODO: finish collection overrides
|
||||
return {
|
||||
slug: extractSlug(pluginConfig.collections?.refunds || defaults.refundsCollection),
|
||||
@@ -35,7 +35,7 @@ export function createRefundsCollection(pluginConfig: BillingPluginConfig): Coll
|
||||
admin: {
|
||||
position: 'sidebar',
|
||||
},
|
||||
relationTo: 'payments',
|
||||
relationTo: extractSlug(pluginConfig.collections?.payments || defaults.paymentsCollection),
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
@@ -117,13 +117,13 @@ export function createRefundsCollection(pluginConfig: BillingPluginConfig): Coll
|
||||
try {
|
||||
const payment = await req.payload.findByID({
|
||||
id: typeof doc.payment === 'string' ? doc.payment : doc.payment.id,
|
||||
collection: 'payments',
|
||||
})
|
||||
collection: extractSlug(pluginConfig.collections?.payments || defaults.paymentsCollection),
|
||||
}) as Payment
|
||||
|
||||
const refundIds = Array.isArray(payment.refunds) ? payment.refunds : []
|
||||
await req.payload.update({
|
||||
id: typeof doc.payment === 'string' ? doc.payment : doc.payment.id,
|
||||
collection: 'payments',
|
||||
collection: extractSlug(pluginConfig.collections?.payments || defaults.paymentsCollection),
|
||||
data: {
|
||||
refunds: [...refundIds, doc.id],
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user