zurri / src /services /paystackService.ts
nexusbert's picture
push
ef85da9
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);
// paystack-node returns response.body.data
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'}`);
}
}
/**
* Verify transaction by reference
*/
async verifyTransaction(reference: string) {
this.initialize();
try {
const response = await this.paystack.verifyTransaction({
reference: reference,
});
// paystack-node returns response.body.data
const responseData = response.body.data;
// Parse metadata if it's a string (paystack-node may return it as JSON string)
let metadata = responseData.metadata;
if (typeof metadata === 'string') {
try {
metadata = JSON.parse(metadata);
} catch (e) {
// If parsing fails, keep as string
}
}
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'}`);
}
}
/**
* Get public key for frontend
*/
getPublicKey(): string {
const publicKey = process.env.PAYSTACK_PUBLIC_KEY;
if (!publicKey) {
throw new Error('PAYSTACK_PUBLIC_KEY not configured');
}
return publicKey;
}
/**
* Check if Paystack is configured
*/
isConfigured(): boolean {
return !!(process.env.PAYSTACK_SECRET_KEY && process.env.PAYSTACK_PUBLIC_KEY);
}
}