Resolve Card BIN: What It Tells You and What It Does Not
Call GET https://api.paystack.co/decision/bin/:bin with the first 6 digits of a card number. Paystack returns the card brand (Visa, Mastercard, Verve), issuing bank name, card type (debit, credit, prepaid), and country of issue. Use this for displaying card logos, fraud screening (flag foreign cards on a domestic-only product), and routing logic. It does not reveal the cardholder name, balance, or whether a transaction will succeed.
What Is a Card BIN
Every payment card has a number printed on its front. The first 6 digits of that number are the Bank Identification Number (BIN). The industry is moving to 8-digit BINs, but 6 digits remain the standard for most lookups.
The BIN encodes three things:
- Which bank issued the card. GTBank, Access Bank, Standard Chartered, any issuing institution.
- Which card network processes it. Visa, Mastercard, Verve, American Express.
- What type of card it is. Debit, credit, or prepaid.
When a user types the first 6 digits of their card number into your checkout form, you already have enough information to know their card brand and issuing bank. Paystack's Resolve Card BIN endpoint turns those digits into structured data you can use.
Calling the Resolve Card BIN Endpoint
The call is simple. It is a GET request with the 6-digit BIN in the URL path.
// resolve-bin.js
const axios = require('axios');
async function resolveCardBin(bin) {
var response = await axios.get(
'https://api.paystack.co/decision/bin/' + bin,
{
headers: {
Authorization: 'Bearer ' + process.env.PAYSTACK_SECRET_KEY,
},
}
);
return response.data.data;
}
// Usage
var binData = await resolveCardBin('408408');
console.log(binData.brand); // "visa"
console.log(binData.bank); // "Test Bank"
console.log(binData.card_type); // "debit"
console.log(binData.country_code); // "NG"
Response fields:
bin: the 6 digits you sent, echoed back.brand: "visa", "mastercard", "verve", etc.bank: the name of the issuing bank.card_type: "debit", "credit", or "prepaid".country_code: two-letter ISO country code like "NG", "KE", "GH".country_name: full country name like "Nigeria".
When to call it. Call it as soon as the user has typed 6 digits into the card number field. You do not need the full card number. This lets you show the card logo and run fraud checks before the user finishes typing.
What BIN Data Tells You
1. Card brand for UI display. Once you know the brand is Visa, show the Visa logo next to the card input. This gives users confidence they typed correctly. If a user expects to see a Mastercard logo but sees Visa, they know to re-check their card number.
2. Card type for routing decisions. Some businesses handle debit and credit cards differently. You might apply different processing logic for prepaid cards (which have hard limits) versus credit cards. Some African merchants refuse prepaid cards entirely because of higher fraud rates.
3. Country for fraud screening. If your product is only available in Nigeria, a card issued in Russia is suspicious. You can flag it for manual review rather than blocking it outright (legitimate customers travel and use cards abroad).
4. Issuing bank for analytics. Over time, you can track which banks your customers use most. This helps with customer support (you know which bank to reference when helping with payment issues) and with business decisions about bank partnerships.
5. Surcharge logic. In some markets, card types attract different interchange rates. While you should not display fee breakdowns to users (Paystack handles settlement), the information can help you understand your cost structure.
What BIN Data Does Not Tell You
BIN resolution has clear limits. Misunderstanding them leads to bad decisions.
It does not tell you who owns the card. You get the bank name, not the cardholder name. If you need the cardholder name, you must get it from the user or from the transaction response after a successful charge.
It does not tell you the card balance. You cannot check if a debit card has enough funds before charging. The only way to know if a charge will succeed is to attempt it.
It does not confirm the card is active. A card might have been cancelled, expired, or blocked. The BIN still resolves because BIN data is about the card type, not the card status.
It does not predict transaction success. A valid BIN from a reputable Nigerian bank can still fail due to insufficient funds, card restrictions, bank downtime, or fraud blocks.
It is not a fraud detector. A foreign BIN does not equal fraud. Nigerians living abroad use foreign-issued cards legitimately. A local BIN does not equal safety. Stolen cards have local BINs too.
Using BIN Data for Fraud Screening
BIN data is one signal among many. It is useful when combined with other data points, dangerous when used alone.
Flag, do not block. If a transaction comes from an unexpected card country, flag it for review rather than rejecting it immediately. A Nigerian user visiting the UK might use a UK-issued card.
// bin-fraud-check.js
function assessBinRisk(binData, expectedCountry) {
var signals = [];
if (binData.country_code !== expectedCountry) {
signals.push({
type: 'UNEXPECTED_COUNTRY',
detail: 'Card issued in ' + binData.country_name + ', expected ' + expectedCountry,
severity: 'medium',
});
}
if (binData.card_type === 'prepaid') {
signals.push({
type: 'PREPAID_CARD',
detail: 'Prepaid cards have higher fraud rates',
severity: 'low',
});
}
return {
riskLevel: signals.length === 0 ? 'low' : 'elevated',
signals: signals,
};
}
Combine with other signals. BIN country mismatch plus a brand new account plus a high-value transaction is worth investigating. BIN country mismatch alone is not.
For a broader look at fraud signals in Paystack transaction data, see the fraud signals guide.
Caching BIN Results
BIN data is static. The 6-digit prefix 408408 will always belong to the same bank, same network, same card type. Cache aggressively.
// cached-bin-resolve.js
var binCache = new Map();
async function resolveBinCached(bin) {
if (binCache.has(bin)) {
return binCache.get(bin);
}
var result = await resolveCardBin(bin);
binCache.set(bin, result);
return result;
}
Cache forever. Unlike account names (which can change), BIN data is permanent. You can cache it indefinitely in memory, in Redis, or in your database. A simple in-memory Map works for most applications. If you process cards from thousands of different BINs, use a database table.
-- bin_cache table
CREATE TABLE bin_cache (
bin CHAR(6) PRIMARY KEY,
brand TEXT NOT NULL,
bank TEXT,
card_type TEXT,
country_code CHAR(2),
country_name TEXT,
cached_at TIMESTAMP NOT NULL DEFAULT NOW()
);
Why caching matters. Every BIN lookup hits Paystack's API. If your checkout form calls Resolve Card BIN every time a user types 6 digits (including corrections and re-entries), you burn through API calls quickly. With caching, most lookups resolve instantly from local storage.
Integrating BIN Data into Your Checkout UX
The best use of BIN data is often invisible to the user. It makes small UX improvements that build confidence without adding friction.
Auto-detect card logo. As soon as the user types 6 digits, show the card brand logo (Visa, Mastercard, Verve). This reassures them that your system recognises their card.
Pre-fill card type. If you have separate flows for credit and debit cards, auto-select the correct one based on BIN data. Do not make the user choose.
Country mismatch warning. If your product is only available in a specific country and the card is from elsewhere, show a gentle warning: "This card was issued outside Nigeria. You can still proceed, but please confirm your details." This is better than a hard block.
Error prevention. If the BIN lookup fails (returns a 404), the first 6 digits likely do not correspond to any known card. The user may have mistyped. Show a "Please check your card number" message early, before they finish filling the form.
Keep the BIN lookup on your backend, not the frontend. The endpoint requires your secret key. Have your frontend send the first 6 digits to your server, which calls Paystack and returns the card brand and type.
Testing BIN Resolution
With test keys, Paystack returns test data for certain BIN values. The test BIN 408408 is the standard Paystack test card prefix.
Test scenarios to cover:
- Valid BIN: returns brand, bank, card type, country.
- Invalid BIN (e.g., "000000"): returns a 404 or empty result.
- Non-numeric input: your validation should reject this before calling the API.
- Short input (fewer than 6 digits): your validation should wait for 6 digits before calling.
In automated tests, mock the BIN response rather than calling Paystack. BIN data is deterministic, so a mock is perfectly reliable.
For more on testing Paystack integrations, see the complete testing guide.
Key Takeaways
- ✓The BIN (Bank Identification Number) is the first 6 digits of any card number. It identifies the issuing bank, card network, and card type.
- ✓Paystack Resolve Card BIN returns: brand (Visa/Mastercard/Verve), bank name, card type (debit/credit/prepaid), and country code.
- ✓It does not return the cardholder name, available balance, card expiry, or whether a transaction will succeed.
- ✓Use BIN data for UX improvements like auto-displaying the correct card logo and for fraud screening like flagging unexpected card countries.
- ✓Cache BIN results aggressively. A given 6-digit prefix always maps to the same bank and card type. The data does not change.
- ✓Never use BIN data as a sole fraud signal. A Nigerian card used by a legitimate diaspora customer is not fraud.
Frequently Asked Questions
- Does Resolve Card BIN require the full card number?
- No. It only needs the first 6 digits, called the BIN. Never send the full card number to any endpoint other than Paystack's tokenization or charge endpoints. The BIN alone is not sensitive data.
- Can I use Resolve Card BIN from the frontend?
- No. The endpoint requires your secret key in the Authorization header. Send the first 6 digits from the frontend to your backend, call Paystack from there, and return only the brand and card type to the frontend.
- What happens if the BIN is not in Paystack's database?
- Paystack returns a 404 or an empty result. This can happen with very new card issuances or obscure international banks. Handle this gracefully: proceed with the transaction without BIN data rather than blocking the user.
- Is BIN data considered sensitive or PCI-regulated?
- The first 6 digits of a card number are generally not considered sensitive data under PCI DSS. They identify the bank and card type, not the individual cardholder. You can store and cache them freely.
- Should I block transactions from unexpected card countries?
- Usually not. Flag them for review instead of blocking. Many legitimate customers use cards issued in countries different from where they live or shop. Blocking based on card country alone creates false positives and frustrates real customers.
Ready to build real-world apps?
Join the McTaba Labs full-stack marathon (4 months full-time · 6 months part-time). Learn M-Pesa, USSD, and WhatsApp engineering while shipping 8 production apps.
Apply to the McTaba Marathon