Skip to content

Instantly share code, notes, and snippets.

@limistah
Created August 7, 2020 13:23
Show Gist options
  • Save limistah/5da0699415a3d4a543c71789c10f6137 to your computer and use it in GitHub Desktop.
Save limistah/5da0699415a3d4a543c71789c10f6137 to your computer and use it in GitHub Desktop.
Card Charge - Rave Pay By Flutterwave
const inputs = require("./inputs");
const {initializeCharge} = require("./initializeCharge");
const {validateCharge} = require("./validateCharge");
const {authorizeCharge} = require("./authorizeCharge");
const {validateCharge} = require("./validateCharge");
const {verifyCharge} = require("./verifyCharge");
// 1. Initialize a charge on the card
initializeCharge(inputs.cardPayload, (err, res, body) => {
if (body && body.data && body.data.status === "success-pending-validation") {
// 1.1 Card has been authorized before but not validated
const payload = {
PBFPubKey: process.env.PUB_KEY,
transaction_reference: body.data.flwRef,
otp: "181971713", // testing purposes
};
validateCharge(payload);
}
if (body.status === "success" && body.data.suggested_auth === "PIN") {
// 2. Request authorization using PIN auth mode
authorizeCharge(payload, (err, res, body) => {
if (body.data.flwRef) {
// 3. Validate the charge
// This stage, the charge becomes successful
validateCharge(body.data.flwRef, (err, res, body) => {
// We can store the embed_model for future charge with no card details collection
if (body.data){
// 4. Verify if the charge actually went through
verifyCharge(body.data.tx.txRef, (err, res, body) => {
if (err) {
console.log(err)
process.exit(1)
}
// Transaction is valid
console.log(body)
});
} else {
console.log(err)
}
});
} else {
console.log(err)
}
});
}
});
// Authorize a charge
function authorizeCharge(payload, callback) {
payload.pin = "3310", // pin included in authorization
payload = makePayload(payload);
makeRequest("/charge", payload, callback)
}
module.exports = {authorizeCharge}
const forge = require("node-forge");
/**
*
* @param {string} key Encryption Key from flutterwave dashboard
* @param {string} text JSON stringified card payload
*/
function encrypt(key, text) {
const cipher = forge.cipher.createCipher(
"3DES-ECB",
forge.util.createBuffer(key)
);
cipher.start({
iv: "",
});
cipher.update(forge.util.createBuffer(text, "utf-8"));
cipher.finish();
const encrypted = cipher.output;
return forge.util.encode64(encrypted.getBytes());
}
// Initialize a charge
const initChargeCharge = (payload, callback) => {
payload = makePayload(payload);
makeRequest("/charge", payload, callback)
};
const ENC_KEY = "FLWSECK_TEST2d34d5de933c";
const PUB_KEY = "FLWPUBK_TEST-053ed313ddd5d245d55823276ae48664-X";
const SEC_KEY = "FLWSECK_TEST-758959aabbc42e25fbe42990728a9a4a-X";
const cardPayload = {
PBFPubKey: process.env.PUB_KEY,
cardno: "5438898014560229",
cvv: "890",
expirymonth: "09",
expiryyear: "20",
currency: "NGN",
country: "NG",
amount: "10",
email: "user@gmail.com",
phonenumber: "0902620185",
firstname: "temi",
lastname: "desola",
IP: "355426087298442",
txRef: "MC-" + Date.now(), // unique merchant reference
meta: [{ metaname: "flightID", metavalue: "123949494DC" }], // Uique details to be attached to the payment
redirect_url: "https://rave-webhook.herokuapp.com/receivepayment",
device_fingerprint: "69e6b7f0b72037aa8428b70fbe03986c",
};
module.export = {cardPayload}
function makePayload (payload, encryptPayload = true) {
// Converts payload to JSON
let params = encryptPayload ? JSON.stringify(payload) : payload;
// Encrypt the stringified payload
let encrypted = encryptPayload ? encrypt(process.env.ENC_KEY, params) : params;
switch (encryptPayload) {
case false:
return payload
default:
// Standard charge encryption payload for rave v2
return {
alg: "3DES-24",
PBFPubKey: process.env.PUB_KEY,
client: encrypted,
}
}
}
module.exports = { makePayload }
const request = require("request")
function makeRequest (url, payload, callback = () => {}) {
const requestOptions = {
path: uri || "/",
baseUrl: "",
method: "POST",
body:payload,
json: true,
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${SEC_KEY}`
}
};
request(requestOptions, function (err, res, body) {
if (typeof res == "undefined") {
res = {};
}
if (typeof body == "undefined") {
body = {};
}
callback(err, res, body)
});
}
module.exports = {makeRequest}
// Validate charge using either the address or otp sent to user's address
// Nigerian/african cards uses otp.
// UK cards uses address
// Authorize a charge
// sample payload
const payload = {
PBFPubKey: process.env.PUB_KEY,
transaction_reference: transaction_ref,
otp,
};
function validateCharge(payload, callback) {
payload = makePayload(payload, false);
makeRequest("/validatecharge", payload, callback)
}
module.exports = {validateCharge}
const verifyCharge = (txref) => {
let payload = {
txref,
SECKEY: process.env.SEC_KEY,
};
payload = makePayload(payload, false);
makeRequest("/v2/verify", payload, callback)
};
module.exports = {validateCharge}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment