McTaba Labs logo
Software EngineeringThe WhiteboardProjectsEventsMasterclassesWebinarsLearn
Book Call

500+ developers already in the community

Get answers, find accountability partners, and stay ahead

Join Discord →
McTaba Labs logo

Educating 1 million students in tech by 2030.

Programs

  • HighSchool Graduates Launchpad
  • AI & Business Automation
  • Corporate Training
  • McTaba Story & Mission
  • Full-Stack Curriculum
  • Course Pricing & Plans
  • Frequently Asked Questions

Resources

  • Join Discord Community
  • Tech Events in Nairobi
  • Masterclasses
  • Free Resources
  • Learn
  • Campus
  • Africa Tech Talent Report
  • Partner With Us
  • Start a Project
  • Our Work

Contact Us

  • 124 Manyani East Road, Lavington, Nairobi
  • +254727795603
  • Book a Discovery Call

Office Hours:

Mon-Fri: 9am - 2pm EAT

Sat: 10am - 12pm EAT

© 2027 McTaba Labs - A product of Edtech Industries. All rights reserved.

Privacy PolicyTerms of ServiceRefund Policy
  1. Learn
  2. Paystack for African Developers
  3. Data Protection Duties When Storing Verification Results
Bonaventure OgetoBy Bonaventure Ogeto|Updated July 20, 2026

Data Protection Duties When Storing Verification Results

Store only the verification result (verified or not), the timestamp, and a reference to the Paystack customer. Do not store raw BVN numbers unless legally required. Encrypt personal data at rest. Set retention periods (typically 2 to 7 years for financial records). Log consent before every verification. Give users the right to access and request deletion of their data, subject to regulatory retention requirements.

In this article

  1. 1. What Data You Collect Through Identity APIs
  2. 2. Data Minimization: Store Only What You Need
  3. 3. Encrypting Verification Data at Rest
  4. 4. Logging Consent
  5. 5. Setting Retention Policies
  6. 6. Honouring Data Subject Rights
  7. 7. Purpose Limitation
  8. 8. What to Do If Verification Data Is Breached

What Data You Collect Through Identity APIs

Each Paystack identity API returns different data. Know what you are collecting.

Resolve Account Number returns: the account holder name, account number (echoed back), and bank ID. The account holder name is personal data. The account number is sensitive personal data in the financial context.

Resolve Card BIN returns: card brand, issuing bank, card type, and country. This data is not personally identifiable on its own. The first 6 digits of a card cannot identify a specific person.

Validate Customer (BVN) returns: a match or mismatch result via webhook. If you submitted the BVN to make the call, you temporarily handled the BVN number, which is highly sensitive personal data in Nigeria.

The personal data you collect triggers obligations under the Nigeria Data Protection Act (NDPA, successor to NDPR), the Kenya Data Protection Act, and similar laws in Ghana and South Africa.

Data Minimization: Store Only What You Need

Data minimization is a core principle in every African data protection law. Collect and store only the data you need for the purpose you stated.

For account resolution: Store the resolved name (you need it for name matching) and the timestamp (you need it for audit trails). You do not need to store the raw bank ID unless you use it for something specific.

For BVN verification: Store the verification result (verified or not verified) and the timestamp. Do not store the BVN number itself. After the verification call completes and you record the result, discard the BVN from your application memory.

// good-storage.js
// DO: Store the result
await db.query(
  'INSERT INTO identity_verifications (user_id, type, verified, verified_at) VALUES ($1, $2, $3, NOW())',
  [userId, 'bvn', true]
);

// DO NOT: Store the raw BVN
// await db.query('INSERT INTO users (bvn) VALUES ($1)', [bvnNumber]);  // Bad practice

If you must store the BVN (some regulatory requirements may demand it): encrypt it with a dedicated encryption key separate from your database encryption. Restrict access to the decryption key. Log every access to the encrypted BVN field. Set a retention period and delete it when the period expires.

