diff --git a/api-references/payments/billpay/api-integration.json b/api-references/payments/billpay/api-integration.json index 3799f28d..bcdff417 100644 --- a/api-references/payments/billpay/api-integration.json +++ b/api-references/payments/billpay/api-integration.json @@ -7433,8 +7433,58 @@ "feeCode": { "type": "string", "example": "CCF1" + }, + "interchangeFeeDetailsV2": { + "type": "array", + "description": "Always returned alongside interchangeFeeDetails. Tiered interchange fee slabs by transaction amount range. Select the slab where the payment amount (in paise) falls between tranAmtRangeMin and tranAmtRangeMax (inclusive) and use that slab's flatFee and percentFee for CCF calculation. When the array has a single slab, it aligns with interchangeFeeDetails.", + "items": { + "required": [ + "effctvFrom", + "effctvTo", + "flatFee", + "percentFee", + "tranAmtRangeMax", + "tranAmtRangeMin" + ], + "type": "object", + "properties": { + "tranAmtRangeMax": { + "type": "integer", + "format": "int64" + }, + "tranAmtRangeMin": { + "type": "integer", + "format": "int64" + }, + "effctvFrom": { + "type": "string", + "example": "2024-01-01" + }, + "effctvTo": { + "type": "string", + "example": "2024-12-31" + }, + "flatFee": { + "type": "number", + "format": "decimal", + "example": 0.0 + }, + "percentFee": { + "type": "number", + "format": "decimal", + "example": 1.0 + } + } + } } - } + }, + "required": [ + "feeCode", + "feeDesc", + "feeDirection", + "interchangeFeeDetails", + "interchangeFeeDetailsV2" + ] } }, "pincode": { @@ -8072,8 +8122,58 @@ "feeCode": { "type": "string", "example": "CCF1" + }, + "interchangeFeeDetailsV2": { + "type": "array", + "description": "Always returned alongside interchangeFeeDetails. Tiered interchange fee slabs by transaction amount range. Select the slab where the payment amount (in paise) falls between tranAmtRangeMin and tranAmtRangeMax (inclusive) and use that slab's flatFee and percentFee for CCF calculation. When the array has a single slab, it aligns with interchangeFeeDetails.", + "items": { + "required": [ + "effctvFrom", + "effctvTo", + "flatFee", + "percentFee", + "tranAmtRangeMax", + "tranAmtRangeMin" + ], + "type": "object", + "properties": { + "tranAmtRangeMax": { + "type": "integer", + "format": "int64" + }, + "tranAmtRangeMin": { + "type": "integer", + "format": "int64" + }, + "effctvFrom": { + "type": "string", + "example": "2024-01-01" + }, + "effctvTo": { + "type": "string", + "example": "2024-12-31" + }, + "flatFee": { + "type": "number", + "format": "decimal", + "example": 0.0 + }, + "percentFee": { + "type": "number", + "format": "decimal", + "example": 1.0 + } + } + } } - } + }, + "required": [ + "feeCode", + "feeDesc", + "feeDirection", + "interchangeFeeDetails", + "interchangeFeeDetailsV2" + ] } }, "pincode": { @@ -9162,8 +9262,58 @@ "feeCode": { "type": "string", "example": "CCF1" + }, + "interchangeFeeDetailsV2": { + "type": "array", + "description": "Always returned alongside interchangeFeeDetails. Tiered interchange fee slabs by transaction amount range. Select the slab where the payment amount (in paise) falls between tranAmtRangeMin and tranAmtRangeMax (inclusive) and use that slab's flatFee and percentFee for CCF calculation. When the array has a single slab, it aligns with interchangeFeeDetails.", + "items": { + "required": [ + "effctvFrom", + "effctvTo", + "flatFee", + "percentFee", + "tranAmtRangeMax", + "tranAmtRangeMin" + ], + "type": "object", + "properties": { + "tranAmtRangeMax": { + "type": "integer", + "format": "int64" + }, + "tranAmtRangeMin": { + "type": "integer", + "format": "int64" + }, + "effctvFrom": { + "type": "string", + "example": "2024-01-01" + }, + "effctvTo": { + "type": "string", + "example": "2024-12-31" + }, + "flatFee": { + "type": "number", + "format": "decimal", + "example": 0.0 + }, + "percentFee": { + "type": "number", + "format": "decimal", + "example": 1.0 + } + } + } } - } + }, + "required": [ + "feeCode", + "feeDesc", + "feeDirection", + "interchangeFeeDetails", + "interchangeFeeDetailsV2" + ] } }, "pincode": { @@ -11649,8 +11799,58 @@ "feeCode": { "type": "string", "example": "CCF1" + }, + "interchangeFeeDetailsV2": { + "type": "array", + "description": "Always returned alongside interchangeFeeDetails. Tiered interchange fee slabs by transaction amount range. Select the slab where the payment amount (in paise) falls between tranAmtRangeMin and tranAmtRangeMax (inclusive) and use that slab's flatFee and percentFee for CCF calculation. When the array has a single slab, it aligns with interchangeFeeDetails.", + "items": { + "required": [ + "effctvFrom", + "effctvTo", + "flatFee", + "percentFee", + "tranAmtRangeMax", + "tranAmtRangeMin" + ], + "type": "object", + "properties": { + "tranAmtRangeMax": { + "type": "integer", + "format": "int64" + }, + "tranAmtRangeMin": { + "type": "integer", + "format": "int64" + }, + "effctvFrom": { + "type": "string", + "example": "2024-01-01" + }, + "effctvTo": { + "type": "string", + "example": "2024-12-31" + }, + "flatFee": { + "type": "number", + "format": "decimal", + "example": 0.0 + }, + "percentFee": { + "type": "number", + "format": "decimal", + "example": 1.0 + } + } + } } - } + }, + "required": [ + "feeCode", + "feeDesc", + "feeDirection", + "interchangeFeeDetails", + "interchangeFeeDetailsV2" + ] } }, "pincode": { diff --git a/api-references/payments/billpay_v1/api-integration.json b/api-references/payments/billpay_v1/api-integration.json index 158440fc..0b547040 100644 --- a/api-references/payments/billpay_v1/api-integration.json +++ b/api-references/payments/billpay_v1/api-integration.json @@ -3871,9 +3871,59 @@ "example": 0.0 } } + }, + "interchangeFeeDetailsV2": { + "type": "array", + "description": "Always returned alongside interchangeFeeDetails. Tiered interchange fee slabs by transaction amount range. Select the slab where the payment amount (in paise) falls between tranAmtRangeMin and tranAmtRangeMax (inclusive) and use that slab's flatFee and percentFee for CCF calculation. When the array has a single slab, it aligns with interchangeFeeDetails.", + "items": { + "required": [ + "effctvFrom", + "effctvTo", + "flatFee", + "percentFee", + "tranAmtRangeMax", + "tranAmtRangeMin" + ], + "type": "object", + "properties": { + "percentFee": { + "type": "number", + "format": "decimal", + "example": 1.0 + }, + "tranAmtRangeMax": { + "type": "integer", + "format": "int64" + }, + "tranAmtRangeMin": { + "type": "integer", + "format": "int64" + }, + "effctvFrom": { + "type": "string", + "example": "2024-01-01" + }, + "effctvTo": { + "type": "string", + "example": "2024-12-31" + }, + "flatFee": { + "type": "number", + "format": "decimal", + "example": 0.0 + } + } + } } } - } + }, + "required": [ + "feeCode", + "feeDesc", + "feeDirection", + "interchangeFeeDetails", + "interchangeFeeDetailsV2" + ] }, "selectionType": { "type": "string", @@ -4695,8 +4745,58 @@ "example": 0.0 } } + }, + "interchangeFeeDetailsV2": { + "type": "array", + "description": "Always returned alongside interchangeFeeDetails. Tiered interchange fee slabs by transaction amount range. Select the slab where the payment amount (in paise) falls between tranAmtRangeMin and tranAmtRangeMax (inclusive) and use that slab's flatFee and percentFee for CCF calculation. When the array has a single slab, it aligns with interchangeFeeDetails.", + "items": { + "required": [ + "effctvFrom", + "effctvTo", + "flatFee", + "percentFee", + "tranAmtRangeMax", + "tranAmtRangeMin" + ], + "type": "object", + "properties": { + "percentFee": { + "type": "number", + "format": "decimal", + "example": 1.0 + }, + "tranAmtRangeMax": { + "type": "integer", + "format": "int64" + }, + "tranAmtRangeMin": { + "type": "integer", + "format": "int64" + }, + "effctvFrom": { + "type": "string", + "example": "2024-01-01" + }, + "effctvTo": { + "type": "string", + "example": "2024-12-31" + }, + "flatFee": { + "type": "number", + "format": "decimal", + "example": 0.0 + } + } + } } - } + }, + "required": [ + "feeCode", + "feeDesc", + "feeDirection", + "interchangeFeeDetails", + "interchangeFeeDetailsV2" + ] } }, "selectionType": { @@ -5699,7 +5799,58 @@ } } } + , + "interchangeFeeDetailsV2": { + "type": "array", + "description": "Always returned alongside interchangeFeeDetails. Tiered interchange fee slabs by transaction amount range. Select the slab where the payment amount (in paise) falls between tranAmtRangeMin and tranAmtRangeMax (inclusive) and use that slab's flatFee and percentFee for CCF calculation. When the array has a single slab, it aligns with interchangeFeeDetails.", + "items": { + "required": [ + "effctvFrom", + "effctvTo", + "flatFee", + "percentFee", + "tranAmtRangeMax", + "tranAmtRangeMin" + ], + "type": "object", + "properties": { + "percentFee": { + "type": "number", + "format": "decimal", + "example": 1.0 + }, + "tranAmtRangeMax": { + "type": "integer", + "format": "int64" + }, + "tranAmtRangeMin": { + "type": "integer", + "format": "int64" + }, + "effctvFrom": { + "type": "string", + "example": "2024-01-01" + }, + "effctvTo": { + "type": "string", + "example": "2024-12-31" + }, + "flatFee": { + "type": "number", + "format": "decimal", + "example": 0.0 + } + } + } } + }, + "required": [ + "feeCode", + "feeDesc", + "feeDirection", + "interchangeFeeDetails", + "interchangeFeeDetailsV2" + ] } }, "selectionType": { @@ -6242,7 +6393,58 @@ } } } + , + "interchangeFeeDetailsV2": { + "type": "array", + "description": "Always returned alongside interchangeFeeDetails. Tiered interchange fee slabs by transaction amount range. Select the slab where the payment amount (in paise) falls between tranAmtRangeMin and tranAmtRangeMax (inclusive) and use that slab's flatFee and percentFee for CCF calculation. When the array has a single slab, it aligns with interchangeFeeDetails.", + "items": { + "required": [ + "effctvFrom", + "effctvTo", + "flatFee", + "percentFee", + "tranAmtRangeMax", + "tranAmtRangeMin" + ], + "type": "object", + "properties": { + "percentFee": { + "type": "number", + "format": "decimal", + "example": 1.0 + }, + "tranAmtRangeMax": { + "type": "integer", + "format": "int64" + }, + "tranAmtRangeMin": { + "type": "integer", + "format": "int64" + }, + "effctvFrom": { + "type": "string", + "example": "2024-01-01" + }, + "effctvTo": { + "type": "string", + "example": "2024-12-31" + }, + "flatFee": { + "type": "number", + "format": "decimal", + "example": 0.0 + } + } + } } + }, + "required": [ + "feeCode", + "feeDesc", + "feeDirection", + "interchangeFeeDetails", + "interchangeFeeDetailsV2" + ] } }, "selectionType": { diff --git a/content/payments/billpay/api-integration/paying-bills/customer-convenience-fee.mdx b/content/payments/billpay/api-integration/paying-bills/customer-convenience-fee.mdx index 2eb26fd6..33007bd0 100644 --- a/content/payments/billpay/api-integration/paying-bills/customer-convenience-fee.mdx +++ b/content/payments/billpay/api-integration/paying-bills/customer-convenience-fee.mdx @@ -11,7 +11,11 @@ visible_in_sidebar: true Customer Convenience Fee (CCF) is an additional charge some billers impose on top of the bill amount—essentially a fee your users pay for the convenience of digital bill payment through BBPS. -You'll discover CCF when calling the List Billers API, where it appears in the biller's metadata. Here's what CCF looks like in biller responses: +You'll discover CCF when calling the List Billers API, where it appears in the biller's metadata. Every fee entry includes both **`interchangeFeeDetails`** (a single object) and **`interchangeFeeDetailsV2`** (an array of objects with the same fields per element). + +For CCF calculation, use **`interchangeFeeDetailsV2`**: find the slab where the bill amount in paise falls between **`tranAmtRangeMin`** and **`tranAmtRangeMax`** (inclusive), then use that slab's `flatFee` and `percentFee`. Legacy **`interchangeFeeDetails`** should be replaced with **`interchangeFeeDetailsV2`** for multi slab support. + +Here's what CCF looks like when a single flat fee applies across all amounts: {` { @@ -29,7 +33,53 @@ You'll discover CCF when calling the + +When **tiered** CCF applies, `interchangeFeeDetailsV2` contains multiple ranges—example (values illustrative): + +{` +{ + "feeCode": "CCF1", + "feeDesc": "Customer_Convenience_Fee", + "feeDirection": "C2B", + "interchangeFeeDetails": { + "effctvFrom": "2025-11-07", + "effctvTo": "", + "flatFee": 590, + "percentFee": 0, + "tranAmtRangeMax": 200000, + "tranAmtRangeMin": 1 + }, + "interchangeFeeDetailsV2": [ + { + "effctvFrom": "2025-11-07", + "effctvTo": "", + "flatFee": 590, + "percentFee": 0, + "tranAmtRangeMax": 200000, + "tranAmtRangeMin": 1 + }, + { + "effctvFrom": "2025-11-07", + "effctvTo": "", + "flatFee": 1180, + "percentFee": 0, + "tranAmtRangeMax": 500000, + "tranAmtRangeMin": 200001 } ] } @@ -55,7 +105,15 @@ Before diving into complex calculations, understand that most billers on the BBP "percentFee": 0, // No percentage fee "tranAmtRangeMax": 9999999999, "tranAmtRangeMin": 1 - } + }, + "interchangeFeeDetailsV2": [ + { + "flatFee": 0, + "percentFee": 0, + "tranAmtRangeMax": 9999999999, + "tranAmtRangeMin": 1 + } + ] } `} @@ -83,7 +141,17 @@ Note: The values are for illustration purposes only. "percentFee": 0, // No percentage component "tranAmtRangeMax": 999999999999, "tranAmtRangeMin": 1 - } + }, + "interchangeFeeDetailsV2": [ + { + "effctvFrom": "2024-08-05", + "effctvTo": "", + "flatFee": 50, + "percentFee": 0, + "tranAmtRangeMax": 999999999999, + "tranAmtRangeMin": 1 + } + ] } ] } @@ -106,7 +174,17 @@ Note: The values are for illustration purposes only. "percentFee": 0, // No percentage component "tranAmtRangeMax": 999999999999, "tranAmtRangeMin": 1 - } + }, + "interchangeFeeDetailsV2": [ + { + "effctvFrom": "2023-07-28", + "effctvTo": "", + "flatFee": 100, + "percentFee": 0, + "tranAmtRangeMax": 999999999999, + "tranAmtRangeMin": 1 + } + ] } ] } @@ -129,7 +207,17 @@ Note: The values are for illustration purposes only. "percentFee": 0, // No percentage component "tranAmtRangeMax": 9999999999, "tranAmtRangeMin": 1 - } + }, + "interchangeFeeDetailsV2": [ + { + "effctvFrom": "2024-01-01", + "effctvTo": "", + "flatFee": 0, + "percentFee": 0, + "tranAmtRangeMax": 9999999999, + "tranAmtRangeMin": 1 + } + ] } ] } @@ -139,12 +227,14 @@ Note: The values are for illustration purposes only. ### 5.1 Detection Logic -Look for `CCF1` + `C2B` entries in the `interchangeFee` array. Zero CCF has two forms, **check for both**: +Look for `CCF1` + `C2B` entries in the `interchangeFee` array. For the matching entry, **`interchangeFeeDetailsV2`** is present: find the object whose range contains the bill amount in paise (`tranAmtRangeMin ≤ billAmount ≤ tranAmtRangeMax`) and use that slab's `flatFee` and `percentFee` for CCF (not the legacy `interchangeFeeDetails` object alone). + +Zero CCF has two forms, **check for both**: 1. **Missing** - No `CCF1`/`C2B` entry at all → Zero CCF -2. **Present but inactive** - Entry exists with `flatFee: 0` AND `percentFee: 0` → Zero CCF +2. **Present but inactive** - After resolving the slab as above, `flatFee: 0` AND `percentFee: 0` → Zero CCF -If either is true, you may omit `custConvFee` from your payment request. If a `CCF1`/`C2B` entry exists with any non-zero fee, calculate the CCF using the formula in section 5.2. +If either is true, you may omit `custConvFee` from your payment request. If a `CCF1`/`C2B` entry exists with any non-zero fee for the resolved slab, calculate the CCF using the formula in section 5.2. ### 5.2 CCF Calculation Formula @@ -174,6 +264,13 @@ When CCF applies, use this formula to calculate the fee in paise: - Calculation: CCF = 0 - Total debit: ₹1500 (omit custConvFee field) +**Example 4: Tiered CCF (`interchangeFeeDetailsV2`)** +- Bill amount: ₹2500 (250000 paise) +- From `interchangeFeeDetailsV2`, the slab where `tranAmtRangeMin` ≤ 250000 ≤ `tranAmtRangeMax` applies (for example 200001–500000 paise when that tier exists) +- CCF base: flatFee = 1180, percentFee = 0 +- Calculation: `(1180 + (250000 × 0/100)) × (1 + 18/100) = 1392.4` → **1392** paise after rounding (₹13.92) +- Total debit: 250000 + 1392 = 251392 paise + ## 6. Building Your Payment Request ### 6.1 Payment Request with CCF @@ -234,7 +331,7 @@ When using payment options (alternative amounts), calculate CCF on the final sel ## 8. Complete Implementation Checklist -- **Detect CCF**: Look for `CCF1` entries with `C2B` direction in biller metadata +- **Detect CCF**: Look for `CCF1` entries with `C2B` direction in biller metadata; resolve CCF from `interchangeFeeDetailsV2` slabs - **Calculate properly**: Use the complete formula including 18% GST - **Handle zero CCF**: Omit `custConvFee` field when CCF is zero - **Separate from bill amount**: Never add CCF to `paymentDetails.amount`