Available Endpoints 🔗
1. Upload QRIS
Upload QRIS image with merchant details to be used in QRIS generation.
Endpoint:
POST /api/v1/qrisly/upload-qris
Base URLs:
- Production: https://api.collaborator.komerce.id/user
- Sandbox: https://api-sandbox.collaborator.komerce.id/user
Request Format:
Content-Type: multipart/form-data
Request Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
name | String | Yes | QRIS identity name (max 100 chars) |
qris_image | File | Yes | QRIS image file (PNG/JPG, max 5MB) |
Request Example:
curl -X POST "https://api-sandbox.collaborator.komerce.id/user/api/v1/qrisly/upload-qris" \
-H "X-API-Key: your_api_key_here" \
-F "name=ABC Online Store" \
-F "qris_image=@/path/to/qris.png"
Success Response (200):
{
"success": true,
"message": "QRIS successfully uploaded and validated",
"data": {
"qris_id": "9d6c9f9e-8c33-4f42-8b1f-0e6a3e2e7d10",
"provider": "DANA",
"name": "ABC Store",
"merchant_name": "ABC Store",
"created_at": "2026-03-03 14:00:54"
}
}
Error Response Examples:
// Invalid file format
{
"message": "Please upload a file with one of these types: image/png,image/jpeg,image/jpg",
"code": 400,
"status": "error"
}
// File too large
{
"message": "file size must be less than 5MB",
"code": 400,
"status": "error"
}
Key Points:
- 📤 Upload once, reuse qris_id for multiple transactions
- 🖼️ Supported formats: PNG, JPG
- 📊 Max file size: 5MB
- ✅ QRIS image will be validated automatically
2. Generate QRIS
Generate dynamic QRIS with custom amount for each transaction.
Endpoint:
POST /api/v1/qrisly/generate-qris
Base URLs:
- Production: https://api.collaborator.komerce.id/user
- Sandbox: https://api-sandbox.collaborator.komerce.id/user
Request Format:
Content-Type: application/json
Request Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
qris_id | UUID | Yes | QRIS ID from upload step |
amount | Number | Yes | Amount in Rupiah (must be >= 1000) |
output_type | String | Yes | "string" or "image" |
unique_amount | Boolean | Yes | Add unique identifier to amount (default: true) |
Request Example:
curl -X POST "https://api-sandbox.collaborator.komerce.id/user/api/v1/qrisly/generate-qris" \
-H "Content-Type: application/json" \
-H "X-API-Key: your_api_key_here" \
-d '{
"qris_id": "9d6c9f9e-8c33-4f42-8b1f-0e6a3e2e7d10",
"amount": 100000,
"output_type": "string",
"unique_amount": true
}'
Success Response (200):
{
"success": true,
"message": "QRIS successfully generated",
"data": {
"history_id": 1778,
"qris_string": "000201021126360011com.danamon5230141331231230061010160313UME51450015ID.CO.VERIFKATORKODE0520418345220630058203645304100650045600962070703121703031280072G051160014ID.KOMERCE.VERIFKATOR52047648530335802ID0106012023012301070440000962220601141331231230071391000160131231230000000000000000000000000000000000000000000000000000000000000000063049FD2",
"original_amount": 1000,
"final_amount": 1003,
"payment_status": "unpaid",
"expiry_time": "2026-03-03 14:52:52"
}
}
Error Response Examples:
// Invalid amount
{
"message": "amount must be between 1000 and 100000000",
"code": 400,
"status": "error"
}
// QRIS not found
{
"success": false,
"message": "QRIS not found",
"error_code": "QRIS_NOT_FOUND",
"details": {
"suggestion": "Verify QRIS ID or upload a new QRIS"
}
}
Understanding Unique Amount
When you enable unique_amount: true, QRISLY adds a unique decimal identifier to your amount. This helps your mobile app listener distinguish between identical amounts.
Example:
Original Amount Requested: IDR 10,000
Response with unique_amount: true: IDR 10,001
If you request IDR 10,000 again:
First request: IDR 10,000 → IDR 10,001
Second request: IDR 10,000 → IDR 10,002
Third request: IDR 10,000 → IDR 10,003
Why This Matters: Your mobile banking app listener reads the payment amount to confirm transactions. Without unique identifiers, two identical payments would look the same. The decimal addition (0.001, 0.002, etc.) tells the listener app that these are separate transactions, enabling proper tracking even when amounts match.
Key Points:
- 💵 IDR 100 per generate - charged immediately
- 🎯 Use unique_amount: true to prevent duplicate payments with identical amounts
- 📊 Each unique amount increment is tracked by QRISLY automatically
- ⏰ Default expiry: 15 minutes from generation
- 📱 Output can be string (for display in app) or image (for print)
- 🔔 Mobile app listener can distinguish transactions via the unique decimal identifier
3. Check Payment Status
Monitor real-time payment status for each generated QRIS.
Endpoint:
GET /api/v1/qrisly/payment-status/{history_id}
Base URLs:
- Production: https://api.collaborator.komerce.id/user
- Sandbox: https://api-sandbox.collaborator.komerce.id/user
Path Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
history_id | INT | Yes | History ID from generate-qris response |
Request Example:
curl -X GET "https://api-sandbox.collaborator.komerce.id/user/api/v1/qrisly/payment-status/1771" \
-H "X-API-Key: your_api_key_here"
Success Response (200):
{
"meta": {
"message": "QRIS payment status successfully retrieved",
"code": 200,
"status": "success"
},
"data": {
"history_id": 2720,
"payment_status": "unpaid",
"amount": 1003,
"name": "ABC",
"paid_at": null,
"created_at": "2026-04-06T08:41:56+07:00",
"updated_at": "2026-04-06T08:41:56+07:00"
}
}
Payment Status Values:
| Status | Description |
|---|---|
unpaid | QRIS has been generated, waiting for payment |
paid | Payment successfully received |
expired | QRIS has expired, need to generate new |
cancelled | Payment cancelled by user |
Error Response Example:
{
"meta": {
"message": "Payment history not found",
"code": 404,
"status": "error"
},
"data": null
}
Key Points:
- ✅ Real-time status, updated instantly when payment is received
- 📞 Use this endpoint as fallback if webhook is not received
- 🔄 Safe to call multiple times without additional charges
- ⏰ Stored for 90 days after transaction