interface AbacatePayConfig { apiKey: string; accountId: string; baseUrl?: string; } interface CreateBillingParams { amount: number; metadata?: { donorName?: string; donorEmail?: string; message?: string; }; returnUrl?: string; completionUrl?: string; } interface BillingResponse { id: string; amount: number; status: "PENDING" | "PAID" | "EXPIRED" | "CANCELLED"; pixCode?: string; pixQrCode?: string; qrCode?: string; expiresAt?: string; createdAt: string; url?: string; // URL para redirecionamento paymentUrl?: string; // URL alternativa de pagamento } class AbacatePayClient { private config: AbacatePayConfig; constructor(config: AbacatePayConfig) { this.config = { ...config, baseUrl: config.baseUrl || "https://api.abacatepay.com/v1", }; } async createBilling(params: CreateBillingParams): Promise { const response = await fetch(`${this.config.baseUrl}/billing`, { method: "POST", headers: { Authorization: `Bearer ${this.config.apiKey}`, "Content-Type": "application/json", }, body: JSON.stringify({ account_id: this.config.accountId, amount: params.amount * 100, // centavos metadata: params.metadata, return_url: params.returnUrl, completion_url: params.completionUrl, }), }); if (!response.ok) { const errorData = await response.json().catch(() => ({})); throw new Error( `Failed to create billing: ${errorData.message || response.statusText}` ); } return response.json(); } async createDonationBilling(params: { amount: number; donorEmail?: string; donorName?: string; message?: string; }): Promise { const requestBody = { products: [ { external_id: `donation-${Date.now()}`, name: "Doação - Tibia Trade Pagodera", quantity: 1, price: Math.round(params.amount * 100), // R$ para centavos }, ], return_url: `${process.env.NEXT_PUBLIC_BASE_URL}/apoiar/obrigado`, completion_url: `${process.env.NEXT_PUBLIC_BASE_URL}/api/donations/verify`, }; console.log("🔍 AbacatePay Request URL:", `${this.config.baseUrl}/billing`); console.log( "🔍 AbacatePay Request Body:", JSON.stringify(requestBody, null, 2) ); const response = await fetch(`${this.config.baseUrl}/billing`, { method: "POST", headers: { Authorization: `Bearer ${this.config.apiKey}`, "Content-Type": "application/json", }, body: JSON.stringify(requestBody), }); console.log("🔍 AbacatePay Response Status:", response.status); console.log("🔍 AbacatePay Response OK:", response.ok); if (!response.ok) { const errorData = await response.json().catch(() => ({})); console.error("🔍 AbacatePay Error Response:", errorData); throw new Error( `Failed to create billing: ${errorData.message || response.statusText}` ); } const result = await response.json(); console.log("🔍 AbacatePay Success Response:", result); return result; } async getBillingStatus(billingId: string): Promise { const response = await fetch( `${this.config.baseUrl}/billing/${billingId}`, { headers: { Authorization: `Bearer ${this.config.apiKey}`, }, } ); if (!response.ok) { const errorData = await response.json().catch(() => ({})); throw new Error( `Failed to get billing status: ${ errorData.message || response.statusText }` ); } return response.json(); } verifyWebhookSignature(payload: string, signature: string): boolean { // Implementar verificação de assinatura conforme documentação do AbacatePay // Por enquanto, retorna true para desenvolvimento // Em produção, implementar a verificação real return true; } } // Instância do cliente (será configurada com variáveis de ambiente) const isProduction = process.env.NODE_ENV === "production"; const apiKey = isProduction ? process.env.ABACATE_APIKEY || "demo_key" : process.env.ABACATE_TEST_APIKEY || "demo_key"; // Log para debug (apenas em desenvolvimento) if (process.env.NODE_ENV !== "production") { console.log( `🔧 AbacatePay: Using ${isProduction ? "PRODUCTION" : "TEST"} environment` ); } export const abacatePay = new AbacatePayClient({ apiKey, accountId: process.env.ABACATEPAY_ACCOUNT_ID || "demo_account", }); export type { CreateBillingParams, BillingResponse };