File size: 3,279 Bytes
4a285d2 ef85da9 4a285d2 ef85da9 4a285d2 ef85da9 4a285d2 ef85da9 4a285d2 ef85da9 4a285d2 ef85da9 4a285d2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
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);
}
}
|