Merchants API
Endpoints for looking up merchant data within the partner's scope. Only merchants in the partner scope (referral / consent / assignment) are returned.
Base URL:
| Environment | Host |
|---|---|
| Production | https://api-merchant.kesles.com |
| Staging | https://api-merchant-staging.kesles.com |
Base path: /api/partner/v1
Auth: Bearer token from POST /api/partner/v1/auth/token. See Partner Onboarding for how to obtain credentials.
List Referral Merchants
GET /api/partner/v1/partners/{partner_id}/referral-merchants
Lists merchants within this partner's scope (referral / consent / assignment).
Scope: merchant.read
Request
GET /api/partner/v1/partners/{partner_id}/referral-merchants
Authorization: Bearer {access_token}
X-Request-ID: {uuid}
Response 200
{
"partner_id": "uuid",
"items": [
{
"merchant_id": "uuid",
"merchant_code": "MRC-000123",
"merchant_name": "Sample Store",
"referral_partner_id": "uuid",
"status": "active"
}
],
"count": 1
}
| Field | Format | Notes |
|---|---|---|
merchant_id | UUID | Merchant identifier |
merchant_code | string | Kesles internal merchant code |
merchant_name | string | Merchant trade name |
referral_partner_id | UUID | null | Partner ID yang mereferral merchant ini |
status | enum | active, pending_review, inactive, suspended |
count | integer | Jumlah item yang dikembalikan |
Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | unauthorized | Access token invalid / expired |
| 403 | forbidden | Partner does not have merchant.read scope or partner_id mismatch |
| 429 | rate_limit_exceeded | More than 60 req/min |
Referral Summary
GET /api/partner/v1/partners/{partner_id}/referral-merchants/summary
Aggregate summary of referral merchants + transaction performance.
Scope: merchant.read
Response 200
{
"partner_id": "uuid",
"merchant_count": 142,
"active_count": 98,
"inactive_count": 44
}
| Field | Format | Notes |
|---|---|---|
merchant_count | integer | Total merchants in partner scope |
active_count | integer | Merchants dengan status = active |
inactive_count | integer | Merchants dengan status selain active |
Merchant Transactions
GET /api/partner/v1/merchants/{merchant_id}/transactions
Lists merchant transactions (only merchants within the partner scope).
Scope: transaction.read
Request
GET /api/partner/v1/merchants/{merchant_id}/transactions?transaction_at_from=2026-04-01T00:00:00Z&transaction_at_to=2026-04-30T23:59:59Z&status=success&limit=50
Authorization: Bearer {access_token}
X-Request-ID: {uuid}
Query params:
| Param | Type | Default | Notes |
|---|---|---|---|
transaction_at_from | RFC3339 | — | Filter awal waktu transaksi (inklusif) |
transaction_at_to | RFC3339 | — | Filter akhir waktu transaksi (inklusif) |
status | string | — | Filter by status: success, pending, failed, refunded |
limit | integer | 50 | Jumlah item, maksimal 500 |
The backend hard-caps responses at 500 items. For high-volume date ranges, use narrower windows via transaction_at_from / transaction_at_to.
Response 200
{
"merchant_id": "uuid",
"items": [
{
"id": "uuid",
"merchant_id": "uuid",
"transaction_code": "TRX-2026-04-000412",
"transaction_status": "success",
"payment_method": "qris",
"payment_channel": "bca",
"gross_amount": 75000,
"mdr_rate": 0.007,
"mdr_fee_amount": 525,
"net_amount_after_mdr": 74475,
"currency": "IDR",
"transaction_at": "2026-04-24T10:15:28Z",
"settled_at": "2026-04-25T08:00:00+07:00",
"settlement_status": "settled"
}
],
"count": 1
}
Per-item fields:
| Field | Format | Notes |
|---|---|---|
id | UUID | Transaction identifier |
merchant_id | UUID | Merchant identifier |
transaction_code | string | Kesles internal code |
transaction_status | enum | success, pending, failed, refunded |
payment_method | string | qris, card, cash, etc. |
payment_channel | string | Channel/issuer (e.g. bca, mandiri) |
gross_amount | integer | Gross amount (smallest currency unit) |
mdr_rate | decimal | MDR rate yang dikenakan |
mdr_fee_amount | integer | Nominal biaya MDR (smallest currency unit) |
net_amount_after_mdr | integer | Gross amount dikurangi MDR fee |
currency | ISO 4217 | Default IDR |
transaction_at | RFC3339 | Waktu transaksi (full timestamp) |
settled_at | RFC3339 | null | Settlement time; null if not yet settled |
settlement_status | string | Status settlement transaksi |
Internal fields not returned to partners: customer_id, qris_payload, gateway-side merchant/terminal identifiers, raw device_id, payer_reference, and internal fee-share components. Default currency is IDR (smallest unit = whole rupiah, no decimals); QRIS Cross-border will add an ISO 4217 currency field once live.
Merchant Scoring Summary
GET /api/partner/v1/merchants/{merchant_id}/scoring-summary
Transaction-based scoring summary — for finance / scoring underwriting partners.
Scope: scoring.read or risk-summary.read
Response 200
{
"merchant_id": "uuid",
"average_monthly_gross_amount": 78500000,
"average_monthly_transaction_count": 412,
"avg_ticket_size": 190534,
"growth_30d": 8.2,
"settlement_consistency_score": 95,
"transaction_stability_score": 90,
"months_sampled": 3
}
| Field | Format | Notes |
|---|---|---|
average_monthly_gross_amount | integer | Gross amount bulan terakhir (smallest currency unit) |
average_monthly_transaction_count | integer | Jumlah transaksi bulan terakhir |
avg_ticket_size | integer | Rata-rata nilai transaksi bulan terakhir |
growth_30d | decimal | Pertumbuhan gross amount vs bulan sebelumnya dalam persen (8.2 = +8.2%) |
settlement_consistency_score | integer 0–100 | Skor konsistensi transaksi dalam stepped buckets: 95 / 85 / 70 / 55 / 35 |
transaction_stability_score | integer 0–100 | Skor stabilitas volume transaksi dalam stepped buckets: 90 / 75 / 60 / 40 |
months_sampled | integer | Jumlah bulan data yang digunakan untuk kalkulasi |
Partner Scope
A partner can only access merchants that are:
- Referred by the partner (via
referral_codematch) - Granted explicit consent by the merchant
- Manually assigned by a Kesles operator
Anything outside this scope → 403 forbidden.
For certain server-to-server integrations (outside the public Partner API scope above), Kesles provides a separate API contract shared directly with the integration PIC via the Partner Agreement + an encrypted onboarding channel. The general signature pattern (HMAC-SHA256) is in HMAC Authentication.