Get weekly developer tips

Join 25,000+ developers. Practical guides, job tips, and new content — straight to your inbox.

No spam. Unsubscribe anytime.

Encrypting Verification Data at Rest

All personal data from identity verifications should be encrypted at rest in your database.

// encrypt-field.js
var crypto = require('crypto');

var ENCRYPTION_KEY = process.env.IDENTITY_ENCRYPTION_KEY; // 32-byte key
var IV_LENGTH = 16;

function encrypt(text) {
  var iv = crypto.randomBytes(IV_LENGTH);
  var cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(ENCRYPTION_KEY, 'hex'), iv);
  var encrypted = cipher.update(text);
  encrypted = Buffer.concat([encrypted, cipher.final()]);
  return iv.toString('hex') + ':' + encrypted.toString('hex');
}

function decrypt(text) {
  var parts = text.split(':');
  var iv = Buffer.from(parts[0], 'hex');
  var encrypted = Buffer.from(parts[1], 'hex');
  var decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(ENCRYPTION_KEY, 'hex'), iv);
  var decrypted = decipher.update(encrypted);
  decrypted = Buffer.concat([decrypted, decipher.final()]);
  return decrypted.toString();
}

// Usage
var encryptedName = encrypt('OKAFOR JOHN DOE');
await db.query(
  'UPDATE account_resolution_cache SET account_name_encrypted = $1 WHERE id = $2',
  [encryptedName, cacheId]
);

Use a separate encryption key for identity data. Do not reuse your general application encryption key. If your application key is compromised, your identity data stays protected (and vice versa).

Database-level encryption is also an option. PostgreSQL Transparent Data Encryption (TDE) and similar features encrypt the entire database at rest. This is simpler but less granular than field-level encryption.

Logging Consent

Before calling any identity API, log that the user consented to the verification.

-- consent_log table
CREATE TABLE verification_consent_log (
  id SERIAL PRIMARY KEY,
  user_id INTEGER NOT NULL,
  verification_type TEXT NOT NULL,
  consent_text TEXT NOT NULL,
  consented_at TIMESTAMP NOT NULL DEFAULT NOW(),
  ip_address INET,
  user_agent TEXT
);

-- Example consent texts
-- 'I agree to verify my bank account details with Paystack for payout purposes.'
-- 'I agree to verify my identity (BVN) for enhanced account verification.'

What constitutes valid consent:

  • The user was told what data would be checked and why.
  • The user took an explicit action (clicked a button, submitted a form).
  • The consent was not bundled with unrelated actions.
  • The user could decline without being blocked from the entire product (only from the features requiring verification).

Store the exact consent text shown to the user. If you change the consent wording later, old records should reflect what the user actually agreed to at the time.

Setting Retention Policies

Do not keep identity data forever. Set retention periods based on regulatory requirements and delete data when the period expires.

Financial record retention: Most African jurisdictions require financial institutions to keep records for 5 to 7 years. If you are not a financial institution, your requirements may be shorter. Consult your legal team.

Verification results: Keep for the duration of the customer relationship plus the required retention period (typically 2 to 5 years after the last transaction).

Cached account names: Keep for 30 days for caching purposes. After 30 days, the cache entry expires and will be refreshed on the next lookup.

Consent records: Keep as long as the data they relate to exists, plus 1 year. If someone asks "when did I consent to BVN verification?" you need the answer.

// cleanup-job.js
// Run monthly
async function cleanupExpiredData() {
  // Delete expired resolution cache
  var deleted = await db.query(
    'DELETE FROM account_resolution_cache WHERE expires_at < NOW() RETURNING id'
  );
  console.log('Deleted ' + deleted.rowCount + ' expired cache entries');

  // Delete verification records past retention
  var retentionYears = 5;
  var deletedVerifications = await db.query(
    'DELETE FROM identity_verifications ' +
    'WHERE verified_at < NOW() - INTERVAL '' + retentionYears + ' years' ' +
    'AND user_id NOT IN (SELECT user_id FROM active_users) ' +
    'RETURNING id'
  );
  console.log('Deleted ' + deletedVerifications.rowCount + ' expired verifications');
}

