Checksum

Learn how to secure your client-side payment integration.

To secure payment on the client side, include a field called payload_hash in your request with a hashed value.
This hash is created by encrypting some immutable values in your request. We will then compute the hash values at runtime and compare them with the value from your request to ensure your payment is indeed secure.

ℹ️

Tip

If you are making payments using any of the integration methods like Inline, Standard, or HTML Checkout, ensure you pass in the hash value in all your requests.

To generate the hash, follow these steps:

  1. Retrieve the transaction data (amount, currency, customer_email, and tx_ref).
  2. Create a SHA256 value of your secret key.
  3. Concatenate the values of your transaction data and your hashed secret key in this exact order, with no separators.
  4. Generate a SHA256 hash of the concatenated string in step 3.
  5. Add the generated hash from Step 4 to the payload_hash field of the checkout object, and then render the checkout page.
  6. Prompt your user to complete the payment.
  7. After completing the payment, verify the transaction as you normally would before providing value to the user.

ℹ️

Tip

When generating a hash, make sure to use a secure backend server that utilizes your secret key. Do not fetch the data from the request body of your HTTP request. Instead, fetch it from a secure datastore.


Request with payload hash

Below is an example of how to generate and send a payload_hash using NodeJs and Python.


const getDataForHash  = (reference_number) => {
// Retrieve data [customer_email, tx_ref, currency, amount] from your preferred data store using a reference number or identifier of your choice.
}
const hashedSecretKey = crypto.createHash("sha256").update(process.env.FLW_SEC_KEY, 'utf8').digest("hex");
const StringToBeHashed = amount + currency + customer_email + tx_ref + hashedSecretKey;
const payload_hash = crypto.createHash("sha256").update(StringToBeHashed, 'utf8').digest("hex");

console.log(payload_hash);
import hashlib, os
from dotenv import load_dotenv

load_dotenv() 

secretKey = os.getenv('SECRET_KEY')
publicKey = os.getenv('PUBLIC_KEY')

data = {
    # enter your request payload here
}

def shaEncryption(input):
    encoded_bytes = input.encode()
    sha256 = hashlib.sha256()
    sha256.update(encoded_bytes)
    encryptedString = sha256.hexdigest()
    return encryptedString

hashedSecretKey = shaEncryption(secretKey)
StringToBeHashed = str(data["amount"]) + data["currency"] + data["customer"]["email"] + data["tx_ref"] + hashedSecretKey
payload_hash = shaEncryption(StringToBeHashed)
print(payload_hash)
<script src="https://checkout.flutterwave.com/v3.js"></script>

<form>
 <button type="button" onclick="makePayment()">Pay Now</button>
</form>

<script>
 function makePayment() {
   const FLW_PUBLIC_KEY = process.env.FLW_PUBLIC_KEY;
     FlutterwaveCheckout({
      public_key: FLW_PUBLIC_KEY,
      amount: '100',
      tx_ref: 'YOUR_PAYMENT_REFERENCE',
      currency: 'NGN',
      customer: {
        email: '[email protected]',
        phone_number: '09012345678',
        name: 'John Doe',
      },
      redirect_url: 'https://example_company.com/success',
      customizations: {
        title: 'Test Payments',
      },
      payload_hash: "YOUR_ENCRYPTED_HASH"
    });
 }
</script>

If any value in the payload is tampered with, causing it to be inconsistent with the generated hash, we will return an error message to the customer on the Flutterwave Checkout page once the payment is submitted.

Before updating your customers' account value, make sure to verify the payment details by comparing the amount, currency, and reference on both receipts.