diff --git a/api-references/payments/billpay/api-integration.json b/api-references/payments/billpay/api-integration.json
index c929b812..a609d44b 100644
--- a/api-references/payments/billpay/api-integration.json
+++ b/api-references/payments/billpay/api-integration.json
@@ -432,7 +432,7 @@
"value": {
"type": "string",
"description": "The value of the biller parameter to be sent as part of UPMS registration.",
- "example": "500.0"
+ "example": "500"
}
},
"description": "Optional. Only some billers require this. Details of the biller parameter to be sent as part of UPMS registration."
@@ -444,11 +444,13 @@
"properties": {
"amount": {
"type": "integer",
- "description": "The fixed or maximum amount set for auto-debit (value must be provided in paise)."
+ "description": "The fixed or maximum amount set for auto-debit (value must be provided in paise).",
+ "example": 10000
},
"currency": {
"type": "integer",
- "description": "The currency code. Use `356` for `INR`."
+ "description": "The currency code. Use `356` for `INR`.",
+ "example": 356
},
"debitDate": {
"type": "string",
@@ -477,7 +479,7 @@
"type": "string",
"description": "The UPMS registration is invalid after this date. Date format is YYYY-MM-DD",
"nullable": true,
- "example": "2025-01-01",
+ "example": "2027-01-01",
"x-omitempty": true
}
}
@@ -7127,7 +7129,7 @@
"value": {
"type": "string",
"description": "The value of the biller parameter to be sent as part of UPMS registration.",
- "example": "500.0"
+ "example": "500"
}
},
"description": "Optional. Only some billers require this. Details of the biller parameter to be sent as part of UPMS registration."
@@ -7139,11 +7141,13 @@
"properties": {
"amount": {
"type": "integer",
- "description": "The fixed or maximum amount set for auto-debit (value must be provided in paise)."
+ "description": "The fixed or maximum amount set for auto-debit (value must be provided in paise).",
+ "example": 10000
},
"currency": {
"type": "integer",
- "description": "The currency code. Use `356` for `INR`."
+ "description": "The currency code. Use `356` for `INR`.",
+ "example": 356
},
"debitDate": {
"type": "string",
@@ -7172,7 +7176,7 @@
"type": "string",
"description": "The UPMS registration is invalid after this date. Date format is YYYY-MM-DD",
"nullable": true,
- "example": "2025-01-01",
+ "example": "2027-01-01",
"x-omitempty": true
}
}
@@ -7734,7 +7738,7 @@
"type": "string",
"description": "The date until which the mandate is valid (YYYY-MM-DD). Must be a future date.",
"format": "date",
- "example": "2025-01-01"
+ "example": "2027-01-01"
}
},
"description": "Details of the mandate to be updated. Only include fields that need changing."
diff --git a/content/payments/billpay/api-integration/objects.mdx b/content/payments/billpay/api-integration/objects.mdx
index fb93e6de..56894e65 100644
--- a/content/payments/billpay/api-integration/objects.mdx
+++ b/content/payments/billpay/api-integration/objects.mdx
@@ -148,7 +148,6 @@ A standard structure for representing errors in API responses or callbacks.
| `code` | `string` | A short code identifying the error category (e.g., `validation-error`, `biller-registration-failed`). |
| `message` | `string` | A human-readable description of the error. |
-**Note:** In some asynchronous UPMS callbacks (e.g., for failed registration/update/cancel), the field names might appear as `Code` and `Message` (PascalCase) instead of `code` and `message`. Your callback handler should accommodate this potential difference.
## Payment Details
diff --git a/content/payments/billpay/api-integration/upms.mdx b/content/payments/billpay/api-integration/upms.mdx
index 7c6505db..abc88de8 100644
--- a/content/payments/billpay/api-integration/upms.mdx
+++ b/content/payments/billpay/api-integration/upms.mdx
@@ -84,7 +84,7 @@ UPMS supports two primary registration types:
- **VIEW_N_PAY**: Standard presentment; your app receives bill notifications, displays them, and the user manually initiates payment.
- **AUTO_PAY**: Auto-payment mandate already set up. When a bill is presented, your app initiates payment automatically using Setu's Payment APIs.
-### 2.4 Mandate (`mandate`)
+### 2.4 Mandate (mandate)
A JSON object provided when creating/updating a registration, containing:
@@ -132,81 +132,139 @@ This process leverages the existing **Bill Fetch API** endpoint (`POST /api/v2/b
**Request Structure:**
Note the added `mandate` block for UPMS registration.
-```diff
+
+
+
+
**Synchronous Responses:**
- **200 OK** (Accepted): Both bill fetch and UPMS registration initiated.
- ```json
- {
- "success": true,
- "data": {
- // Your reference ID for tracking this specific bill fetch operation
- "refId": "HENSVVR4QOS7X1UGPY7JGUV444P10102201",
- "upmsRegistration": {
- // Status of the registration request processing by our system
- "status": "PENDING",
- // The unique reference ID generated for this specific UPMS registration attempt.
- // Use this ID to correlate with the registration callback.
- "refId": "HENSVVR4QOS7X1UGPY7JGUV444P10102202"
- }
- },
- "traceId": "CV4PE82LTNJE9O014OE0"
- }
- ```
-- **200 OK** (Invalid mandate): Bill fetch initiated, no UPMS registration.
- ```json
- {
- "success": true,
- "data": {
- "refId": "HENSVVR4QOS7X1UGPY7JGUV444P10102201",
+
+
+
+
+
+- **200 OK** (Invalid mandate): Bill fetch initiated, no UPMS registration.
+
+
+
+
+
- **400 Bad Request** (Invalid Request): Neither bill fetch nor UPMS registration is initiated.
- ```json
- {
- "success": false,
- "error": {
- "code": "invalid-parameter",
- "message": "Missing required field"
- },
- "traceId": "CV4PE82LTNJE9O014OE1"
- }
- ```
-- **500 Internal Server Error**: An unexpected error occurred on the server. Neither bill fetch nor UPMS registration is initiated.
- ```json
- {
- "success": false,
- "error": {
- "code": "internal-error",
- "message": "Internal Error"
- },
- "traceId": "CV4PE82LTNJE9O014OE1"
- }
- ```
+
+
+
+
+
+- **500 Internal Server Error**: Neither bill fetch nor UPMS registration is initiated.
+
+
+
+
**Handling Asynchronous Callbacks for Creation:**
@@ -228,7 +286,14 @@ Two independent callbacks can be triggered following this API call:
- The `data` field will be present, and the `error` field will be absent.
- The `registration` object within `data` will contain the full details of the newly created registration.
- ```json
+
+
+
- **For failed registration attempts:**
- The `error` object will be present, containing:
- - `code` (string): The error code (Note: Field name might be `Code` as per example).
- - `message` (string): A description of the error (Note: Field name might be `Message` as per example).
+ - `code` (string): The error code
+ - `message` (string): A description of the error
- The `data` object will be absent.
- ```json
+
+
+
- **For duplicate registrations:**
- The `data` field will be present, and the `error` field will be absent.
@@ -306,7 +382,14 @@ Two independent callbacks can be triggered following this API call:
- `code`: Code indicating the duplicate situation (e.g., `duplicate-upms-registration`).
- `message`: Description of the duplicate situation.
- ```json
+
+
+
**Action:** Update your internal registration record based on the callback status and response details (`registration`, `error`, or `duplicate`).
@@ -347,85 +433,125 @@ This synchronous endpoint allows you to retrieve the current status and details
**Response Breakdown:**
- **On Success (Registration Found): HTTP 200 OK**
- ```json
- {
- "data": {
- "biller": {
- "id": "ABLP01000ANP03"
- },
- "createdAt": "2025-04-24T14:38:46.377Z",
- "customer": {
- "customerParams": [
- {
- "name": "Roll No",
- "value": "27257063"
- }
- ],
- "mobile": "9039403265",
- "name": "Priya Shukla"
- },
- "mandate": {
- "billPeriod": "ASPRESENTED",
- "billerParams": [
- {
- "name": "Low Balance Threshold",
- "value": "500"
- }
- ],
- "debitInfo": {
- "amount": 999999999,
- "currency": 356,
- "debitDate": "10-Feb",
- "paymentMode": "Internet Banking",
- "type": "FIXED_AMOUNT"
- },
- "registrationType": "AUTO_PAY",
- "toDate": "2025-12-22"
+
+
+
- **On Not Found: HTTP 404 Not Found**
- ```json
- {
- "success": false,
- "error": {
- "code": "registration-not-found",
- "message": "UPMS registration with the specified refId not found"
- },
- "traceId": "CV4PE82LTNJE9O014OE2"
- }
- ```
+
+
+
- **On Bad Request: HTTP 400 Bad Request** (e.g., invalid format for `upmsRegistrationRefID`).
- ```json
- {
- "success": false,
- "traceId": "C3SFG0O6N88R6UI7EQ",
- "error": {
- "code": "invalid-ref-id",
- "message": "Ref ID length must be 35 characters"
- }
+
+
+
- **On Server Error: HTTP 500 Internal Server Error**
- ```json
- {
- "success": false,
- "traceId": "C3SFG0O6N88R6UI7EQ",
- "error": {
- "code": "internal-error",
- "message": "Internal Error"
- }
+
+
+
**Action:** Update your internal registration record based on the API response.
@@ -458,65 +584,115 @@ This asynchronous endpoint allows modification of certain fields of an active UP
- `upmsRegistrationRefID` (string): The ID of the registration to update.
- **Body:** Include only the fields you want to modify within the `mandate` object.
- ```json
- // Example: Update expiry date and debit amount
- {
- "mandate": {
- "toDate": "2025-12-31",
- "debitInfo": {
- "amount": 750000 // 7500.00 INR
- }
+
+
+
**Synchronous Response (Acknowledgment):**
Confirms receipt and basic validation of the update request.
- **On Acceptance: HTTP 200 OK**
- ```json
- {
- "success": true,
- "traceId": "CV4PE82LTNJE9O014OE0"
- }
- ```
+
+
+
- **On Bad Request: HTTP 400 Bad Request** (Invalid field, invalid value, trying to update non-modifiable field).
- ```json
- {
- "success": false,
- "traceId": "C3SFG0O6N88R6UI7EQ",
- "error": {
- "code": "invalid-ref-id", // Example code, could vary
- "message": "Ref ID length must be 35 characters" // Example message
- }
+
+
+
- **On Not Found: HTTP 404 Not Found** (Registration doesn't exist or is not in an updatable state).
- ```json
- {
- "success": false,
- "error": {
- "code": "registration-not-found",
- "message": "UPMS registration with the specified refId not found"
- },
- "traceId": "CV4PE82LTNJE9O014OE2"
- }
- ```
+
+
+
- **On Server Error: HTTP 500 Internal Server Error**
- ```json
- {
- "success": false,
- "traceId": "C3SFG0O6N88R6UI7EQ",
- "error": {
- "code": "internal-error",
- "message": "Internal Error"
- }
+
+
+
**Handling the Asynchronous Callback for Update:**
@@ -534,7 +710,14 @@ You will receive an `UPDATE_UPMS_REGISTRATION` callback with the final outcome.
- The `data` object will be present and the `error` object will be absent.
- The `registration` object in `data` will contain the complete, updated details of the registration. Use this to refresh your stored data.
- ```json
+
+
+
- **If the update failed:**
- - The `error` object will contain the `code` and `message` explaining the failure (Note: Field names might be `Code`/`Message`).
+ - The `error` object will contain the `code` and `message` explaining the failure
- The `data` object will be absent.
- ```json
+
+
+
- > **Note:** The error object within failed *callback* payloads uses `Code` and `Message` (PascalCase) field names.
**Action:** Update your internal registration record based on the callback status and details.
@@ -630,60 +825,110 @@ This asynchronous endpoint permanently cancels an existing UPMS registration.
Confirms receipt of the cancellation request.
- **On Acceptance: HTTP 200 OK**
- ```json
- {
- "success": true,
- "traceId": "CV4PE82LTNJE9O014OE0"
- }
- ```
+
+
+
- **On Bad Request: HTTP 400 Bad Request** (e.g., invalid `upmsRegistrationRefID` format).
- ```json
- {
- "success": false,
- "traceId": "C3SFG0O6N88R6UI7EQ",
- "error": {
- "code": "invalid-ref-id",
- "message": "Ref ID length must be 35 characters"
- }
+
+
+
- **On Not Found: HTTP 404 Not Found** (Registration doesn't exist).
- ```json
- {
- "success": false,
- "error": {
- "code": "registration-not-found",
- "message": "UPMS registration with the specified refId not found"
- },
- "traceId": "CV4PE82LTNJE9O014OE2"
- }
- ```
+
+
+
- **On Conflict: HTTP 409 Conflict** (e.g., registration is already cancelled or in a state that cannot be cancelled).
- ```json
- {
- "success": false,
- "error": {
- "code": "invalid-state-transition",
- "message": "Registration is already cancelled or in a state that cannot be cancelled"
- },
- "traceId": "CV4PE82LTNJE9O014OE0"
- }
- ```
+
+
+
- **On Server Error: HTTP 500 Internal Server Error**
- ```json
- {
- "success": false,
- "traceId": "C3SFG0O6N88R6UI7EQ",
- "error": {
- "code": "internal-error",
- "message": "Internal Error"
- }
+
+
+
**Handling the Asynchronous Callback for Cancellation:**
@@ -701,7 +946,14 @@ You will receive a `CANCEL_UPMS_REGISTRATION` callback confirming the outcome.
- The `data` object will be present and the `error` object will be absent.
- The `registration` object in `data` will contain the details of the registration, now marked with `status: "CANCELLED"`.
- ```json
+
+
+
- **If the cancellation failed:**
- - The `error` object will contain the `code` and `message` explaining the failure (Note: Field names might be `Code`/`Message`).
+ - The `error` object will contain the `code` and `message` explaining the failure
- The `data` object will be absent.
- ```json
+
+
+
**Action:** Update the status of the registration in your system to `CANCELLED` upon successful confirmation via the callback.
@@ -770,7 +1033,15 @@ When a new bill is available for a registered customer, the flow is:
**Example `BILL_FETCH` Callback (for UPMS Presentment):**
Note the presence of `upmsRegistrationRefId` indicating this is for a registered subscription.
-```json
+
+
+
+
> **Note**: The same webhook endpoint receives notifications for both automatically presented bills (via UPMS) and bills retrieved through manual fetch requests (using separate Bill Fetch API). You can distinguish between these two scenarios by checking the `upmsRegistrationRefId` field within the callback's data object:
> - If `upmsRegistrationRefId` is present (not null), this callback represents an automatic bill presentment for a registered customer.
@@ -835,11 +1109,19 @@ If a bill is paid elsewhere after presentation, you'll receive a `SKIP_PAYMENT`
3. **Callback to You**: We send a `SKIP_PAYMENT` webhook to your configured endpoint.
4. **Your Processing**:
- Acknowledge with HTTP `200 OK`.
- - Parse `data.billRefId` and `data.dateOfPayment`.
+ - Parse `data.billRefId` and `data.dateOfPayment`. (Note: `data.billRefId` of skip payment callback is the same as `data.refId` of the bill fetch callback, i.e. the reference id of the presented bill(s))
- Locate and mark the bill as paid in your system.
**Example `SKIP_PAYMENT` Callback:**
-```json
+
+
+
+
### 6.2 Why Handle SKIP_PAYMENT Callbacks?
@@ -909,56 +1194,110 @@ This asynchronous API allows you to manually trigger a `BILL_FETCH` callback for
Confirms that the request to simulate the callback has been accepted.
- **On Acceptance: HTTP 200 OK**
- ```json
- {
- "success": true,
- "traceId": "CV4PE82LTNJE9O014OE0"
- }
- ```
+
+
+
+
- **On Bad Request: HTTP 400 Bad Request** (e.g., Invalid `upmsRegistrationRefID` format).
- ```json
- {
- "success": false,
- "error": {
- "code": "invalid-registration-ref-id",
- "message": "Invalid format for upmsRegistrationRefID"
- },
- "traceId": "CV4PE82LTNJE9O014OE1"
- }
- ```
+
+
+
+
- **On Forbidden: HTTP 403 Forbidden** - If attempted in the Production environment.
- ```json
- {
- "success": false,
- "error": {
- "code": "forbidden-operation",
- "message": "Simulation API not allowed in this environment"
- },
- "traceId": "CV4PE82LTNJE9O014OE2"
- }
- ```
+
+
+
+
- **On Not Found: HTTP 404 Not Found** - If the specified `upmsRegistrationRefID` does not exist or is not active.
- ```json
- {
- "success": false,
- "error": {
- "code": "registration-not-found",
- "message": "UPMS registration with the specified refId not found or inactive"
- },
- "traceId": "CV4PE82LTNJE9O014OE3"
- }
- ```
+
+
+
+
- **On Server Error: HTTP 500 Internal Server Error**.
- ```json
- {
- "success": false,
- "error": {
- "code": "internal-error",
- "message": "Internal Error"
- },
- "traceId": "CV4PE82LTNJE9O014OE2"
- }
- ```
+
+
+
**Handling the Asynchronous Callback Outcome:**
@@ -993,56 +1332,110 @@ This asynchronous API allows you to manually trigger a `SKIP_PAYMENT` callback f
Confirms that the request to simulate the skip payment callback has been accepted.
- **On Acceptance: HTTP 200 OK**
- ```json
- {
- "success": true,
- "traceId": "CV4PE82LTNJE9O014OE0"
- }
- ```
+
+
+
+
- **On Bad Request: HTTP 400 Bad Request** - e.g., Invalid `billRefId` format, or if the bill state is incompatible (e.g., already marked paid). May include specific codes like `invalid-bill`.
- ```json
- {
- "success": false,
- "error": {
- "code": "invalid-bill",
- "message": "Bill reference ID not found or inactive"
- },
- "traceId": "SIM4PE82LTNJE9O014OE0"
- }
- ```
+
+
+
+
- **On Forbidden: HTTP 403 Forbidden** - If attempted in the Production environment.
- ```json
- {
- "success": false,
- "error": {
- "code": "forbidden-operation",
- "message": "Simulation API not allowed in this environment"
- },
- "traceId": "CV4PE82LTNJE9O014OE2"
- }
- ```
+
+
+
+
- **On Not Found: HTTP 404 Not Found** - If the specified `billRefId` does not exist.
- ```json
- {
- "success": false,
- "error": {
- "code": "bill-not-found",
- "message": "Bill with the specified refId not found"
- },
- "traceId": "CV4PE82LTNJE9O014OE4"
- }
- ```
+
+
+
+
- **On Server Error: HTTP 500 Internal Server Error**.
- ```json
- {
- "success": false,
- "error": {
- "code": "internal-error",
- "message": "Internal Error"
- },
- "traceId": "CV4PE82LTNJE9O014OE2"
- }
- ```
+
+
+
**Handling the Asynchronous Callback Outcome:**
@@ -1060,7 +1453,7 @@ Shortly after receiving the 200 OK acknowledgment, your configured webhook liste
- Successful reception and processing of `SKIP_PAYMENT`.
- Handling potential errors if simulation is called with non-existent `upmsRegistrationRefId` or `billRefId`.
- **Correlation:** Pay attention to correlating the simulation API call with the resulting callback using `traceId` and the relevant reference IDs (`upmsRegistrationRefId`, `billRefId`).
-- **Idempotency:** While simulating, consider how your webhook handler deals with potentially receiving the same callback event more than once.
+- **Idempotency:** While simulating, ensure your webhook handler deals with potentially receiving the same callback event more than once.
This concludes the guide on integrating with Setu's UPMS APIs.
diff --git a/content/payments/billpay/api-integration/webhooks.mdx b/content/payments/billpay/api-integration/webhooks.mdx
index 6faf8663..46d83e91 100644
--- a/content/payments/billpay/api-integration/webhooks.mdx
+++ b/content/payments/billpay/api-integration/webhooks.mdx
@@ -21,7 +21,7 @@ Here is the general structure of any webhook—
2. `timeStamp` denotes the time when the webhook was triggered
3. `event` is a pre-defined list of event types used to define what the webhook was triggered for
4. `data` contains the webhook payload data on successful completion of the event.
-5. `error` contains details about the failure if the event could not be completed successfully. It typically includes `code` (or `Code`) and `message` (or `Message`) fields. One of `data` or `error` will be present.
+5. `error` contains details about the failure if the event could not be completed successfully. It typically includes `code` and `message` fields. One of `data` or `error` will be present.