Collect.js Card Type Detection

Overview

Collect.js includes automatic card type detection using BIN (Bank Identification Number) lookup. This feature identifies whether a card is a credit card, debit card, or another card type.

There are two ways to utilize this feature:

  1. Real-Time Lookup (Recommended): Detect the card type immediately after the user types a valid card number to update the UI instantly.
  2. Tokenization Callback: Verify the card type within the final payment token response to ensure data integrity upon submission.

This information enables developers to implement intelligent surcharging systems that only apply surcharges to credit cards, helping ensure compliance with industry regulations and local requirements.

🚧

This feature is currently rolling out to all accounts. Please contact your account manager if you would like access immediately.

How It Works

1. Real-Time Detection (lookUpCallback)

As the user types their card number, Collect.js monitors the input. Once the number is deemed valid, the lookUpCallback fires immediately. This allows you to display surcharge warnings or update the total price before the customer submits the form.

2. Final Verification (callback)

When the form is submitted, the standard callback response includes a category field. This serves as the final system of record to confirm the card type associated with the generated token.

Response Formats

Real-Time Lookup Response

Received via lookUpCallback when the card number is valid:

{
    "number": "411111******1111",
    "bin": "411111",
    "exp": null
    "type": "visa",
    "category": "credit", // varies based on card
    "hash": ""
}
📘

The exp value is typically null in this callback since it happens before the customer fills out their expiation date. If the expiration date is available, the callback will include a value here formatted MMYY.

Tokenization Response

Received via callback after form submission:

{
  "tokenType": "inline",
  "token": "SW8eBa72-jkaqt9-xyuEX2-DC8qceRbe6z6",
  ...
  "card": {
    "number": "411111******1111",
    "bin": "411111",
    "exp": "1030",
    "type": "visa",
    "category": "credit",
    "hash": ""
  }
	...
}

Category Values

  • credit
  • debit
  • prepaid
  • deferred_debit
  • charge
  • unknown

Implementation Guide

Step 1: Configure Callbacks

Update your CollectJS.configure method to include the lookUpCallback. This is where you will handle the immediate UI updates. You must also retain the standard callback to handle the final submission.

CollectJS.configure({
  fields: {
    cardNumber: {
      selector: "#card-number",
      title: "Card Number"
    },
    cardExpiration: {
      selector: "#card-expiration",
      title: "Card Expiration"
    },
    cvv: {
      selector: "#cvv",
      title: "CVV"
    }
  },
  // 1. PRIMARY: Fires as soon as the card number is valid
  lookUpCallback: function(response) {
     if (response.category) {
         updateSurchargeUI(response.category);
     }
  },

  // 2. FALLBACK: Fires after the user clicks submit
  callback: function(response) {
    if (response.token) {
      // Verify the category one last time before sending to your server
      const finalCategory = response.card.category;
      const token = response.token;

      submitPayment(token, finalCategory);
    }
  }
});

Step 2: Implement Real-Time Surcharge Logic

Create a function to handle the UI updates triggered by the lookUpCallback. This ensures the user sees the cost implication immediately.

const baseAmount = 100.00; 

function updateSurchargeUI(category) {
  let finalAmount = baseAmount;
  let surchargeAmount = 0;

  // Only apply surcharge to credit cards
  if (category === "credit") {
    const surchargeRate = 0.03; // 3% surcharge rate (example)
    surchargeAmount = baseAmount * surchargeRate;
    finalAmount = baseAmount + surchargeAmount;
    
    // Show the surcharge notice
    document.getElementById("surcharge-notice").textContent = 
      `Credit card surcharge: $${surchargeAmount.toFixed(2)}`;
    document.getElementById("surcharge-notice").style.display = "block";
  } else {
    // Hide notice for debit, prepaid, or unknown
    document.getElementById("surcharge-notice").style.display = "none";
  }

  // Update the total displayed to the user
  document.getElementById("total-amount").textContent = 
    `Total: $${finalAmount.toFixed(2)}`;
}

Step 3: Final Submission & Fallback

When the user submits the form, use the standard callback to confirm the calculation one last time. This handles edge cases where a user might have changed the card number rapidly before hitting enter.

function submitPayment(token, cardCategory) {
  let finalAmount = baseAmount;
  let surchargeApplied = false;

  // Re-verify logic before sending to backend
  if (cardCategory === "credit") {
    const surchargeRate = 0.03; 
    finalAmount = baseAmount + (baseAmount * surchargeRate);
    surchargeApplied = true;
  }

  // Send the token and the calculated amount to your backend
  // Your backend should perform a final math check as well
  processTransaction(token, finalAmount, surchargeApplied);
}

Important Considerations

  1. Callback Timing: The lookUpCallback only fires when the card number is deemed valid. If a user types a partial or invalid number, this event will not trigger.
  2. Fallback Necessity: While lookUpCallback provides the best UX, never rely on it exclusively for the final transaction amount. Always use the category returned in the final callback (the token response) to ensure the charged amount matches the actual card type tokenized.
  3. Compliance Responsibility: Merchants remain responsible for ensuring compliance with all applicable regulations, including local surcharging laws and card network rules.
  4. Surcharge Calculations: This feature provides card type identification only. Integrators must implement their own surcharge calculation logic based on their business rules.