switched to paddle inline checkout, removed paypal and most of stripe. added product sync between app and paddle.

This commit is contained in:
Codex Agent
2025-10-27 17:26:39 +01:00
parent ecf5a23b28
commit 5432456ffd
117 changed files with 4114 additions and 3639 deletions

View File

@@ -10,6 +10,7 @@ interface CheckoutState {
paymentIntent: string | null;
loading: boolean;
error: string | null;
paymentCompleted: boolean;
}
interface CheckoutWizardContextType {
@@ -19,6 +20,11 @@ interface CheckoutWizardContextType {
currentStep: CheckoutStepId;
isAuthenticated: boolean;
authUser: any;
paddleConfig?: {
environment?: string | null;
client_token?: string | null;
} | null;
paymentCompleted: boolean;
selectPackage: (pkg: CheckoutPackage) => void;
setSelectedPackage: (pkg: CheckoutPackage) => void;
setAuthUser: (user: any) => void;
@@ -31,6 +37,7 @@ interface CheckoutWizardContextType {
setLoading: (loading: boolean) => void;
setError: (error: string | null) => void;
resetPaymentState: () => void;
setPaymentCompleted: (completed: boolean) => void;
}
const CheckoutWizardContext = createContext<CheckoutWizardContextType | null>(null);
@@ -44,6 +51,7 @@ const initialState: CheckoutState = {
paymentIntent: null,
loading: false,
error: null,
paymentCompleted: false,
};
type CheckoutAction =
@@ -54,14 +62,15 @@ type CheckoutAction =
| { type: 'GO_TO_STEP'; payload: CheckoutStepId }
| { type: 'UPDATE_PAYMENT_INTENT'; payload: string | null }
| { type: 'SET_LOADING'; payload: boolean }
| { type: 'SET_ERROR'; payload: string | null };
| { type: 'SET_ERROR'; payload: string | null }
| { type: 'SET_PAYMENT_COMPLETED'; payload: boolean };
function checkoutReducer(state: CheckoutState, action: CheckoutAction): CheckoutState {
switch (action.type) {
case 'SELECT_PACKAGE':
return { ...state, selectedPackage: action.payload };
return { ...state, selectedPackage: action.payload, paymentCompleted: false };
case 'SET_AUTH_USER':
return { ...state, authUser: action.payload };
return { ...state, authUser: action.payload, isAuthenticated: Boolean(action.payload) };
case 'NEXT_STEP':
const steps: CheckoutStepId[] = ['package', 'auth', 'payment', 'confirmation'];
const currentIndex = steps.indexOf(state.currentStep);
@@ -84,6 +93,8 @@ function checkoutReducer(state: CheckoutState, action: CheckoutAction): Checkout
return { ...state, loading: action.payload };
case 'SET_ERROR':
return { ...state, error: action.payload };
case 'SET_PAYMENT_COMPLETED':
return { ...state, paymentCompleted: action.payload };
default:
return state;
}
@@ -96,6 +107,10 @@ interface CheckoutWizardProviderProps {
initialStep?: CheckoutStepId;
initialAuthUser?: any;
initialIsAuthenticated?: boolean;
paddle?: {
environment?: string | null;
client_token?: string | null;
} | null;
}
export function CheckoutWizardProvider({
@@ -104,7 +119,8 @@ export function CheckoutWizardProvider({
packageOptions,
initialStep,
initialAuthUser,
initialIsAuthenticated
initialIsAuthenticated,
paddle,
}: CheckoutWizardProviderProps) {
const customInitialState: CheckoutState = {
...initialState,
@@ -124,7 +140,8 @@ export function CheckoutWizardProvider({
if (savedState) {
try {
const parsed = JSON.parse(savedState);
if (parsed.selectedPackage && initialPackage && parsed.selectedPackage.id === initialPackage.id && parsed.currentStep !== 'confirmation') {
const hasValidPackage = parsed.selectedPackage && typeof parsed.selectedPackage.paddle_price_id === 'string' && parsed.selectedPackage.paddle_price_id !== '';
if (hasValidPackage && initialPackage && parsed.selectedPackage.id === initialPackage.id && parsed.currentStep !== 'confirmation') {
// Restore state selectively
if (parsed.selectedPackage) dispatch({ type: 'SELECT_PACKAGE', payload: parsed.selectedPackage });
if (parsed.currentStep) dispatch({ type: 'GO_TO_STEP', payload: parsed.currentStep });
@@ -192,6 +209,11 @@ export function CheckoutWizardProvider({
dispatch({ type: 'UPDATE_PAYMENT_INTENT', payload: null });
dispatch({ type: 'SET_LOADING', payload: false });
dispatch({ type: 'SET_ERROR', payload: null });
dispatch({ type: 'SET_PAYMENT_COMPLETED', payload: false });
}, []);
const setPaymentCompleted = useCallback((completed: boolean) => {
dispatch({ type: 'SET_PAYMENT_COMPLETED', payload: completed });
}, []);
const cancelCheckout = useCallback(() => {
@@ -226,6 +248,8 @@ export function CheckoutWizardProvider({
currentStep: state.currentStep,
isAuthenticated: state.isAuthenticated,
authUser: state.authUser,
paddleConfig: paddle ?? null,
paymentCompleted: state.paymentCompleted,
selectPackage,
setSelectedPackage,
setAuthUser,
@@ -238,6 +262,7 @@ export function CheckoutWizardProvider({
setLoading,
setError,
resetPaymentState,
setPaymentCompleted,
};
return (