|
|
const Paystack = require('paystack-node'); |
|
|
|
|
|
export class PaystackService { |
|
|
private paystack: any; |
|
|
private initialized: boolean = false; |
|
|
|
|
|
private initialize() { |
|
|
if (this.initialized) { |
|
|
return; |
|
|
} |
|
|
|
|
|
const secretKey = process.env.PAYSTACK_SECRET_KEY; |
|
|
if (!secretKey) { |
|
|
throw new Error('PAYSTACK_SECRET_KEY not configured'); |
|
|
} |
|
|
|
|
|
const environment = process.env.NODE_ENV === 'production' ? 'production' : 'development'; |
|
|
this.paystack = new Paystack(secretKey, environment); |
|
|
this.initialized = true; |
|
|
} |
|
|
|
|
|
async initializeTransaction(data: { |
|
|
email: string; |
|
|
amount: number; // Amount in kobo (NGN) or smallest currency unit |
|
|
reference: string; |
|
|
metadata?: Record<string, any>; |
|
|
callback_url?: string; |
|
|
}) { |
|
|
this.initialize(); |
|
|
try { |
|
|
const payload: any = { |
|
|
email: data.email, |
|
|
amount: data.amount, |
|
|
reference: data.reference, |
|
|
}; |
|
|
|
|
|
if (data.metadata) { |
|
|
payload.metadata = JSON.stringify(data.metadata); |
|
|
} |
|
|
|
|
|
if (data.callback_url) { |
|
|
payload.callback_url = data.callback_url; |
|
|
} |
|
|
|
|
|
const response = await this.paystack.initializeTransaction(payload); |
|
|
|
|
|
|
|
|
const responseData = response.body.data; |
|
|
|
|
|
return { |
|
|
authorization_url: responseData.authorization_url, |
|
|
access_code: responseData.access_code, |
|
|
reference: responseData.reference, |
|
|
}; |
|
|
} catch (error: any) { |
|
|
console.error('Paystack initialize error:', error); |
|
|
throw new Error(`Failed to initialize transaction: ${error.message || 'Unknown error'}`); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async verifyTransaction(reference: string) { |
|
|
this.initialize(); |
|
|
try { |
|
|
const response = await this.paystack.verifyTransaction({ |
|
|
reference: reference, |
|
|
}); |
|
|
|
|
|
|
|
|
const responseData = response.body.data; |
|
|
|
|
|
|
|
|
let metadata = responseData.metadata; |
|
|
if (typeof metadata === 'string') { |
|
|
try { |
|
|
metadata = JSON.parse(metadata); |
|
|
} catch (e) { |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
return { |
|
|
status: responseData.status, |
|
|
reference: responseData.reference, |
|
|
amount: responseData.amount, |
|
|
currency: responseData.currency, |
|
|
customer: responseData.customer, |
|
|
metadata: metadata, |
|
|
paidAt: responseData.paid_at, |
|
|
gatewayResponse: responseData.gateway_response, |
|
|
channel: responseData.channel, |
|
|
}; |
|
|
} catch (error: any) { |
|
|
console.error('Paystack verify error:', error); |
|
|
throw new Error(`Failed to verify transaction: ${error.message || 'Unknown error'}`); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
getPublicKey(): string { |
|
|
const publicKey = process.env.PAYSTACK_PUBLIC_KEY; |
|
|
if (!publicKey) { |
|
|
throw new Error('PAYSTACK_PUBLIC_KEY not configured'); |
|
|
} |
|
|
return publicKey; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
isConfigured(): boolean { |
|
|
return !!(process.env.PAYSTACK_SECRET_KEY && process.env.PAYSTACK_PUBLIC_KEY); |
|
|
} |
|
|
} |
|
|
|
|
|
|