Bin Discount is a feature on XPay that allows merchants to configure discounts based on card BINs (the first 6 or 8 digits of a card). Merchants can apply discounts for specific BINs using either a fixed value or a percentage of the order price.
The Bin Discount module supports multiple configurable options, including:
How It Works
You need to pass apply_bin_discount: true in the payment intent create API payload, the system could process the bin discount based on the configurations in the store.
If a merchant has configured bin discounts on the XPay portal, then when a user enters their card in the SDK:
onBinDiscount event will return discount details.binDiscount event will return discount details.Using these details, you need to apply the discount to the order.
If you want to use the BIN discount feature and enable pre-calculation, you must pass the piClientSecret while initializing the XPay SDK.
BIN discount and pre-calculation features are supported only in XPay SDK v4.1 versions.
const xpayy = new window.Xpay({
publishableKey: xpay?.publishableKey,
accountId: xpay?.accountId,
email: xpay?.email || null,
customerName: xpay?.customerName || null,
piClientSecret: xpay?.piClientSecret || null,
});
React
<xpay
xpay={{
publishableKey: storePK,
accountId: user_id,
customerName: customer?.name || null,
email: customer?.email || null,
piClientSecret: pi_client_secret,
}}
>
<PaymentElement
onBinDiscount={(data) => console.log("discount event data", data)}
/>
</xpay>;
In Vanilla JavaScript, you can listen for the binDiscount event using the xpay.on() method:
xpay.on('binDiscount', function (event) {
console.log(event, 'bin discount event');
// Apply the discount based on event data
});
In React.js, you can listen for the event using the onBinDiscount prop inside the <PaymentElement /> component:
<PaymentElement
onBinDiscount={(data)=> console.log("discount event data", data)}
/>
If you pass payment intent secret before SDK load and bin discount is applicable, you will get pre-calculated discount details in the event in the following format:
{
"bin": 512345,
"bank_name": "Bank ALafalah (MPGS)",
"account_id": "0ddb82950784f875",
"store_id": "65ccc486e9c7cd07445f6d28",
"bank_acronym": "BAFL",
"bank_logo": "<https://xstak-pay-admin.s3.us-east-2.amazonaws.com/assets/bank-logos/HBL.png>",
"discount_type": "percentage",
"discount_value": 10,
"discount_limit": 1,
"active_days": "monday,tuesday",
"max_daily_usage": 1,
"max_monthly_usage": 3,
"on_discounted_items": false,
"rule_enabled": true,
"id": "d0b80c34-7bc1-4f02-8f25-9fbbef6f4208",
"_id": "6a0318717eacae338fe7379b",
"createdAt": "2026-05-12T12:09:21.729Z",
"updatedAt": "2026-05-12T12:09:21.729Z",
"__v": 0,
"discount_applicable": true,
"discount_details": {
"discount_amount": 10,
"amount_after_discounted": 990,
"original_amount": 1000,
},
"hash": "42a56aa1413773ab1652a04e1e170adeec5b9e359900ba8ebeaa904a84aa8069"
}
When a bin discount is applied and payment intent secret is not passed before SDK load, the event will return a response in the following format:
{
"account_id": "0ddb82950784f875",
"bank_acronym": "HBL",
"bank_logo": "<https://js.xstak.com/assets/logos/HBL.png>",
"bank_name": "Habib Bank Limited",
"bin": 512345,
"createdAt": "2025-01-06T09:53:45.148Z",
"discount_type": "percentage",
"discount_value": 70,
"hash": "df49774ea1bcf4ff15ab18af6a989fc84e2e821b19700fb8bc9aa9577d57abe4",
"id": "d1dffc51-7b7c-4af0-b306-a8cf76c344d4",
"on_discounted_items": false,
"rule_enabled": true,
"store_id": "64f06b2fcabbf492b6d3a1e1",
"updatedAt": "2025-01-06T09:53:45.148Z",
"__v": 0,
"_id": "677ba829b48208d8392c7633"
}
When the order payment is captured, you will receive a webhook response containing the transaction details, including the unique hash for tracking discounts.
{
"type": "PAYMENT_INTENT_NOTIFICATION",
"payment_intent_id": "xpay_pi_1f4ebd77fe08624ee1216d4138d6f29227556a85473f2e7c128a622c2be56d2b",
"refund_id": null,
"amount": 9999,
"currency": "PKR",
"status": "succeeded",
"customer": {
"name": "Guest User",
"email": "[email protected]",
"phone": "03415682456"
},
"shipping": {
"address1": "Gulberg",
"city": "Lahore",
"country": "Pakistan",
"province": "Punjab",
"zip": "65191",
"shipping_method": "Standard"
},
"payment_method_types": "card",
"product": {},
"transaction_details": {
"_id": "6a045b5d088c8840474298c7",
"order": {
"customer": {
"name": "Guest User",
"email": "[email protected]",
"phone": "03415682456"
},
"name": "b2b-pl-02",
"type": "headless"
},
"status": "CAPTURED",
"secure": "3DS2",
"refunded_amount": 0,
"gateway": "bank-alfalah",
"response_from_bank": "The payment was completed successfully",
"status_message_from_bank": "PAYMENT_CAPTURED",
"activity": [
{
"status": "AUTHENTICATION_SUCCESSFUL",
"amount": 9999,
"timestamp": "2026-05-13T11:07:11.348Z",
"createdAt": "2026-05-13T11:07:13.300Z",
"token": "",
"card": {
"bin": "512345",
"last4digits": "2346",
"name": "Guest User",
"funding_method": "DEBIT",
"type": "MASTERCARD",
"issuer_details": {
"card_issuer": "Habib Bank Limited",
"card_network": "VISA",
"card_type": "DEBIT"
}
},
"3ds": { "authorization_code": "", "secure": "3DS2", "eci": "02" },
"processing": { "acquirer_transaction_id": "trans-MHdo1pHUgK" }
},
{
"status": "CAPTURED",
"amount": 9999,
"timestamp": "2026-05-13T11:07:12.478Z",
"createdAt": "2026-05-13T11:07:13.300Z",
"token": "",
"card": {
"hash": "42a56aa1413773ab1652a04e1e170adeec5b9e359900ba8ebeaa904a84aa8069",
"bin": "512345",
"last4digits": "2346",
"name": "Guest User",
"funding_method": "DEBIT",
"type": "MASTERCARD",
"issuer_details": {
"card_issuer": "Habib Bank Limited",
"card_network": "VISA",
"card_type": "DEBIT"
}
},
"3ds": {
"authorization_code": "134697",
"secure": "3DS2",
"eci": "02"
},
"processing": { "acquirer_transaction_id": "trans-XSVwnVKIG5" }
}
]
},
"metadata": { "order_reference": "b2b-pl-02" },
"store_id": "65ccc486e9c7cd07445f6d28",
"mode": "test",
"account_id": "0ddb82950784f875",
"discount_details": {
"bin": 51234567,
"binId": "6a0318717eacae338fe7379b",
"type": "percentage",
"limit": 1,
"value": 10,
"acronym": "BAFL",
"max_daily_usage": 1,
"max_monthly_usage": 3,
"minimum_order_value": null,
"active_days": null
}
}
If you have configured bin discounts, the event will return a unique hash corresponding to the user's card:
onBinDiscount eventbinDiscount eventWhen the order payment is captured, you will receive the same hash in the webhook data for the transaction captured status event.
If you want to allow only one discount per day for a card, follow these steps:
onBinDiscount in React, binDiscount in Vanilla JS) will return a unique hash for the card.This ensures that discounts are applied according to your business logic while preventing multiple discounts for the same card within a specified period.
Create Bin Discount Configuration
POST /bin/config/create/:store_id
Creates a new BIN discount configuration for a specific store
Request Payload
{
"bin": 437585,
"discount_type": "percentage",
"discount_value": 300,
"minimum_order_value": 1000,
"active_days": "monday,thursday,friday",
"max_daily_usage": 1,
"max_monthly_usage": 3,
"rule_enabled": true
}
| Field | Type | Required | Description |
|---|---|---|---|
bin |
Number | Yes | Card BIN number. Must be exactly 6 or 8 digits |
discount_type |
String | Yes | Type of discount. Allowed values: percentage, value |
discount_value |
Number | Yes | Discount amount/value to apply |
minimum_order_value |
Number | No | Minimum transaction amount required to apply discount |
active_days |
String | No | Comma-separated weekdays when discount is active |
max_daily_usage |
Number | No | Maximum number of discount usages allowed per day |
max_monthly_usage |
Number | No | Maximum number of discount usages allowed per month |
rule_enabled |
Boolean | No | Enables or disables the discount rule |
discount_limit |
Number | No | Maximum discount amount allowed |
rule_status |
String | No | Allowed values: TRUE, FALSE |
id |
String | No | Optional custom identifier |
Response
{
"success": true,
"responseStatus": "OK",
"message": "Request processed successfully.",
"data": {
"_id": "69ddec858da4120a0355d13c",
"bin": 51234567,
"bank_name": "Bank Alfalah Limited",
"account_id": "xxxb8295xxxxf875",
"store_id": "670cc16c5x5x5xe748916396",
"bank_acronym": "BAFL",
"bank_logo": "",
"discount_type": "percentage",
"discount_value": 10,
"discount_limit": 5,
"on_discounted_items": false,
"rule_enabled": true,
"id": "",
"createdAt": "2026-04-14T07:28:05.954Z",
"updatedAt": "2026-05-13T08:10:48.424Z",
"__v": 0,
"active_days": null,
"max_daily_usage": 1,
"max_monthly_usage": 3,
"minimum_order_value": null
}
}
Update Bin Discount Configuration
PUT /bin/config/create/:store_id
Updates a new BIN discount configuration for a specific store
Request Payload
{
"_id": "6a0318717eacae338fe7379b"
"bin": 437585,
"discount_type": "percentage",
"discount_value": 300,
"minimum_order_value": 1000,
"active_days": "monday,thursday,friday",
"max_daily_usage": 1,
"max_monthly_usage": 3,
"rule_enabled": true
}
Response
{
"success": true,
"responseStatus": "OK",
"message": "Request processed successfully.",
"data": {
"_id": "69ddec858da4120a0355d13c",
"bin": 51234567,
"bank_name": "Bank Alfalah Limited",
"account_id": "xxxb8295xxxxf875",
"store_id": "670cc16c5x5x5xe748916396",
"bank_acronym": "BAFL",
"bank_logo": "",
"discount_type": "percentage",
"discount_value": 10,
"discount_limit": 5,
"on_discounted_items": false,
"rule_enabled": true,
"id": "",
"createdAt": "2026-04-14T07:28:05.954Z",
"updatedAt": "2026-05-13T08:10:48.424Z",
"__v": 0,
"active_days": null,
"max_daily_usage": 1,
"max_monthly_usage": 3,
"minimum_order_value": null
}
}
Get Bin Discount Configuration Details
POST /bin/config
Request Payload
{
"bin": 123456 // 123456 or 12345678
}
Response
{
"success": true,
"responseStatus": "OK",
"message": "Request processed successfully.",
"data": {
"_id": "69ddec858da4120a0355d13c",
"bin": 51234567,
"bank_name": "Bank Alfalah Limited",
"account_id": "xxxb8295xxxxf875",
"store_id": "670cc16c5x5x5xe748916396",
"bank_acronym": "BAFL",
"bank_logo": "",
"discount_type": "percentage",
"discount_value": 10,
"discount_limit": 5,
"on_discounted_items": false,
"rule_enabled": true,
"id": "",
"createdAt": "2026-04-14T07:28:05.954Z",
"updatedAt": "2026-05-13T08:10:48.424Z",
"__v": 0,
"active_days": null,
"max_daily_usage": 1,
"max_monthly_usage": 3,
"minimum_order_value": null
}
}
Delete Bin Discount Configuration
DELETE /bin/config/:store_id/:id
The bin discount configuration against _id will be deleted from the store.