#Part 1: Understanding UPMS
This section introduces the core concepts of UPMS, its benefits, and the terminology you'll encounter while integrating.
#1. Introduction to UPMS
#1.1 What is UPMS?
UPMS, or Unified Presentment Management Service, is a feature within the Bharat Bill Payment System (BBPS) designed to simplify how recurring bills are presented to customers.
Think of it as a subscription service for bills. Instead of end-users manually fetching their bill details (like amount and due date) each cycle for various billers (electricity, phone, loan EMIs, etc.), UPMS allows them to register once through your app.
Once a customer is registered for UPMS with a specific biller:
- The biller automatically pushes the bill details into the BBPS network when a new bill is generated.
- BBPS makes this information available to us.
- We then notify your app about the new bill via a webhook (callback).
This enables a seamless, automated bill presentment experience right within your app.
#1.2 Why Integrate with UPMS?
Integrating with UPMS offers significant advantages for both your app and your end-users:
- Improved End-User Experience: Registered users see their bills automatically in your app, removing the need for them or you to fetch bills each cycle. This shifts bill management from a manual "pull" to an automated "push" model.
- Timely Bill Awareness & Centralized View: Proactive notifications about new bills and due dates help users avoid missed payments and late fees. Users can manage subscribed bills from different billers in one place—your app.
- Increased Engagement: Simplified bill discovery encourages users to pay digitally via your app, boosting engagement.
#1.3 How UPMS Works
A simplified UPMS flow when using our APIs:
- User Action: An end-user on your app requests to register for automatic bill presentment for a specific biller (e.g., electricity provider).
- API Call (You → Us): Your app calls our Fetch Bill and Create Registration API with customer and mandate details.
- BBPS Interaction (Us → BBPS → Biller): We interact securely with BBPS central unit and the biller's system to validate and record the registration.
- Acknowledgement (Us → You): Our API returns a synchronous response (typically
PENDING
). - Asynchronous Confirmation (Us → You): Final registration status (
SUCCESS
orFAILED
) is communicated later via webhook. - Bill Push (Biller → BBPS → Us): On a new bill cycle, the biller pushes bill details to BBPS.
- Bill Notification (Us → You): We send a callback to your configured endpoint with the bill details.
- Presentment (Your App): Your app parses the callback, identifies the user, and displays the bill.
- Payment (Optional): The user can then initiate payment for the presented bill.
#1.4 Who is this Guide For?
This guide is intended for BBPS Agent Institutions integrating Setu's APIs to offer seamless recurring BBPS bill payment services, specifically leveraging UPMS features. It is valuable for individuals or teams seeking to understand the UPMS integration process.
#1.5 What this Guide Covers
This document provides comprehensive information on:
- Core UPMS concepts and terminology.
- Prerequisites and setup for integrating with Setu's UPMS APIs.
- Detailed explanations of each UPMS API endpoint.
- Handling webhook callbacks for managing registrations and bills.
- Error handling, testing procedures, and best practices.
#2. Key UPMS Concepts & Terminology
#2.1 UPMS Registration
A UPMS registration represents an end-customer's mandate with a UPMS enabled biller for automatic bill presentment via your app. A successful registration authorizes the biller (with customer consent) to push bill details for that customer through BBPS to us, and subsequently, to you via callbacks.
UPMS is only available for billers who have the upmsEnabled
flag set to true
. You can check this flag using the List billers API, which also allows filtering by this flag. Trying to create a UPMS registration for billers without upmsEnabled
set to true
will fail.
#2.2 Registration Lifecycle
A UPMS registration progresses through various states:
- PENDING: Initial state after a registration request is accepted but before the registration is confirmed.
- SUCCESS: Registration is active; bills will be presented via callbacks.
- FAILED: Registration could not be completed (e.g., invalid details).
- CANCELLED: Registration permanently cancelled by user or system.
- DEACTIVATED: Registration has been deactivated.
#2.3 Registration Types
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)
A JSON object provided when creating/updating a registration, containing:
registrationType
:VIEW_N_PAY
orAUTO_PAY
.billPeriod
: Frequency of expected bills (mandatory for some billers; optional for others).toDate
: Expiry date of the registration.debitInfo
(forAUTO_PAY
):debitType
(string): Specifies the debit rule. Can beFIXED_AMOUNT
(pay the exact bill amount) orMAX_AMOUNT
(pay up to this limit).amount
(number): The fixed or maximum amount set for auto-debit (value must be provided in paise).currency
(number): The currency code. Use356
forINR
.paymentMode
(string): The payment method intended for auto-debit, likeInternet Banking
orUPI
.debitDate
(string): The preferred date format (DD-MMM
, e.g.,10-Feb
) for attempting the auto-debit each cycle.
#2.5 Asynchronous Operations & Callbacks
All UPMS operations (create, update, cancel) are asynchronous:
- Synchronous Response: Immediate HTTP acknowledgment (
200 OK
) indicatingPENDING
status. - Asynchronous Outcome: Final status sent via webhook callback to your server.
Additionally, you'll receive a callback for each bill generated for the registered user.
Ensure you implement a reliable webhook listener to receive and process these callbacks.
#Part 2: Managing Customer Registrations
#Prerequisite: Configure Your Registration Callback URL
You must set up and provide us with a secure HTTPS webhook endpoint URL. This endpoint is crucial as it's where our system will send asynchronous notifications (via HTTP POST) regarding:
- UPMS Registration Status: Updates for creation, modification, and cancellation (
CREATE_UPMS_REGISTRATION
,UPDATE_UPMS_REGISTRATION
,CANCEL_UPMS_REGISTRATION
events).
#3. UPMS Registration Management APIs
#3.1 Creating a Registration (Combined with Bill Fetch)
This process leverages the existing Bill Fetch API endpoint. To initiate a UPMS registration alongside fetching the current bill (if available), you simply include the mandate
object in the standard Bill Fetch request.
Endpoint: POST /api/v2/bbps/bills/fetch/request
(See API Reference)
Type: Asynchronous
Purpose: To fetch the current bill and, by adding mandate
, simultaneously initiate customer registration for future automatic bill presentments (UPMS).
Request Structure:
Note the added mandate
block for UPMS registration.
Sample Request
{"agent": { /* ... agent details ... */ },"biller": { /* ... biller details ... */ },"customer": { /* ... customer identifiers ... */ },+ "mandate": { /* UPMS specific: details about the mandate as described in section 2.4 */+ "registrationType": "VIEW_N_PAY" | "AUTO_PAY",+ "billPeriod": "MONTHLY" | "ASPRESENTED" | ...,+ "toDate": "YYYY-MM-DD",+ "debitInfo": { /* required for AUTO_PAY */ }+ }}
Synchronous Responses:
- 200 OK (Accepted): Both bill fetch and UPMS registration initiated.
Sample Response
{"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.
Sample Response
{"success": true,"data": {"refId": "HENSVVR4QOS7X1UGPY7JGUV444P10102201",// Status of the registration request processing by our system"upmsRegistration": {// No UPMS Registration will be initiated"status": "FAILED",// The error details"error": {"code": "invalid-debit-info","message": "Invalid amount in debit info"}}},"traceId": "CV4PE82LTNJE9O014OE0"}
- 400 Bad Request (Invalid Request): Neither bill fetch nor UPMS registration is initiated.
Sample Response
{"success": false,"error": {"code": "invalid-parameter","message": "Missing required field"},"traceId": "CV4PE82LTNJE9O014OE1"}
- 500 Internal Server Error: Neither bill fetch nor UPMS registration is initiated.
Sample Response
{"success": false,"error": {"code": "internal-error","message": "Internal Error"},"traceId": "CV4PE82LTNJE9O014OE1"}
Handling Asynchronous Callbacks for Creation:
Two independent callbacks can be triggered following this API call:
Bill Fetch Callback (If Bill Found): If a current bill exists for the customer, you will receive a
BILL_FETCH
callback containing the bill details. Handle this as described in Part 3. This callback is independent of the registration success/failure.Registration Status Callback: For registrations with initial status as
PENDING
, you will receive aCREATE_UPMS_REGISTRATION
callback to inform you of the final outcome of the registration attempt identified byupmsRegistration.refId
from the synchronous response.
CREATE_UPMS_REGISTRATION
Callback: (See Webhook Reference)
Event Type:
event: "CREATE_UPMS_REGISTRATION"
Timestamp:
timeStamp
(ISO 8601 format)Correlation:
refId
(Matches theupmsRegistration.refId
from the sync response, e.g.,HENSVVR4QOS7X1UGPY7JGUV444P10102202
)Trace ID:
traceId
(For logging/debugging)Outcome: Check the
data
,duplicate
, anderror
fields within the callback payload:For successful registrations:
- The
data
field will be present, and theerror
field will be absent. - The
registration
object withindata
will contain the full details of the newly created registration.
Sample Callback Payload
// Example SUCCESS Callback Payload{"event": "CREATE_UPMS_REGISTRATION","traceId": "D07LJTJ71N0PUBJKS640","timeStamp": "2025-04-28T16:05:34.762+05:30","data": {"registration": {"refId": "D07LJTB71N0PGH5KG32G6dH2QjK51181605", // Unique reference ID for this registration"status": "SUCCESS", // Final status of the registration"biller": { // Same as the biller object in the request"id": "ABLP01000ANP03"},"customer": { // Same as the customer object in the request, except for the name field"customerParams": [{"name": "Roll No","value": "14989991"}],"mobile": "7378926241","name": "Anjali Desai" // NEW: Optional, only present if the biller shares the customer name},"mandate": { // Same as the mandate object in the request"billPeriod": "ASPRESENTED","billerParams": [{"name": "Low Balance Threshold","value": "500"}],"debitInfo": {"amount": 999999999,"currency": 356,"debitDate": "10-Feb","paymentMode": "Debit Card","type": "FIXED_AMOUNT"},"registrationType": "AUTO_PAY","toDate": "2025-12-22"},"createdAt": "2025-04-28T10:35:33Z", // Timestamp of the registration creation"updatedAt": "2025-04-28T10:35:34Z" // Timestamp of the last registration modification}},"refId": "D07LJTB71N0PGH5KG32G6dH2QjK51181605" // Matches registration.refId}- The
For failed registration attempts:
- The
error
object will be present, containing:code
(string): The error codemessage
(string): A description of the error
- The
data
object will be absent.
Sample Callback Payload
// Example FAILED Callback Payload{"event": "CREATE_UPMS_REGISTRATION","timeStamp": "2025-03-11T10:20:00.000+05:30","refId": "HENSVVR4QOS7X1UGPY7JGUV444P10102204", // Reference ID of the FAILED attempt from sync response"error": {"code": "biller-registration-failed","message": "Failed to register with Biller"},"traceId": "D07LJTJ71N0PUBJKS640" // Trace ID for this callback}- The
For duplicate registrations:
- The
data
field will be present, and theerror
field will be absent. - The
duplicate
object withindata
indicates that a previous registration attempt wasSUCCESS
/PENDING
. Details of the existing registration can be found here.refId
: The reference ID of the existing successful/pending registration.code
: Code indicating the duplicate situation (e.g.,duplicate-upms-registration
).message
: Description of the duplicate situation.
Sample Callback Payload
// Example Duplicate Callback Payload{"event": "CREATE_UPMS_REGISTRATION","traceId": "CVVQVLN5STDFRUU0LLFG","timeStamp": "2025-04-16T18:55:42.758+05:30","data": {"duplicate": {"code": "duplicate-upms-registration","message": "Successful UPMS registration already exists","refId": "CVVQFN8BT5ONNAN3JCO059wmPQX51061821" // Ref ID of the EXISTING registration}},"refId": "CVVQVLGBT5ONNAN3JD90qXrHAWg51061855" // Ref ID of the DUPLICATE attempt from sync response}- The
Action: Update your internal registration record based on the callback status and response details (registration
, error
, or duplicate
).
#3.2 Viewing Registration Details
This synchronous endpoint allows you to retrieve the current status and details of a specific, existing UPMS registration immediately.
Endpoint: GET /api/v2/upms/registrations/{upmsRegistrationRefID}
(See API Reference)
Purpose: To check the details and current status of a UPMS registration.
Endpoint Type: Synchronous. The response contains the full, current details of the registration.
Request Breakdown:
- Headers:
X-PARTNER-ID: <Your_Partner_ID>
Authorization: Bearer <Your_Auth_Token>
Content-Type: application/json
- Path Parameter:
upmsRegistrationRefID
(string): The unique reference ID of the UPMS registration you want to view (obtained from a successfulCREATE_UPMS_REGISTRATION
callback, e.g.,D07LJTB71N0PGH5KG32G6dH2QjK51181605
).
Response Breakdown:
On Success (Registration Found): HTTP 200 OK
Sample Response
{"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"},"refId": "D054PTM52FL7R8CJPQ90GZ2ORTG51142008", // Unique reference ID of the registration"status": "SUCCESS", // Current status"updatedAt": "2025-04-24T14:38:47.389Z"},"success": true,"traceId": "D055CNT3GMB863CND9LG"}On Not Found: HTTP 404 Not Found
Sample Response
{"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
).Sample Response
{"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
Sample Response
{"success": false,"traceId": "C3SFG0O6N88R6UI7EQ","error": {"code": "internal-error","message": "Internal Error"}}
Action: Update your internal registration record based on the API response.
#3.3 Updating a Registration
This asynchronous endpoint allows modification of certain fields of an active UPMS registration.
Endpoint: PATCH /api/v2/upms/registrations/{upmsRegistrationRefID}
(See API Reference)
Purpose: To modify specific details of an existing, active UPMS registration.
Endpoint Type: Asynchronous. The API call acknowledges the request, and the final result is delivered via callback.
Modifiable Mandate Details:
registrationType
billPeriod
(restrictions may apply)toDate
debitInfo.debitType
debitInfo.amount
debitInfo.debitDate
(restrictions may apply)
Request Breakdown:
- Headers:
X-PARTNER-ID: <Your_Partner_ID>
Authorization: Bearer <Your_Auth_Token>
Content-Type: application/json
- Path Parameter:
upmsRegistrationRefID
(string): The ID of the registration to update.
- Body: Include only the fields you want to modify within the
mandate
object.
Example Request Body: Update Mandate
// 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
Sample Response
{"success": true,"traceId": "CV4PE82LTNJE9O014OE0"}On Bad Request: HTTP 400 Bad Request (Invalid field, invalid value, trying to update non-modifiable field).
Sample Response
{"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).
Sample Response
{"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
Sample Response
{"success": false,"traceId": "C3SFG0O6N88R6UI7EQ","error": {"code": "internal-error","message": "Internal Error"}}
Handling the Asynchronous Callback for Update:
You will receive an UPDATE_UPMS_REGISTRATION
callback with the final outcome.
UPDATE_UPMS_REGISTRATION
Callback: (See Webhook Reference)
Event Type:
event: "UPDATE_UPMS_REGISTRATION"
Timestamp:
timeStamp
Correlation:
refId
(Matches theupmsRegistrationRefID
from the PATCH request path).Trace ID:
traceId
Outcome:
If the update was successful:
- The
data
object will be present and theerror
object will be absent. - The
registration
object indata
will contain the complete, updated details of the registration. Use this to refresh your stored data.
Sample Callback Payload
{"event": "UPDATE_UPMS_REGISTRATION","traceId": "D07MLCSRLASJ2P3SVAI0","timeStamp": "2025-04-28T17:16:59.941+05:30","data": {"registration": {"refId": "D07ML76AIQNN6974G200emsL9K451181716","status": "SUCCESS","biller": {"id": "ABLP01000ANP03"},"customer": {"customerParams": [{"name": "Roll No","value": "67d88976"}],"mobile": "9039403265","name": "Gautam Rajput"},"mandate": {"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" // Note: This was the updated value in the example},"createdAt": "2025-04-28T11:46:36Z","updatedAt": "2025-04-28T11:46:59Z" // Reflects the update time}},"refId": "D07ML76AIQNN6974G200emsL9K451181716"}- The
If the update failed:
- The
error
object will contain thecode
andmessage
explaining the failure - The
data
object will be absent.
Sample Callback Payload
{"event": "UPDATE_UPMS_REGISTRATION","traceId": "D07N6PSRLASJ2P3SVAMG","timeStamp": "2025-04-28T17:54:07.062+05:30","refId": "D07N6M6AIQNN6974G9EGH18p7p051181753", // The refId of the attempted update"error": {"code": "biller-update-registration-failed","message": "Failed to update registration with Biller"}}- The
Action: Update your internal registration record based on the callback status and details.
#3.4 Cancelling a Registration
This asynchronous endpoint permanently cancels an existing UPMS registration.
Endpoint: DELETE /api/v2/upms/registrations/{upmsRegistrationRefID}
(See API Reference)
Purpose:
- To permanently stop automatic bill presentments and any associated auto-debits for a specific UPMS registration.
- Once cancelled, the same registration cannot be reactivated. A new registration will need to be created if the user wishes to re-enable automatic presentment.
Endpoint Type: Asynchronous. The API acknowledges the request, and confirmation comes via callback.
Request Breakdown:
- Headers:
X-PARTNER-ID: <Your_Partner_ID>
Authorization: Bearer <Your_Auth_Token>
Content-Type: application/json
- Path Parameter:
upmsRegistrationRefID
(string): The ID of the registration to cancel.
- Body: None
Synchronous Response (Acknowledgment):
Confirms receipt of the cancellation request.
On Acceptance: HTTP 200 OK
Sample Response
{"success": true,"traceId": "CV4PE82LTNJE9O014OE0"}On Bad Request: HTTP 400 Bad Request (e.g., invalid
upmsRegistrationRefID
format).Sample Response
{"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).
Sample Response
{"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).
Sample Response
{"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
Sample Response
{"success": false,"traceId": "C3SFG0O6N88R6UI7EQ","error": {"code": "internal-error","message": "Internal Error"}}
Handling the Asynchronous Callback for Cancellation:
You will receive a CANCEL_UPMS_REGISTRATION
callback confirming the outcome.
CANCEL_UPMS_REGISTRATION
Callback Details: (See Webhook Reference)
Event Type:
event: "CANCEL_UPMS_REGISTRATION"
Timestamp:
timeStamp
Correlation:
refId
(Matches theupmsRegistrationRefID
from the DELETE request path).Trace ID:
traceId
Outcome:
If the cancellation was successful:
- The
data
object will be present and theerror
object will be absent. - The
registration
object indata
will contain the details of the registration, now marked withstatus: "CANCELLED"
.
Sample Callback Payload
{"event": "CANCEL_UPMS_REGISTRATION","traceId": "D07MLCSRLASJ2P3SVAI0", // Example Trace ID"timeStamp": "2025-04-28T17:16:59.941+05:30", // Example Timestamp"data": {"registration": {"refId": "D07ML76AIQNN6974G200emsL9K451181716","status": "CANCELLED","biller": { /* ... biller details ... */ },"customer": { /* ... customer details ... */ },"mandate": { /* ... mandate details ... */ },"createdAt": "2025-04-28T11:46:36Z","updatedAt": "2025-04-28T11:46:59Z" // Time of cancellation}},"refId": "D07ML76AIQNN6974G200emsL9K451181716"}- The
If the cancellation failed:
- The
error
object will contain thecode
andmessage
explaining the failure - The
data
object will be absent.
Sample Callback Payload
{"event": "CANCEL_UPMS_REGISTRATION","traceId": "D07N6PSRLASJ2P3SVAMG", // Example Trace ID"timeStamp": "2025-04-28T17:54:07.062+05:30", // Example Timestamp"refId": "D07N6M6AIQNN6974G9EGH18p7p051181753", // The refId of the attempted cancellation"error": {"code": "registration-cancellation-failed", // Example Error Code"message": "Failed to cancel registration with Biller" // Example Error Message}}- The
Action: Update the status of the registration in your system to CANCELLED
upon successful confirmation via the callback.
#Part 3: Handling Bills and Payments
Once a customer is successfully registered for UPMS (see Part 2), the core value proposition comes into play: receiving automatic bill presentments. This part guides you on how to handle these presented bills and integrate them into your payment flows.
#Prerequisite: Configure Your Skip Payment Callback URL
You must set up and provide us with a secure HTTPS webhook endpoint URL. This endpoint is crucial as it's where our system will send asynchronous notifications (via HTTP POST) regarding presented bills and skipped payments (BILL_FETCH
, SKIP_PAYMENT
events).
#4. Receiving Presented Bills
The primary way you receive details about a newly generated bill for a registered customer is through the standard Bill Notification callback (BILL_FETCH
event). This is the same event used for responses to manual bill fetches, but includes an identifier for UPMS.
When a new bill is available for a registered customer, the flow is:
- Bill Generation: The biller generates a new bill for the customer.
- Push to BBPS: The biller pushes the bill to the BBPS Central Unit.
- Notification to COU: BBPS identifies the UPMS registration and notifies us.
- Callback to You: We send a
BILL_FETCH
webhook with the bill details. (See Webhook Reference) - Your Processing:
- Acknowledge with HTTP
200 OK
. - Parse the JSON payload.
- Check for
upmsRegistrationRefId
: Use this field to identify the UPMS registration associated with the bill. - Extract the bill object(s) from
data.bills
. - Store or update the bill in your system, associate with the user.
- Display bill details in your app.
- Acknowledge with HTTP
Example BILL_FETCH
Callback (for UPMS Presentment):
Note the presence of upmsRegistrationRefId
indicating this is for a registered subscription.
Sample Callback Payload
{"event": "BILL_FETCH","timeStamp": "2025-04-17T17:56:55.159+05:30","data": {"additionalInfo": [{"name": "Biller Unique Number","value": "Scaroasis"}],"billerResponseType": "SINGLE","billerSelectionType": null,"bills": [{"amount": 83400,"billDate": "2025-04-17","billNumber": "BILL-226131","billPeriod": "MONTHLY","customerName": "Nitin Gupta","dueDate": "2025-05-02","paymentOptions": [{"amount": 75060,"name": "Early Payment Amount"},{"amount": 91740,"name": "Late Payment Amount"}]}],"exactness": "RANGE","refId": "D00F73QLFUHJFPQC2800HVDeelt51071756", // Ref ID for this specific bill fetch instance"status": "Success","upmsRegistrationRefId": "D00EP9IJSBI05F06U9K0eBQWOq851071727"}}
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.- If
upmsRegistrationRefId
is absent or null, this callback is the result of a manual bill fetch request.
#5. Initiating Payment for Presented Bills
When a user opts to pay a presented bill:
- Invoke Payment API: Construct and send a request to our BBPS Payment API endpoint. (See API Reference)
- Follow Payment Flow: Handle the response and subsequent steps (e.g., status checks, notifications) as defined in the Payment API documentation.
#6. Handling Skipped Payments
Sometimes, a user might pay a bill through a different channel (e.g., directly on the biller's website, via another app) after it has been presented to them in your application via UPMS. To avoid showing already-paid bills as pending, Setu provides a mechanism to notify you about such payments.
#6.1 SKIP_PAYMENT Callback Flow
If a bill is paid elsewhere after presentation, you'll receive a SKIP_PAYMENT
callback: (See Webhook Reference)
- Payment Elsewhere: User pays via another BBPS channel.
- Notification to Us: BBPS detects external payment and informs us.
- Callback to You: We send a
SKIP_PAYMENT
webhook to your configured endpoint. - Your Processing:
- Acknowledge with HTTP
200 OK
. - Parse
data.billRefId
anddata.dateOfPayment
. (Note:data.billRefId
of skip payment callback is the same asdata.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.
- Acknowledge with HTTP
Example SKIP_PAYMENT
Callback:
Sample Callback Payload
{"event": "SKIP_PAYMENT","traceId": "D0508DIBJFBLCSGI36RG","timeStamp": "2025-04-25T18:16:46.716+05:30","data": {"billRefId": "D050862BJFBLCSGI36N0e3qv9Zu51151816","dateOfPayment": "2025-04-25T18:16:44+05:30"}}
#6.2 Why Handle SKIP_PAYMENT Callbacks?
Handling SKIP_PAYMENT callbacks ensures data consistency and improves user experience:
- Accurate Bill Status: Prevents users from seeing bills they've already paid elsewhere as still outstanding in your app.
- Avoids Double Payments: Reduces the risk of users accidentally attempting to pay the same bill twice.
- Clean User Interface: Keeps the list of pending bills relevant and actionable.
#Part 4: Testing and Simulation
This part covers the specialized APIs designed to help you test your integration, particularly your handling of asynchronous callbacks, in non-production environments.
#7. Introduction to Simulation APIs
Integrating asynchronous flows, especially those involving callbacks (webhooks), requires thorough testing. Waiting for real bill generation cycles or actual skipped payments can be slow and unpredictable during development and testing phases.
To facilitate this, we provide Simulation APIs that allow you to manually trigger specific callback events on demand.
Key Purposes:
- Verify Callback Handling: Ensure your webhook listener correctly receives, parses, and processes
BILL_FETCH
andSKIP_PAYMENT
callbacks. - Test Business Logic: Test the downstream logic in your application that gets triggered by these callbacks (e.g., displaying bills, marking bills as paid).
- Accelerate Development: Trigger events instantly without external dependencies in lower environments.
❗ Limitation:
- These Simulation APIs are strictly for use in lower environments only. They will not function in the Production environment. Attempting to use them in Production will result in an error.
Simulatable Events:
BILL_FETCH
(via Simulate Bill Notification Callback API)SKIP_PAYMENT
(via Simulate Skip Payment Callback API)
#8. Simulating a Bill Notification Callback
This asynchronous API allows you to manually trigger a BILL_FETCH
callback for a specific, active UPMS registration.
Endpoint: POST /api/v2/upms/simulate/{upmsRegistrationRefID}/callbacks/bill
(See API Reference)
Purpose: To trigger the delivery of a simulated BILL_FETCH
callback to your configured webhook endpoint for the specified upmsRegistrationRefID
. This helps test how your system handles incoming bill presentments.
Endpoint Type: Asynchronous. The API call acknowledges the request to simulate, and the actual BILL_FETCH
callback is delivered shortly after to your webhook listener.
Request Structure:
- Headers:
X-PARTNER-ID: <Your_Partner_ID>
Authorization: Bearer <Your_Auth_Token>
Content-Type: application/json
- Path Parameter:
upmsRegistrationRefID
(string): The unique reference ID of the active UPMS registration for which you want to simulate a bill notification. This registration must exist and be in a state likeSUCCESS
.
- Body: None
Synchronous Response (Acknowledgment):
Confirms that the request to simulate the callback has been accepted.
On Acceptance: HTTP 200 OK
Sample Response
{"success": true,"traceId": "CV4PE82LTNJE9O014OE0"}On Bad Request: HTTP 400 Bad Request (e.g., Invalid
upmsRegistrationRefID
format).Sample Response
{"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.
Sample Response
{"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.Sample Response
{"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.
Sample Response
{"success": false,"error": {"code": "internal-error","message": "Internal Error"},"traceId": "CV4PE82LTNJE9O014OE2"}
Handling the Asynchronous Callback Outcome:
Shortly after receiving the 200 OK acknowledgment, your configured webhook listener endpoint should receive an HTTP POST request containing the BILL_FETCH
callback (which shares the same BILL_FETCH
event structure).
- Callback Payload: The payload structure will follow the schema described for
BILL_FETCH
events (see Part 3, Section 4), including theupmsRegistrationRefId
you specified in the simulation request.
Action: Use this API in your test environment to verify that your webhook endpoint correctly receives, parses, and processes incoming bill notifications. Ensure you can link the received bill to the correct user based on the upmsRegistrationRefId
.
#9. Simulating a Skip Payment Callback
This asynchronous API allows you to manually trigger a SKIP_PAYMENT
callback for a specific bill reference ID.
Endpoint: POST /api/v2/upms/simulate/{billRefId}/callbacks/skip-payment
(See API Reference)
Purpose: To trigger the delivery of a simulated SKIP_PAYMENT
callback to your configured webhook endpoint for the specified billRefId
. This helps test how your system handles notifications that a bill, previously presented, was paid via another channel.
Endpoint Type: Asynchronous. The API call acknowledges the request, and the actual SKIP_PAYMENT
callback is delivered shortly after to your webhook listener.
Request Structure:
- Headers:
X-PARTNER-ID: <Your_Partner_ID>
Authorization: Bearer <Your_Auth_Token>
Content-Type: application/json
- Path Parameter:
billRefId
(string): The unique reference ID of the specific bill instance for which you want to simulate a skip payment notification. ThisbillRefId
would typically have been received previously in aBILL_FETCH
callback (either real or simulated).
- Body: None
Synchronous Response (Acknowledgment):
Confirms that the request to simulate the skip payment callback has been accepted.
On Acceptance: HTTP 200 OK
Sample Response
{"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 likeinvalid-bill
.Sample Response
{"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.
Sample Response
{"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.Sample Response
{"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.
Sample Response
{"success": false,"error": {"code": "internal-error","message": "Internal Error"},"traceId": "CV4PE82LTNJE9O014OE2"}
Handling the Asynchronous Callback Outcome:
Shortly after receiving the 200 OK acknowledgment, your configured webhook listener endpoint should receive an HTTP POST request containing the SKIP_PAYMENT
callback.
- Callback Payload: The payload structure will follow the schema described for
SKIP_PAYMENT
events (see Part 3, Section 6.1). It will includeevent: "SKIP_PAYMENT"
,timeStamp
,traceId
, and adata
object containing thebillRefId
you specified and adateOfPayment
.
Action: Use this API in your test environment to verify that your webhook endpoint correctly receives SKIP_PAYMENT
events and that your application logic correctly identifies the bill using billRefId
and updates its status appropriately (e.g., marks it as paid, removes it from pending lists).
#10. General Testing Recommendations
- Webhook Listener: Ensure you have a stable and publicly accessible webhook listener endpoint configured in our system for your Sandbox/UAT environment before using the simulation APIs.
- Test Scenarios: Use the simulation APIs to test various scenarios:
- Successful reception and processing of
BILL_FETCH
. - Successful reception and processing of
SKIP_PAYMENT
. - Handling potential errors if simulation is called with non-existent
upmsRegistrationRefId
orbillRefId
.
- Successful reception and processing of
- 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, 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.
Was this page helpful?