mirror of
https://github.com/xtr-dev/payload-billing.git
synced 2025-12-10 02:43:24 +00:00
fix: resolve plugin initialization failure in Next.js API routes
Use Symbol.for() instead of Symbol() for plugin singleton storage to ensure
plugin state persists across different module loading contexts (admin panel,
API routes, server components).
This fixes the "Billing plugin not initialized" error that occurred when
calling payload.create() from Next.js API routes, server components, or
server actions.
Changes:
- Plugin singleton now uses Symbol.for('@xtr-dev/payload-billing')
- Provider singletons (stripe, mollie, test) use global symbols
- Enhanced error message with troubleshooting guidance
Fixes #1
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +7,8 @@ export const initProviderPayment = async (payload: Payload, payment: Partial<Pay
|
|||||||
|
|
||||||
if (!billing) {
|
if (!billing) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'Billing plugin not initialized. Make sure the billingPlugin is properly configured in your Payload config and that Payload has finished initializing.'
|
'Billing plugin not initialized. Make sure the billingPlugin is properly configured in your Payload config and that Payload has finished initializing. ' +
|
||||||
|
'If you are calling this from a Next.js API route or Server Component, ensure you are using getPayload() with the same config instance used in your Payload configuration.'
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import type { Config, Payload } from 'payload'
|
|||||||
import { createSingleton } from './singleton'
|
import { createSingleton } from './singleton'
|
||||||
import type { PaymentProvider } from '../providers/index'
|
import type { PaymentProvider } from '../providers/index'
|
||||||
|
|
||||||
const singleton = createSingleton(Symbol('billingPlugin'))
|
const singleton = createSingleton(Symbol.for('@xtr-dev/payload-billing'))
|
||||||
|
|
||||||
type BillingPlugin = {
|
type BillingPlugin = {
|
||||||
config: BillingPluginConfig
|
config: BillingPluginConfig
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import {
|
|||||||
import { formatAmountForProvider, isValidAmount, isValidCurrencyCode } from './currency'
|
import { formatAmountForProvider, isValidAmount, isValidCurrencyCode } from './currency'
|
||||||
import { createContextLogger } from '../utils/logger'
|
import { createContextLogger } from '../utils/logger'
|
||||||
|
|
||||||
const symbol = Symbol('mollie')
|
const symbol = Symbol.for('@xtr-dev/payload-billing/mollie')
|
||||||
export type MollieProviderConfig = Parameters<typeof createMollieClient>[0]
|
export type MollieProviderConfig = Parameters<typeof createMollieClient>[0]
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import {
|
|||||||
import { isValidAmount, isValidCurrencyCode } from './currency'
|
import { isValidAmount, isValidCurrencyCode } from './currency'
|
||||||
import { createContextLogger } from '../utils/logger'
|
import { createContextLogger } from '../utils/logger'
|
||||||
|
|
||||||
const symbol = Symbol('stripe')
|
const symbol = Symbol.for('@xtr-dev/payload-billing/stripe')
|
||||||
|
|
||||||
export interface StripeProviderConfig {
|
export interface StripeProviderConfig {
|
||||||
secretKey: string
|
secretKey: string
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { handleWebhookError, logWebhookEvent } from './utils'
|
|||||||
import { isValidAmount, isValidCurrencyCode } from './currency'
|
import { isValidAmount, isValidCurrencyCode } from './currency'
|
||||||
import { createContextLogger } from '../utils/logger'
|
import { createContextLogger } from '../utils/logger'
|
||||||
|
|
||||||
const TestModeWarningSymbol = Symbol('TestModeWarning')
|
const TestModeWarningSymbol = Symbol.for('@xtr-dev/payload-billing/test-mode-warning')
|
||||||
const hasGivenTestModeWarning = () => TestModeWarningSymbol in globalThis
|
const hasGivenTestModeWarning = () => TestModeWarningSymbol in globalThis
|
||||||
const setTestModeWarning = () => ((<any>globalThis)[TestModeWarningSymbol] = true)
|
const setTestModeWarning = () => ((<any>globalThis)[TestModeWarningSymbol] = true)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user