Bill payments public contract v2026-07-01
This page defines the target public PayWise Bill Payments contract for version=2026-07-01.
The current 2024-10-01 contract remains the compatibility/runtime shape. This page is the cleaner public draft and should be read as the forward contract target for Bill Payments only.
The canonical flow is:
Client or Virtual Agent -> wrappers -> transactions -> DAP -> DevHouse /api/third_party_transactions
1. Overview​
Bill Payments is a public, institution-scoped payment flow for approved integrators. The public edge validates the caller, normalizes the request, forwards the request into transactions, and lets DAP execute the DevHouse provider flow.
The public client does not execute provider step 1 or step 2, and it never receives provider tokens, IP headers, encrypted IDs, raw provider payloads, or internal provider references by default.
2. Target clients
- Virtual Agent
- Credit unions
- Third-party integrators
3. Public route summary
Canonical public routes:
GET /bill_payments/billers?version=2026-07-01POST /bill_payments/pay?version=2026-07-01GET /bill_payments/status?version=2026-07-01&transaction_id=...GET /bill_payments/receipt?version=2026-07-01&transaction_id=...
Compatibility aliases may continue to exist for older integrations, but they are not the recommended public integration target.
Do not document kiosk/internal /api/billpay/* routes as public partner routes.
4. Versioning
The public Bill Payments contract uses query parameter versioning only:
- ?version=2026-07-01
Do not introduce a version header for this contract.
5. Headers
Required and recommended public headers:
PW-subscription-keyPW-origin-countryPW-request-datePW-ip-addressUser-AgentIdempotency-KeyX-Request-Id
Notes:
Idempotency-Keyis required forPOST /bill_payments/pay.X-Request-Idis recommended for traceability.- Do not expose DevHouse legacy provider headers in the public contract.
- Public docs must not include
iportokenprovider headers.
6. POST /bill_payments/pay
Request body​
Use snake_case for the public request body.
Canonical request example:
{
"biller_code": "18689859859",
"product_code": "0000",
"amount": "50",
"currency": "TTD",
"customer_reference": "1023358",
"customer_mobile_no": "18685125125",
"external_reference": "CU-20260704-000123",
"client_receipt_id": "VENTURE-RCPT-981234",
"id_type": "DP",
"id_number": "732711",
"description": "Bill payment",
"other_data": "optional trace metadata",
"metadata": {
"source": "partner"
}
}
Field definitions:
biller_code: PayWise biller/payee identifier.product_code: product or service code under the biller.amount: string decimal amount.currency: ISO currency code, for exampleTTD.customer_reference: customer account, bill, or reference number at the biller.customer_mobile_no: payer or customer mobile number, if available.external_reference: client or partner order or correlation reference.client_receipt_id: client or partner receipt/reference proving its own customer or member funds collection.id_type: optional payer identity document type.id_number: optional payer identity document number.description: optional transaction description.other_data: optional trace metadata.metadata: optional client metadata.
Important:
receipt_idis not accepted in the request.- Clients must use
client_receipt_idfor their own receipt/reference. - PayWise generates
receipt_id.
Response body: create
Use snake_case in the public response.
{
"status": "success",
"code": 201,
"message": "Bill payment completed.",
"transaction_id": "af49178b-bd4c-4104-9b7f-f00cf1125d29",
"normalized_status": "SUCCESS",
"receipt_id": "PWBP-9C11D5BC",
"external_reference": "CU-20260704-000123",
"client_receipt_id": "VENTURE-RCPT-981234"
}
7. GET /bill_payments/status
Query shape​
The status endpoint uses:
transaction_idas a query parameter
Response body: status
{
"status": "success",
"code": 200,
"transaction_id": "af49178b-bd4c-4104-9b7f-f00cf1125d29",
"normalized_status": "SUCCESS",
"receipt_id": "PWBP-9C11D5BC",
"external_reference": "CU-20260704-000123",
"client_receipt_id": "VENTURE-RCPT-981234"
}
8. GET /bill_payments/receipt
Query shape​
The receipt endpoint uses:
transaction_idas a query parameter
Response body: receipt
{
"status": "success",
"code": 200,
"transaction_id": "af49178b-bd4c-4104-9b7f-f00cf1125d29",
"receipt_id": "PWBP-9C11D5BC",
"normalized_status": "SUCCESS",
"amount": "50",
"currency": "TTD",
"biller_code": "18689859859",
"product_code": "0000",
"customer_reference": "1023358",
"external_reference": "CU-20260704-000123",
"client_receipt_id": "VENTURE-RCPT-981234",
"timestamp": "2026-07-04T00:00:00.000Z"
}
Receipt ID rules
receipt_idis returned only after successful billpay execution.receipt_idis PayWise-owned.receipt_idis never supplied by the client.transaction_idis never used asreceipt_id.- DevHouse encrypted IDs are never used as
receipt_id.
9. Identifier rules
transaction_id = PayWise transaction tracking ID
receipt_id = PayWise-generated bill payment receipt/reference
external_reference = client or partner order or correlation reference
client_receipt_id = client or partner receipt/reference for its own funds collection
provider_reference = internal provider reference, not public by default
10. Receipt format
PayWise bill payment receipt format:
PWBP-<8 uppercase alphanumeric characters>
Example:
PWBP-9C11D5BC
This keeps bill payments distinct from other receipt families while preserving a short human-readable format.
11. Status model​
Public statuses are terminal-only:
SUCCESSFAILED
Public clients must not see:
PENDINGPROCESSING
Any intermediate orchestration state must remain internal to transactions or DAP.
12. Idempotency​
Idempotency-Keyis required forPOST /bill_payments/pay.- The same key plus the same payload returns the stored result.
- The same key plus a different payload returns a conflict.
- Replay must not re-execute provider step 1 or step 2.
13. Public client funding model
Third-party clients such as credit unions may collect funds from their customer or member before calling PayWise Bill Payments. In that case, the client may send client_receipt_id and/or external_reference for reconciliation.
PayWise still generates its own receipt_id for the PayWise bill payment execution. Settlement between the client and PayWise is governed separately and is not represented by provider credentials in this API.
14. Public billers endpoint​
The 2026-07-01 public contract includes a billers catalogue endpoint.
Sandbox billers intentionally mirror the sandbox/mobile source catalogue, so public sandbox responses may include test/dev-looking billers when they are active and present in source. Public clients should rely on documented visibility/status fields and product availability, not on name heuristics.
Endpoint
GET /bill_payments/billers?version=2026-07-01
Target response shape
{
"status": "success",
"code": 200,
"billers": [
{
"biller_code": "18689859859",
"display_name": "Example Utility",
"category": "Utilities",
"country": "TT",
"currency": "TTD",
"products": [
{
"product_code": "0000",
"display_name": "Bill Payment",
"required_fields": [
"customer_reference",
"amount"
]
}
]
}
]
}
This page is the forward contract target. If the runtime still exposes a compatibility shape, that shape remains separate from the 2026-07-01 draft contract.