82 lines
2.4 KiB
TypeScript
82 lines
2.4 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
|
|
export type CheckoutItem = {
|
|
productId: string;
|
|
quantity: number;
|
|
};
|
|
|
|
export type CheckoutResult = {
|
|
success: boolean;
|
|
url?: string;
|
|
error?: string;
|
|
};
|
|
|
|
export function useCheckout() {
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
const checkout = async (items: CheckoutItem[]): Promise<CheckoutResult> => {
|
|
const apiUrl = process.env.NEXT_PUBLIC_API_URL;
|
|
const projectId = process.env.NEXT_PUBLIC_PROJECT_ID;
|
|
|
|
if (!apiUrl || !projectId) {
|
|
const errorMsg = "NEXT_PUBLIC_API_URL or NEXT_PUBLIC_PROJECT_ID not configured";
|
|
setError(errorMsg);
|
|
return { success: false, error: errorMsg };
|
|
}
|
|
|
|
setIsLoading(true);
|
|
setError(null);
|
|
|
|
try {
|
|
const response = await fetch(`${apiUrl}/stripe/project/checkout-session`, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({
|
|
projectId,
|
|
items,
|
|
successUrl: window.location.href,
|
|
cancelUrl: window.location.href,
|
|
}),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const errorData = await response.json().catch(() => ({}));
|
|
const errorMsg = errorData.message || `Request failed with status ${response.status}`;
|
|
setError(errorMsg);
|
|
return { success: false, error: errorMsg };
|
|
}
|
|
|
|
const data = await response.json();
|
|
|
|
if (data.data.url) {
|
|
window.location.href = data.data.url;
|
|
}
|
|
|
|
return { success: true, url: data.data.url };
|
|
} catch (err) {
|
|
const errorMsg = err instanceof Error ? err.message : "Failed to create checkout session";
|
|
setError(errorMsg);
|
|
return { success: false, error: errorMsg };
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
const buyNow = async (productId: string, quantity: number = 1): Promise<CheckoutResult> => {
|
|
return checkout([{ productId, quantity }]);
|
|
};
|
|
|
|
return {
|
|
checkout,
|
|
buyNow,
|
|
isLoading,
|
|
error,
|
|
clearError: () => setError(null),
|
|
};
|
|
}
|