"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createOrder = createOrder; exports.captureOrder = captureOrder; exports.refundCapture = refundCapture; exports.verifyWebhookEvent = verifyWebhookEvent; exports.isConfigured = isConfigured; const BASE_URL = process.env.PAYPAL_BASE_URL ?? 'https://api-m.paypal.com'; const CLIENT_ID = process.env.PAYPAL_CLIENT_ID ?? ''; const CLIENT_SECRET = process.env.PAYPAL_CLIENT_SECRET ?? ''; let cachedToken = null; async function getAccessToken() { if (cachedToken && Date.now() < cachedToken.expiresAt - 30_000) { return cachedToken.token; } const res = await fetch(`${BASE_URL}/v1/oauth2/token`, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', Authorization: `Basic ${Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString('base64')}`, }, body: 'grant_type=client_credentials', }); if (!res.ok) throw new Error('PayPal: failed to obtain access token'); const json = await res.json(); cachedToken = { token: json.access_token, expiresAt: Date.now() + json.expires_in * 1000 }; return cachedToken.token; } async function ppFetch(path, init) { const token = await getAccessToken(); const res = await fetch(`${BASE_URL}${path}`, { ...init, headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}`, ...(init?.headers ?? {}), }, }); if (!res.ok) { const err = await res.json().catch(() => ({})); throw new Error(`PayPal ${path} failed: ${err?.message ?? res.statusText}`); } return res.json(); } async function createOrder(params) { const json = await ppFetch('/v2/checkout/orders', { method: 'POST', body: JSON.stringify({ intent: 'CAPTURE', purchase_units: [ { reference_id: params.orderId, description: params.description, amount: { currency_code: params.currency, value: (params.amount / 100).toFixed(2), }, }, ], application_context: { return_url: params.returnUrl, cancel_url: params.cancelUrl, brand_name: 'RentalDriveGo', user_action: 'PAY_NOW', }, }), }); const approveLink = json.links?.find((l) => l.rel === 'approve'); return { orderId: json.id, approveUrl: approveLink?.href ?? '', status: json.status, }; } async function captureOrder(paypalOrderId) { return ppFetch(`/v2/checkout/orders/${paypalOrderId}/capture`, { method: 'POST', body: '{}' }); } async function refundCapture(captureId, amount, currency, note) { return ppFetch(`/v2/payments/captures/${captureId}/refund`, { method: 'POST', body: JSON.stringify({ amount: { currency_code: currency, value: (amount / 100).toFixed(2) }, note_to_payer: note, }), }); } async function verifyWebhookEvent(headers, rawBody) { try { const json = await ppFetch('/v1/notifications/verify-webhook-signature', { method: 'POST', body: JSON.stringify({ auth_algo: headers['paypal-auth-algo'], cert_url: headers['paypal-cert-url'], transmission_id: headers['paypal-transmission-id'], transmission_sig: headers['paypal-transmission-sig'], transmission_time: headers['paypal-transmission-time'], webhook_id: process.env.PAYPAL_WEBHOOK_ID ?? '', webhook_event: JSON.parse(rawBody), }), }); return json.verification_status === 'SUCCESS'; } catch { return false; } } function isConfigured() { return !!(CLIENT_ID && CLIENT_SECRET && CLIENT_ID !== 'your-paypal-client-id'); } //# sourceMappingURL=paypalService.js.map