Cards BIN Lookup & Eligibility API
Amwal provides a secured, real-time BIN (Bank Identification Number) inspection endpoint (/check/bin_numbers_lookup/) for backend systems to evaluate customer payment card prefixes (first 6 to 8 digits) alongside the basket order amount.
This endpoint enables merchants to programmatically identify the issuing bank, card network/scheme, funding classification (credit vs. debit vs. prepaid), bank loyalty rewards programs, and real-time eligibility for Amwal 0% Bank Installments based on bank-specific order minimums.
PCI-DSS Compliance Required for Direct PAN / BIN Handling
Directly capturing customer card Primary Account Numbers (PAN) or extracting 6-to-8 digit BIN prefixes on your merchant application brings your servers and infrastructure into scope for PCI-DSS Compliance (such as PCI-DSS SAQ-D or Level 1 certification).
- Merchants Without PCI Certification: Do not attempt to collect or parse raw card numbers directly. Instead, use Amwal Embedded Checkout or Hosted Fields. Amwal securely captures card details inside isolated PCI-compliant iframes and evaluates bank installment eligibility automatically on the client device without exposing card data to your server.
- PCI-Certified Merchants & Server-to-Server Integrations: If your organization maintains PCI compliance, invoke this endpoint strictly from your secure backend (server-to-server). Never expose your confidential
Authorizationtoken orX-API-Keyin client-side / browser code or public repositories.
1. Real-Time BIN & Eligibility API Endpoint
Use this endpoint on your backend to determine whether a customer's card qualifies for 0% bank installments for their specific cart total.
Endpoint Details
| Attribute | Details |
|---|---|
| Method | GET |
| URL | https://backend.sa.amwal.tech/check/bin_numbers_lookup/?bin={bin}&amount={amount} |
| Authentication | Secured (Authorization + X-API-Key / X-Amwal-Key headers) |
| Response Content Type | application/json |
Request Headers
| Header | Required? | Description |
|---|---|---|
Authorization | Required | Your confidential Merchant Secret Key / Auth Token (e.g. 6a9f2323-fde2-43ce-ba33-7048d758d917). |
X-API-Key (or X-Amwal-Key) | Required | Your Amwal Merchant Public / API Key (e.g. sandbox-amwal-4117016a-b09c-41e2-93d8-2474c9287cef). |
Accept | Required | application/json |
Query Parameters
| Parameter | Type | Required? | Description |
|---|---|---|---|
bin | string | Yes | First 6 to 8 digits of the payment card number (e.g., 532446 or 411111). Must be between 6 and 8 numeric digits. |
amount | number / string | No (Optional) | Total cart or order amount in SAR (e.g., 500 or 1000.00). When provided, the API checks whether the order satisfies the issuing bank's minimum installment limit. When omitted, the API inspects card details and general eligibility without amount restriction. |
2. Bank Minimum Amount Rules
Saudi partner banks enforce strict minimum transaction thresholds before a cardholder is eligible to convert an order into 0% interest monthly installments.
Partner Bank Thresholds
| Bank Name | Bank Code | Test BIN Example | Minimum Basket (bank_amount_limit) | Supported Tenures | Rewards Program |
|---|---|---|---|---|---|
| The Saudi National Bank (SNB) | snb | 532446 | 1,000.00 SAR | 3, 6, 12 Months | LAK |
| Al Rajhi Banking & Investment Corp. | rajhi | 411111 / 545454 | 300.00 SAR | 3, 6, 12, 24 Months | Mokafaa |
How the API Evaluates Minimum Amounts
-
Eligible Card Meeting Bank Minimum: When an eligible credit card is submitted and
amount >= bank_amount_limit(e.g. SNB card withamount=1000):is_eligible: true- Returns full bank metadata, loyalty program details, and installment limit.
-
Eligible Card Below Bank Minimum: When an eligible credit card is submitted but
amount < bank_amount_limit(e.g. SNB card withamount=999):is_eligible: false- Returns the dynamic threshold notice:
"message": "Minimum amount for THE SAUDI NATIONAL BANK is 1000.00." - Recommended Merchant UX: Display an in-checkout notification encouraging the user to add items to meet the threshold: “Add 1.00 SAR more to qualify for 0% installments with SNB!”
-
Ineligible Card (Mada Debit / Prepaid / Foreign Card):
is_eligible: false"message": "Bin number not found."- Amwal automatically routes these cards to 1-Click Pay in Full.
3. Example cURL Requests
Example A: SNB Card Meeting Minimum (amount=1000)
curl --request GET \
--url "https://backend.sa.amwal.tech/check/bin_numbers_lookup/?bin=532446&amount=1000" \
--header "Authorization: 6a9f2323-fde2-43ce-ba33-7048d758d917" \
--header "X-API-Key: sandbox-amwal-4117016a-b09c-41e2-93d8-2474c9287cef" \
--header "Accept: application/json"Example B: SNB Card Below Bank Minimum (amount=999)
curl --request GET \
--url "https://backend.sa.amwal.tech/check/bin_numbers_lookup/?bin=532446&amount=999" \
--header "Authorization: 6a9f2323-fde2-43ce-ba33-7048d758d917" \
--header "X-API-Key: sandbox-amwal-4117016a-b09c-41e2-93d8-2474c9287cef" \
--header "Accept: application/json"Example C: Al Rajhi Bank Card (amount=500)
curl --request GET \
--url "https://backend.sa.amwal.tech/check/bin_numbers_lookup/?bin=411111&amount=500" \
--header "Authorization: 6a9f2323-fde2-43ce-ba33-7048d758d917" \
--header "X-API-Key: sandbox-amwal-4117016a-b09c-41e2-93d8-2474c9287cef" \
--header "Accept: application/json"Example D: Card Lookup Without Amount (General Eligibility)
curl --request GET \
--url "https://backend.sa.amwal.tech/check/bin_numbers_lookup/?bin=532446" \
--header "Authorization: 6a9f2323-fde2-43ce-ba33-7048d758d917" \
--header "X-API-Key: sandbox-amwal-4117016a-b09c-41e2-93d8-2474c9287cef" \
--header "Accept: application/json"Try it Live in the API Playground
Execute live requests and test custom BINs with or without amounts in the interactive API Playground.
4. API Response Schemas
200 OK — Eligible Credit Card Meeting Minimum
{
"id": 12840,
"bin": "532446",
"brand": "MASTERCARD",
"category": "WORLD",
"country": "Saudi Arabia",
"issuer": "THE SAUDI NATIONAL BANK",
"type": "CREDIT",
"program_name": "LAK",
"program_logo": "https://fra1.digitaloceanspaces.com/media-amwal/media/program_logo/Lak_va4LNQy.png",
"earn_rate": 0.0,
"rate_label": "points",
"is_override": false,
"bank_amount_limit": "1000.00",
"bank_name": "THE SAUDI NATIONAL BANK",
"bank_code": "snb",
"is_eligible": true
}200 OK — Eligible Card Below Bank Minimum Amount
Returned when the card is a participating bank credit card, but the cart amount is lower than bank_amount_limit:
{
"id": 12840,
"bin": "532446",
"brand": "MASTERCARD",
"category": "WORLD",
"country": "Saudi Arabia",
"issuer": "THE SAUDI NATIONAL BANK",
"type": "CREDIT",
"program_name": "LAK",
"program_logo": "https://fra1.digitaloceanspaces.com/media-amwal/media/program_logo/Lak_va4LNQy.png",
"earn_rate": 0.0,
"rate_label": "points",
"is_override": false,
"bank_amount_limit": "1000.00",
"bank_name": "THE SAUDI NATIONAL BANK",
"bank_code": "snb",
"is_eligible": false,
"message": "Minimum amount for THE SAUDI NATIONAL BANK is 1000.00."
}200 OK — Unrecognized / Ineligible BIN
Returned when the card prefix does not match any participating bank installment credit program (e.g. Mada debit cards or international cards):
{
"is_eligible": false,
"message": "Bin number not found."
}400 Bad Request — Validation Errors
Returned when the parameters are missing or formatted incorrectly:
// If 'bin' is fewer than 6 or greater than 8 digits:
{
"message": "bin must be 6 to 8 digits."
}
// If 'amount' is not a valid numeric value:
{
"message": "amount must be a valid number."
}401 Unauthorized — Missing Authentication
Returned if the Authorization header is omitted or invalid:
{
"detail": "Authentication credentials were not provided."
}5. Response Attributes Reference
| Field | Type | Description |
|---|---|---|
bin | string | The matched 6 or 8-digit Bank Identification Number. |
brand | string | Card network or scheme (VISA, MASTERCARD, MADA, AMEX). |
issuer / bank_name | string | Official legal name of the issuing bank or financial entity. |
bank_code | string | null | Normalized bank identifier code (e.g. snb, rajhi, ribl, inma). |
type | string | Card funding classification (CREDIT, DEBIT, PREPAID). |
category | string | Card product tier (e.g. WORLD, PLATINUM, CLASSIC, TEST). |
is_eligible | boolean | true if the card qualifies for 0% installments and meets the bank's minimum basket amount; false otherwise. |
bank_amount_limit | string | Minimum order amount required by the issuing bank for installments (e.g. 1000.00 SAR for SNB, 300.00 SAR for Al Rajhi). |
message | string | null | Clarification notice when is_eligible is false (e.g. "Minimum amount for THE SAUDI NATIONAL BANK is 1000.00." or "Bin number not found."). |
program_name | string | null | Associated bank loyalty rewards program (e.g. LAK, Mokafaa, Akthr). |
program_logo | string | null | URL to the bank rewards program logo badge. |
earn_rate | number | Multiplier for loyalty rewards earned per unit spent. |
6. End-to-End Decision Flow
7. Developer Code Snippets (Server-Side)
Server-Side Implementation
Ensure the following code runs exclusively on your secure application server so that your Authorization secret token is never exposed to customer browsers.
Node.js / TypeScript
import axios from 'axios';
export interface BinCheckResponse {
id?: number;
bin?: string;
brand?: string;
category?: string;
country?: string;
issuer?: string;
type?: 'CREDIT' | 'DEBIT' | 'PREPAID';
program_name?: string | null;
program_logo?: string | null;
bank_amount_limit?: string;
bank_name?: string;
bank_code?: string | null;
is_eligible: boolean;
message?: string;
}
export async function checkBinAndEligibility(binNumber: string, orderAmount: number) {
const bin = binNumber.replace(/\D/g, '').slice(0, 8);
try {
const { data } = await axios.get<BinCheckResponse>(
`https://backend.sa.amwal.tech/check/bin_numbers_lookup/`,
{
params: {
bin,
amount: orderAmount,
},
headers: {
'Authorization': process.env.AMWAL_SECRET_KEY, // e.g. 6a9f2323-fde2-43ce-ba33-7048d758d917
'X-API-Key': process.env.AMWAL_PUBLIC_KEY, // e.g. sandbox-amwal-4117016a-b09c-41e2-93d8-2474c9287cef
'Accept': 'application/json',
},
}
);
if (data.is_eligible) {
console.log(`✅ Qualified for 0% Installments via ${data.bank_name}`);
console.log(`Bank Minimum Limit: ${data.bank_amount_limit} SAR`);
return { status: 'ELIGIBLE', data };
}
if (data.message && data.message.includes('Minimum amount')) {
console.log(`⚠️ Card is eligible but order total is below minimum: ${data.message}`);
return { status: 'BELOW_MINIMUM', data };
}
console.log('⚡ Debit or non-participating card — fallback to 1-Click Pay in Full');
return { status: 'INELIGIBLE', data };
} catch (error) {
console.error('BIN Lookup API Error:', error);
return null;
}
}Python
import os
import requests
import re
def check_card_bin_and_amount(card_prefix: str, basket_amount: float):
bin_digits = re.sub(r'\D', '', card_prefix)[:8]
url = "https://backend.sa.amwal.tech/check/bin_numbers_lookup/"
headers = {
"Authorization": os.getenv("AMWAL_SECRET_KEY"), # 6a9f2323-fde2-43ce-ba33-7048d758d917
"X-API-Key": os.getenv("AMWAL_PUBLIC_KEY"), # sandbox-amwal-4117016a-b09c-41e2-93d8-2474c9287cef
"Accept": "application/json"
}
params = {
"bin": bin_digits,
"amount": basket_amount
}
response = requests.get(url, headers=headers, params=params)
if response.status_code == 200:
data = response.json()
if data.get("is_eligible"):
print(f"Eligible for 0% Installments: {data.get('bank_name')}")
elif "Minimum amount" in data.get("message", ""):
print(f"Below bank minimum: {data.get('message')}")
return data
else:
print(f"Lookup failed with status {response.status_code}: {response.text}")
return NonePHP
<?php
function check_amwal_bin_eligibility($card_number, $amount) {
$bin = substr(preg_replace('/\D/', '', $card_number), 0, 8);
$url = "https://backend.sa.amwal.tech/check/bin_numbers_lookup/?" . http_build_query([
'bin' => $bin,
'amount' => $amount
]);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: " . getenv("AMWAL_SECRET_KEY"),
"X-API-Key: " . getenv("AMWAL_PUBLIC_KEY"),
"Accept: application/json"
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status === 200) {
$result = json_decode($response, true);
return $result;
}
return null;
}
?>8. Related Resources
- Sandbox Test Cards — Full reference table of installment and pay-in-full sandbox test cards.
- Troubleshooting Card Eligibility — How to handle
CARD_TYPE_NOT_ELIGIBLEcheckout errors. - API Keys & Authentication — Retrieve and manage your Merchant Secret and API keys.
- Installment Marketing Widget — Present 0% installment messaging on product detail pages before checkout.