Honouring Data Subject Rights

Under the Kenya DPA, Nigeria NDPA, and GDPR (if you serve EU residents), users have specific rights over their personal data.

Right to access. If a user asks "what identity data do you have about me?" you must be able to answer. Build an endpoint or admin tool that compiles all verification data for a given user.

Right to rectification. If verification data is wrong (misspelled name, wrong verification result), the user can request correction. You may need to re-run the verification to confirm the correct data.

Right to deletion. A user can request deletion of their personal data. However, if regulatory requirements mandate that you keep financial records for a certain period, you can decline deletion until the retention period expires. Explain this to the user clearly.

Right to know the purpose. Users can ask why you collected their identity data and what you are doing with it. Your answer should match what you told them at consent time.

// data-export.js
async function exportUserIdentityData(userId) {
  var verifications = await db.query(
    'SELECT verification_type, verified, verified_at FROM identity_verifications WHERE user_id = $1',
    [userId]
  );

  var consents = await db.query(
    'SELECT verification_type, consent_text, consented_at FROM verification_consent_log WHERE user_id = $1',
    [userId]
  );

  var cached = await db.query(
    'SELECT account_number, bank_code, account_name, resolved_at ' +
    'FROM account_resolution_cache WHERE account_number IN ' +
    '(SELECT bank_account_number FROM kyc_verifications WHERE user_id = $1)',
    [userId]
  );

  return {
    verifications: verifications.rows,
    consents: consents.rows,
    cached_resolutions: cached.rows,
  };
}

Purpose Limitation

Data collected for identity verification must only be used for identity verification. This is called purpose limitation, and every major data protection law enforces it.

What you can do: Use the resolved account name for name matching in payout flows. Use the verification result to determine KYC tier and transaction limits. Use the data for fraud detection directly related to payment processing.

What you cannot do: Use resolved account names to build marketing profiles. Use BVN verification data for credit scoring unless the user explicitly consented to that specific purpose. Share verification data with third parties for purposes unrelated to payment processing.

If you want to use identity data for a new purpose (say, credit scoring), you need fresh consent from the user for that specific purpose. The original consent for payment verification does not cover credit scoring.

What to Do If Verification Data Is Breached

If your database is compromised and identity verification data is exposed, you have legal obligations.

Nigeria NDPA: Report the breach to the Nigeria Data Protection Commission (NDPC) within 72 hours. Notify affected users if the breach poses a high risk to their rights.

Kenya DPA: Report to the Office of the Data Protection Commissioner (ODPC) within 72 hours. Notify affected data subjects.

Practical steps:

  1. Contain the breach: identify how the data was accessed and close the vulnerability.
  2. Assess the impact: how many users are affected? What data was exposed?
  3. Notify the regulator within 72 hours with details of the breach.
  4. Notify affected users with clear language: what happened, what data was exposed, what you are doing about it, and what they should do.
  5. If BVN data was exposed, advise users to contact their banks and monitor their accounts for suspicious activity.

This is why data minimization matters. If you only stored verification results (pass/fail) and not raw BVNs, a breach exposes far less sensitive data.

Key Takeaways

  • ✓Apply data minimization: store the verification result (pass/fail), not the raw identity data. You do not need the BVN itself after verification.
  • ✓Encrypt personal data at rest. Account names, verification results, and customer codes should be in encrypted database columns or an encrypted database.
  • ✓Set retention periods. Financial regulations typically require 2 to 7 years of record keeping. After the retention period, delete the data.
  • ✓Log consent before every identity check. Record when the user consented, what they consented to, and how they were informed.
  • ✓Honour data subject access requests. Users have the right to know what data you hold about them and to request corrections.
  • ✓Keep verification data separate from marketing data. Identity information collected for KYC should never be used for advertising.

