Skip to content

Instantly share code, notes, and snippets.

@YohannesTz
Created June 1, 2024 07:48
Show Gist options
  • Save YohannesTz/27d4dccf49196cdab81979a3f30196c6 to your computer and use it in GitHub Desktop.
Save YohannesTz/27d4dccf49196cdab81979a3f30196c6 to your computer and use it in GitHub Desktop.
bookRepository.getChapaLink = async (userId, bookId) => {
let result = {
success: false,
error: null,
checkoutUrl: null
};
try {
// Retrieve the book details by bookId
const book = await bookRepository.getById(bookId);
if (!book) {
result.error = "Book does not exist!";
return result;
}
const user = await userRepository.getById(userId);
if (!user) {
result.error = "User does not exist!";
return result;
}
// Assuming the book object has a price property
const price = book.price;
// Generate transaction reference using our utility method or provide your own
const txRef = await chapa.generateTransactionReference();
// Initialize Chapa payment
const chapaRequestData = {
amount: price,
currency: 'ETB',
email: user.email,
first_name: user.fname,
last_name: user.lname,
tx_ref: txRef,
callback_url: 'http://localhost:3000/api/v1/books/callback', // Replace with your callback URL
return_url: 'http://localhost:3000/api/v1/books/return', // Replace with your return URL
customization: {
title: 'Book Purchase',
},
};
const chapaResponse = await fetch('https://api.chapa.co/v1/transaction/initialize', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.CHAPA_SECRET_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(chapaRequestData)
});
const responseData = await chapaResponse.json();
console.log("chapa response\n", responseData);
if (responseData.status === 'success') {
result.success = true;
result.checkoutUrl = responseData.data.checkout_url;
} else {
result.error = responseData.message || "Failed to initialize payment!";
}
} catch (error) {
console.error(error);
result.error = error.toString();
}
return result;
};
bookRepository.paymentCallback = async (event) => {
console.log("payment callback called...");
console.log(event);
try {
const { chapa_reference: txRef } = event;
// Select transaction by reference
const transaction = await transactionRepository.getByTransactionRef(txRef);
if (!transaction) {
throw new Error("Transaction not found!");
}
// Update transaction status
const updatedTransaction = await transactionRepository.updateStatus(transaction.id, 1); // Assuming status 1 means success
if (!updatedTransaction) {
throw new Error("Failed to update transaction status!");
}
// Add a new row to userBooks repository using the date from reference
const newUserBook = await userBooksRepository.create({
userId: transaction.userId,
bookId: transaction.bookId,
progress: 0, // Assuming initial progress is 0
});
if (!newUserBook) {
throw new Error("Failed to create new user book entry!");
}
return {
success: true,
message: "Payment callback processed successfully!"
};
} catch (error) {
console.error(error);
return {
success: false,
error: error.message || "An error occurred during payment callback processing."
};
}
};
//literally doing this because I don't know which method chapa use
router.post("/books/callback", bookController.paymentCallback);
router.get("/books/callback", bookController.paymentCallback);
router.options("/books/callback", bookController.paymentCallback);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment