Checksum
This page describes how to implement checksum for adding quidpay's inline js
How Integrity checksum works
Quidpay helps secure your payments on the client side using an integrity hash
, we would explain how integrity hash works:
Using an integrity hash
you are meant to sort the payment request parameter's you send in your getpaidSetup
function, on your server e.g.
[ 'PBFPubKey',
'amount',
'country',
'currency',
'custom_description',
'custom_logo',
'custom_title',
'customer_email',
'customer_firstname',
'customer_lastname',
'customer_phone',
'payment_method',
'txref' ]
We would pick up the parameters you sent in your getpaidSetup function sort it, compute the hash and compare the it with the value of integrity_hash
to make sure they match. This means that values you hash must match the values you passed to us in your getpaidSetup function.
Rule of thumb
- Make sure you send your
integrity_hash
value in lower case, the server computes the hash in lowercase so they need to match.
- Make sure your values are sorted and hashed using the same letter cases as what you add in your
getpaidSetup
function i.e. if you hash customer_firstname: JIDENNA, then you need to pass it to the client as customer_firstname: JIDENNA. and vice-versa.
- For amount with decimal places, if decimal places have trailing zero's e.g. 100.000 , remove all trailing zero's.
Hash your pay button values on your server and send the hash to the client page
Quidpay inline secures payment on your site using an Integrity hash. You should always create the values you are passing to your inline js script on your server, after creating the value you hash it using a hashing algorithm called Sha 256 . Once the value is hashed send the value to the client and add it as parameter to your inline script. The steps to hash are listed below:
Step 1: Create payment request parameters and values on your server
integrityValue: (req, res) => {
const hashedPayload = '';
const payload = {
"PBFPubKey": 'FLWPUBK-e634d14d9ded04eaf05d5b63a0a06d2f-X',
"amount": 20,
"payment_method": "both",
"custom_description": "Pay Internet",
"custom_logo": "http://localhost/payporte-3/skin/frontend/ultimo/shoppy/custom/images/logo.svg",
"custom_title": "Shoppy Global systems",
"country": "NG",
"currency": "NGN",
"customer_email": '[email protected]',
"customer_firstname": 'Temi',
"customer_lastname": "Adelewa",
"customer_phone": "234099940409",
"txref": "MG-" + Date.now()
};
$pb_key = "FLWPUBK-7adb6177bd71dd43c2efa3f1229e3b7f-X";
$amount_in_naira = 900;
$customer_email = "[email protected]";
$customer_firstname = "user";
$customer_lastname = "example";
$txref = "MV-1838383-JH";
$pmethod = "both";
$seckey = "FLWSECK-e6db11d1f8a6208de8cb2f94e293450e-X";
$country = "NG";
$currency = "NGN";
$custom_description = "Hey Quidpay";
$custom_logo = "http://logo.com";
$custom_title = "Ravepay";
$customer_phone = "+2348185615980";
$options = array(
"PBFPubKey" => $pb_key,
"amount" => $amount_in_naira,
"customer_email" => $customer_email,
"customer_firstname" => $customer_firstname,
"txref" => $txref,
"payment_method" => $pmethod,
"customer_lastname" => $customer_lastname,
"country" => $country,
"currency" => $currency,
"custom_description" => $custom_description,
"custom_logo" => $custom_logo,
"custom_title" => $custom_title,
"customer_phone" => $customer_phone
);
Step 2: Sort the parameters this way: Ascii (value) Sort keys of data to send
// The keys in step 1 above are sorted by their ASCII value
const keys = Object.keys(payload).sort();
// The sorted keys would be outputed in this format:
[ 'PBFPubKey',
'amount',
'country',
'currency',
'custom_description',
'custom_logo',
'custom_title',
'customer_email',
'customer_firstname',
'customer_lastname',
'customer_phone',
'payment_method',
'txref' ]
// The keys in step 1 above are sorted by their ASCII value
ksort($options);
var_dump($options); // check the order of the keys in the array.
// The sorted keys would be outputed in this format:
array(13) {
["PBFPubKey"]=>
string(42) "FLWPUBK-7adb6177bd71dd43c2efa3f1229e3b7f-X"
["amount"]=>
int(900)
["country"]=>
string(2) "NG"
["currency"]=>
string(3) "NGN"
["custom_description"]=>
string(8) "Hey Quidpay"
["custom_logo"]=>
string(15) "http://logo.com"
["custom_title"]=>
string(7) "Ravepay"
["customer_email"]=>
string(16) "[email protected]"
["customer_firstname"]=>
string(4) "user"
["customer_lastname"]=>
string(7) "example"
["customer_phone"]=>
string(14) "+2348185615980"
["payment_method"]=>
string(4) "both"
["txref"]=>
string(13) "MV-1838383-JH"
}
Step 3: Concatenate the values in the order of your sorted keys e.g.
// The payload is rearranged and the values concatenated in the order of the sorted keys.
for(var index in keys){
const key = keys[index];
hashedPayload += payload[key];
}
// The above sample would output a string that looks like this:
"FLWPUBK-e634d14d9ded04eaf05d5b63a0a06d2f-X20NGNGNPay Internethttp://localhost/payporte-3/skin/frontend/ultimo/shoppy/custom/images/logo.svgShoppy Global systemsuser@example.comTemiAdelewa234099940409bothMG-1500041286295"
// The payload is rearranged and the values concatenated in the order of the sorted keys.
$hashedPayload = '';
foreach($options as $key => $value){
$hashedPayload .= $value;
}
// The above sample would output a string that looks like this:
FLWPUBK-7adb6177bd71dd43c2efa3f1229e3b7f-X900NGNGNHey Ravehttp://[email protected]+2348185615980bothMV-1838383-JHFLWSECK-e6db11d1f8a6208de8cb2f94e293450e-X
Step 4: Create a full string to be hashed by concatenating the result from step 3 with your secret key
// This creates a the full string to be hashed:
hashString = hashedPayload + "FLWSECK-bb971402072265fb156e90a3578fe5e6-X";
// This creates a the full string to be hashed:
$completeHash = $hashedPayload.$seckey;
echo "$completeHash\n";
Using Secret key in your application
Always store your
secret key
in an environment variable, don't expose it in your code, you would most likely commit it, and it would be exposed to the public. You can add it in your code using an environment variable.
Step 5: Generate a Sha256 hash of the hashstring and send to your Client page.
// Generate the sha256 hash of the concatenated strings
const sha256Hash = createHash('sha256').update(hashString, 'utf8').digest('hex');
// Send the hash and any dynamic value to your client.
res.json({hash: sha256Hash, txref: payload.txref});
// Generate the sha256 hash of the concatenated strings
$hash = hash('sha256', $completeHash);
echo "$hash";
Once the user clicks the button for the modal to open up, if they change any value on the browser the modal would not be opened and an error would be returned.
Step 6: Pass the integrity hash to quidpay.
HTML EMBED
When using the html embed pass it in as
data-integrity_hash
.
<form>
<button type="button" style="cursor:pointer;" value="Pay Now" id="submit">Pay Now</button>
</form>
<script type="text/javascript" src="https://api.ravepay.co/flwv3-pug/getpaidx/api/quidpay-inline.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function(event) {
const paybutton = document.getElementById("submit");
paybutton.addEventListener("click", function(e) {
const API_publicKey = "FLWPUBK-24b72aebb821aea177483039677df9d3-X";
getpaidSetup({
PBFPubKey: API_publicKey,
customer_email: "[email protected]",
amount: 2000,
customer_phone: "234099940409",
currency: "NGN",
payment_method: "both",
txref: "quidpay-123456",
integrity_hash: "<PASS YOUR INTEGRITY HASH HERE>"
meta: [{metaname:"flightID", metavalue: "AP1234"}],
onclose: function() {},
callback: function(response) {
var flw_ref = response.tx.flwRef; // collect flwRef returned and pass to a server page to complete status check.
console.log("This is the response returned after a charge", response);
if (
response.tx.chargeResponseCode == "00" ||
response.tx.chargeResponseCode == "0"
) {
// redirect to a success page
} else {
// redirect to a failure page.
}
}
});
});
});
</script>
Error returned for a bad integrity hash
Updated about 6 years ago