Amwal Tech logoDocs

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 Authorization token or X-API-Key in 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

AttributeDetails
MethodGET
URLhttps://backend.sa.amwal.tech/check/bin_numbers_lookup/?bin={bin}&amount={amount}
AuthenticationSecured (Authorization + X-API-Key / X-Amwal-Key headers)
Response Content Typeapplication/json

Request Headers

HeaderRequired?Description
AuthorizationRequiredYour confidential Merchant Secret Key / Auth Token (e.g. 6a9f2323-fde2-43ce-ba33-7048d758d917).
X-API-Key (or X-Amwal-Key)RequiredYour Amwal Merchant Public / API Key (e.g. sandbox-amwal-4117016a-b09c-41e2-93d8-2474c9287cef).
AcceptRequiredapplication/json

Query Parameters

ParameterTypeRequired?Description
binstringYesFirst 6 to 8 digits of the payment card number (e.g., 532446 or 411111). Must be between 6 and 8 numeric digits.
amountnumber / stringNo (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 NameBank CodeTest BIN ExampleMinimum Basket (bank_amount_limit)Supported TenuresRewards Program
The Saudi National Bank (SNB)snb5324461,000.00 SAR3, 6, 12 MonthsLAK
Al Rajhi Banking & Investment Corp.rajhi411111 / 545454300.00 SAR3, 6, 12, 24 MonthsMokafaa

How the API Evaluates Minimum Amounts

  1. Eligible Card Meeting Bank Minimum: When an eligible credit card is submitted and amount >= bank_amount_limit (e.g. SNB card with amount=1000):

    • is_eligible: true
    • Returns full bank metadata, loyalty program details, and installment limit.
  2. Eligible Card Below Bank Minimum: When an eligible credit card is submitted but amount < bank_amount_limit (e.g. SNB card with amount=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!”
  3. 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

FieldTypeDescription
binstringThe matched 6 or 8-digit Bank Identification Number.
brandstringCard network or scheme (VISA, MASTERCARD, MADA, AMEX).
issuer / bank_namestringOfficial legal name of the issuing bank or financial entity.
bank_codestring | nullNormalized bank identifier code (e.g. snb, rajhi, ribl, inma).
typestringCard funding classification (CREDIT, DEBIT, PREPAID).
categorystringCard product tier (e.g. WORLD, PLATINUM, CLASSIC, TEST).
is_eligiblebooleantrue if the card qualifies for 0% installments and meets the bank's minimum basket amount; false otherwise.
bank_amount_limitstringMinimum order amount required by the issuing bank for installments (e.g. 1000.00 SAR for SNB, 300.00 SAR for Al Rajhi).
messagestring | nullClarification notice when is_eligible is false (e.g. "Minimum amount for THE SAUDI NATIONAL BANK is 1000.00." or "Bin number not found.").
program_namestring | nullAssociated bank loyalty rewards program (e.g. LAK, Mokafaa, Akthr).
program_logostring | nullURL to the bank rewards program logo badge.
earn_ratenumberMultiplier for loyalty rewards earned per unit spent.

6. End-to-End Decision Flow

Rendering diagram...

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 None

PHP

<?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;
}
?>

On this page