@adsesugh/monnify-react-native
Version:
A React Native component for integrating Monnify payment gateway using WebView for both React Native CLI and Expo.
117 lines (114 loc) • 4.34 kB
JavaScript
;
import axios from "axios";
import { Buffer } from 'buffer';
export default class Monnify {
constructor(config) {
this.config = config;
this.baseUrl = config.isTestMode ? "https://sandbox.monnify.com/api/v1" : "https://api.monnify.com/api/v1";
}
async getAccessToken() {
const {
apiKey,
secretKey
} = this.config;
if (!apiKey || !secretKey) {
throw new Error("API key and secret key are required");
}
const auth = Buffer.from(`${apiKey}:${secretKey}`).toString("base64");
try {
const res = await axios.post(`${this.baseUrl}/auth/login`, {}, {
headers: {
Authorization: `Basic ${auth}`,
'Content-Type': 'application/json'
},
timeout: 10000
});
if (!res.data?.responseBody?.accessToken) {
throw new Error(`Invalid response structure: ${JSON.stringify(res.data)}`);
}
return res.data.responseBody.accessToken;
} catch (error) {
//console.error("Authentication failed:", error.response?.data || error.message);
throw new Error(`Authentication failed: ${error.response?.data?.responseMessage || error.message}`);
}
}
async initializePayment(payload) {
try {
const token = await this.getAccessToken();
const requestBody = {
...payload,
contractCode: this.config.contractCode,
currencyCode: payload.currencyCode || "NGN",
redirectUrl: payload.redirectUrl || "https://webhook.site/payment-complete"
};
const res = await axios.post(`${this.baseUrl}/merchant/transactions/init-transaction`, requestBody, {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json'
},
timeout: 15000
});
if (!res.data?.responseBody?.checkoutUrl) {
throw new Error(`Invalid payment response: ${JSON.stringify(res.data)}`);
}
return {
checkoutUrl: res.data.responseBody.checkoutUrl,
transactionReference: res.data.responseBody.transactionReference
};
} catch (error) {
//console.error("Payment initialization failed:", error.response?.data || error.message);
throw new Error(`Payment initialization failed: ${error.response?.data?.responseMessage || error.message}`);
}
}
async verifyPayment(transactionReference) {
try {
const token = await this.getAccessToken();
const res = await axios.get(`${this.baseUrl}/merchant/transactions/query?paymentReference=${transactionReference}`, {
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json'
},
timeout: 10000
});
const paymentData = res.data.responseBody;
// Service-level verification - only return verified successful payments
if (paymentData.paymentStatus === 'PAID' && paymentData.completed) {
return {
success: true,
paymentStatus: paymentData.paymentStatus,
amount: paymentData.amount,
amountPaid: paymentData.amountPaid,
fee: paymentData.fee,
paymentReference: paymentData.paymentReference,
transactionReference: paymentData.transactionReference,
customerName: paymentData.customerName,
customerEmail: paymentData.customerEmail,
paymentMethod: paymentData.paymentMethod,
completedOn: paymentData.completedOn
};
} else {
throw new Error(`Payment not completed. Status: ${paymentData.paymentStatus}`);
}
} catch (error) {
//console.error("Payment verification failed:", error.response?.data || error.message);
throw new Error(`Payment verification failed: ${error.response?.data?.responseMessage || error.message}`);
}
}
async handlePaymentCompletion(paymentReference) {
try {
// Minimal wait for payment to process
await new Promise(resolve => setTimeout(resolve, 500));
// Verify payment at service level
const verifiedPayment = await this.verifyPayment(paymentReference);
return verifiedPayment;
} catch (error) {
// Return failure response for frontend
return {
success: false,
error: error.message,
paymentStatus: 'FAILED'
};
}
}
}
//# sourceMappingURL=monnify.js.map