Files
fotospiel-app/resources/js/admin/mobile/hooks/usePackageCheckout.ts
Codex Agent 6fe363640f
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled
Reapply photobooth uploader changes after sync
2026-01-12 17:10:47 +01:00

60 lines
1.9 KiB
TypeScript

import React from 'react';
import { useTranslation } from 'react-i18next';
import toast from 'react-hot-toast';
import { createTenantPaddleCheckout } from '../../api';
import { adminPath } from '../../constants';
import { getApiErrorMessage } from '../../lib/apiError';
import { storePendingCheckout } from '../lib/billingCheckout';
export function usePackageCheckout(): {
busy: boolean;
startCheckout: (packageId: number) => Promise<void>;
} {
const { t } = useTranslation('management');
const [busy, setBusy] = React.useState(false);
const startCheckout = React.useCallback(
async (packageId: number) => {
if (busy) {
return;
}
setBusy(true);
try {
if (typeof window === 'undefined') {
throw new Error('Checkout is only available in the browser.');
}
const billingUrl = new URL(adminPath('/mobile/billing'), window.location.origin);
const successUrl = new URL(billingUrl);
successUrl.searchParams.set('checkout', 'success');
successUrl.searchParams.set('package_id', String(packageId));
const cancelUrl = new URL(billingUrl);
cancelUrl.searchParams.set('checkout', 'cancel');
cancelUrl.searchParams.set('package_id', String(packageId));
const { checkout_url, checkout_session_id } = await createTenantPaddleCheckout(packageId, {
success_url: successUrl.toString(),
return_url: cancelUrl.toString(),
});
if (checkout_session_id) {
storePendingCheckout({
packageId,
checkoutSessionId: checkout_session_id,
startedAt: Date.now(),
});
}
window.location.href = checkout_url;
} catch (err) {
toast.error(getApiErrorMessage(err, t('shop.errors.checkout', 'Checkout failed')));
setBusy(false);
}
},
[busy, t],
);
return { busy, startCheckout };
}