Frequently Asked Questions

Do I need to register as a data controller to store verification results?
In Nigeria, organizations that process personal data are required to file a compliance audit with the NDPC. In Kenya, you may need to register with the ODPC depending on the scale and nature of your data processing. Consult your legal team for your specific situation.
Can I store verification data in a cloud database outside Africa?
The Kenya DPA requires that personal data of Kenyan citizens be processed in Kenya, with some exceptions. The Nigeria NDPA has cross-border transfer provisions that require adequate protection in the destination country. Check the specific requirements for your target markets before choosing a database region.
How long should I keep BVN verification results?
Keep the verification result (pass or fail) for the duration of the customer relationship plus your regulatory retention period, typically 5 to 7 years for financial records. If you stored the BVN number itself, delete it as soon as verification is complete unless regulation specifically requires you to retain it.
What if a user asks me to delete their data but I need it for regulatory compliance?
You can retain data required by law for the regulatory retention period, even if the user requests deletion. Inform the user that their data will be deleted after the retention period expires. You should still delete any data that is not required by regulation.

Learn Paystack Integration

KES 2,999

The definitive guide to building payment systems with Paystack — from your first transaction to production-grade payment infrastructure across Africa. 9 modules, 47 lessons. Free preview available.

Start Paystack Course

Not ready? Create Free Account

Keep reading

Paystack Identity Verification: Complete Guide

Paystack gives you three identity endpoints: resolve account number, resolve card BIN, and validate customer (BVN). This guide shows you how to use each one, build a KYC flow around them, and stay within the Kenya DPA and Nigeria NDPR while doing it.

Read more

Validating a Customer Before Payout

Every payout you send is money you cannot get back. Validating the recipient before initiating a transfer is not optional. This guide shows you how to chain Paystack identity APIs into a validation gate that catches wrong accounts, name mismatches, and suspicious requests before a single kobo leaves your account.

Read more

Building a KYC Flow on Paystack Identity APIs

A KYC flow is not a single API call. It is a sequence of verification steps that increase in strength as the user needs more from your product. This guide shows you how to chain Paystack identity APIs into a progressive KYC system with tiers, database tracking, and clear UX at every step.

Read more

Handling Identity Verification Failures Gracefully

Identity verification calls fail. Banks go offline. Networks time out. BVN checks return unexpected errors. Your job is to handle every failure in a way that does not strand the user. This guide covers every failure mode, the right response for each, and how to build a verification flow that stays useful even when upstream systems break.

Read more

Storing Paystack Keys in Environment Variables Properly

Environment variables are the standard way to keep Paystack API keys out of source code. But developers still get it wrong by committing .env files, mixing up public and secret key variables, or exposing server keys through frontend build tools. This guide covers the right way to do it across every major framework.

Read more

Explore related topics

M-Pesa & African Stack

M-Pesa Daraja API tutorials, USSD development, and WhatsApp Business API guides. The African Stack that global bootcamps do not teach.

Learn to Code in Kenya

Everything a Kenyan needs to know before writing their first line of code. Career paths, real costs, hardware requirements, and honest answers about what it takes.

Learning to Code

Roadmaps, language guides, and practical advice for learning to code and launching a programming career.

Breaking Into Tech

Practical, no-nonsense guides for anyone looking to start or change their career in tech. From choosing your first language to acing interviews.

The African Stack: Skills for This Market

The skills that make Kenyan developers hard to replace: M-Pesa, USSD, WhatsApp, fintech, and building for the African market.

Bonaventure Ogeto

Bonaventure Ogeto

Founder, McTaba Labs

Bonaventure is the founder of McTaba Labs, a coding bootcamp in Nairobi, Kenya. He has spent years building products for the African market and mentoring the next generation of developers across the continent.