Changelog
We follow calendar versioning. Every notable change that affects partners is logged here. Subscribe to [email protected] for release emails.
2026-08-04
Added — Jasa Pembayaran is now documented
- Jasa Pembayaran API documents the pay-on-behalf product:
GET /api/jasabayar/config,POST /api/jasabayar/quote,POST /api/jasabayar,GET /api/jasabayar,GET /api/jasabayar/:id, andPOST /api/jasabayar/:id/cancel. The surface shipped earlier but had no reference page, so integrators had nothing to build against. - An order is not an escrow: no counterparty, no chat, no dispute, no shipping. It has its own status enum (
awaiting_payment,pending_review,paid,processing,delivered,refunded,cancelled). Do not map escrow statuses onto it. - Undelivered funded orders auto-refund in full when the SLA window expires;
auto_refundeddistinguishes a sweeper refund from an operator's.
Changed — escrow fee default corrected to 1%
- The fallback escrow fee used when
escrow_fee_valueis absent from settings read 3%, while RekberPay's published rate is 1%. A fresh install therefore priced at triple the advertised rate. The fallback is now1%with aRp2.000floor. - This is a fallback only. Deployments with an explicit
escrow_fee_valuewere charging their configured rate throughout and are unaffected. - The
2026-05-18entry below quotes the old3% / 5.000default. It is accurate as a record of that release; this entry supersedes it.
Added — buyers can extend the auto-release window
POST /api/escrows/:id/extendpushes backauto_release_atwhen a buyer needs longer to inspect. Capped:409 EXTEND_LIMIT_REACHEDonceauto_release_extend_counthits the configured maximum, and409 EXTEND_DISABLEDwhere the category does not allow it.
Changed — withdrawal destinations are acknowledged
POST /api/withdrawalsacceptsdestination_ack: true, recording that the user confirmed the destination account. The acknowledgement is stored with a hash, timestamp, and IP. Money sent to a correctly-processed but user-mistyped destination is not refundable, so the record is the evidence for that clause.
Fixed — idempotency keys no longer strand PPOB and voucher retries
POST /api/ppob/checkoutandPOST /api/vouchers/redeemregistered the idempotency pre-handler without the companion send hook, so their keys stayedpendingfor the full 24h TTL. A client retrying a timed-out request with the same key — the documented contract — received409 IDEMPOTENCY_KEY_IN_FLIGHTindefinitely and could never learn the outcome. Both routes now finalize the key on response, so retries replay the original result as intended.
Corrected — outbound webhooks were documented but never existed
- The webhooks reference, the webhook guide, the quickstart, and the homepage all described RekberPay POSTing signed events (
payment.completed,escrow.released, …) to a partner URL, with a signature scheme, a 5s timeout and 7 retries. None of it was implemented. There is no outbound sender, no webhook registration, no/.well-known/webhook-ips, and every route under/api/webhooks/*is inbound (payment gateways calling us). - If you built a verification endpoint against that spec, nothing was ever going to arrive at it. That is our error and it is called out rather than quietly removed.
- Use polling:
GET /api/escrows/:id/payment-statusandGET /api/jasabayar/:id/payment-status, orGET /api/escrows/:idfor full state. A 5–10s cadence on an open checkout is well inside the rate limit. - The event contract is retained on the webhooks page as a planned design so it stays stable when delivery ships. It is clearly marked unimplemented.
Corrected — authentication page denied that bearer tokens exist
- The page opened with "No bearer tokens". The API has supported
Authorization: Bearer <api-key>throughout, with issuance atGET /api/auth/me/api-keyand rotation atPOST /api/auth/me/api-key/rotate. - Now documented, including the sharp edge: rotation revokes all existing keys immediately, with no grace period, and the plaintext is returned exactly once. Deploy the new key before rotating.
- Bearer callers are exempt from CSRF by design; cookie sessions still require
X-CSRF-Tokenon mutations.
Corrected — idempotency coverage and error codes
- The idempotency guide claimed keys work "on every mutation endpoint". Disputes, ratings, support and auth expose 16 POST routes with no support at all — a key sent there is ignored and a retry duplicates the action. The guide now lists exactly which routes honour it, and which do not.
IDEMPOTENCY_PARAMS_MISMATCHnever existed; the real code is422 IDEMPOTENCY_KEY_CONFLICT. Added409 IDEMPOTENCY_KEY_IN_FLIGHT, whose correct recovery is to retry the same key — a fresh one runs the operation twice.- Status codes fixed against source:
LINK_EXPIREDandSELLER_NOT_FOUNDare 422 (documented 400/404);GATEWAY_TIMEOUT(504) does not exist and isGATEWAY_ERROR(502);PAYLOAD_TOO_LARGEis really Fastify'sFST_ERR_CTP_BODY_TOO_LARGE. RemovedINVALID_VERSION,MISSING_FIELDandDUPLICATE_REF, which are never thrown.
2026-07-04
Changed — attachment URLs are now short-lived signed links
attachment_urlvalues returned for chat messages, dispute evidence, and escrow attachments now carry a signed capability token (?exp=…&sig=…). Render or download the URL as returned — do not strip the query string, cache it long-term, or reconstruct the bare URL. The token is valid for roughly 12–24h; re-fetch the parent resource to obtain a fresh link. Files remain private to the escrow's parties and admins.- Uploads still return a bare, storable URL from
POST /api/upload/:type; the signing happens only on read responses. Submit the bare URL back asattachment_url/evidence_urlsexactly as before.
Changed — partner deep links must be signed
POST /api/escrows/from-linknow requires a valid HMAC signature whenever partner parameters (seller, item, etc.) are present. An unsigned partner link is rejected with400 SIGNATURE_REQUIRED. Malformed URL-encoding now returns400instead of a500.
Fixed — payment webhook retries are never silently dropped
- A webhook delivery that fails mid-processing on a transient error is now reprocessed on the gateway's retry instead of being treated as a duplicate. Previously such a retry could be acknowledged (
200) without the payment being applied. Genuinely duplicate (already-processed) deliveries are still acknowledged idempotently. A lateexpired/failedcallback arriving after a successfulpaidno longer overwrites the paid state.
2026-06-30
Fixed — idempotent retries after a failed request
- A request that fails (any non-2xx response, including a transient 5xx) is no longer cached against its
Idempotency-Key. Previously the failure was frozen as the key's answer and replayed for the key's 24h lifetime; now retrying with the same key re-executes the operation. Successful (2xx) responses are still cached and replayed as before.
2026-06-27
Added — shipping tracking for physical goods
- Sellers can attach a courier + AWB (resi) when marking an escrow shipped:
POST /api/escrows/:id/sendnow accepts an optional{ courier, tracking_number }body. - New party-only endpoints:
GET /api/escrows/:id/tracking(courier metadata, live journey snapshot, and the courier dropdown list) andPOST /api/escrows/:id/tracking/refresh(forces a fresh upstream check, rate-limited to one call per escrow every 5 minutes). GET /api/escrows/:idnow includes atrackingobject (courier, AWB, last-known status, and an official-courier deep link) once a resi is attached.- The live status timeline is best-effort enrichment: the courier + AWB are always persisted and an official-courier deep link is always available, so a flaky upstream never blocks the page.
2026-06-16
Added
- Universal inbound Webhook/IPN endpoints (
POST /api/webhooks/inbound,/ipn,/payment,/universal) with dynamic provider auto-detection. - Integrated
Paymentopayment gateway adapter supporting cryptocurrency payments. - Support for admin-configured payment gateway surcharges (
fee_percentandfee_fixed), calculated securely on the server and surfaced inGET /api/gateways/available-methodsandPOST /api/escrows/:id/pay. - New payment response fields:
escrow_amount(base value) andsurcharge(gateway fee) in payment responses.
2026-05-18
Added
POST /api/escrows/from-link— full HMAC-signed partner link flowGET /api/escrows/:id/preview— public preview endpointGET /api/escrows/:id/payment-status— polling fallback to webhooksIdempotency-Keyheader on all mutation endpoints- Webhook signature verification on every outbound event
- Sandbox environment at
sandbox-api.rekberpay.comwith mock-pay support
Changed
- Default fee config tightened: 3% with 5,000 IDR floor (was 2.5% / 3,000)
- Withdrawal fee now flat 5,000 IDR up to 25,000 IDR cap
Documentation
- Initial public docs at docs.rekberpay.com
Stability promise
We commit to no breaking changes within signature version v=1. Any breaking change will:
- Bump the version (
v=2) and ship alongsidev=1 - Be announced 90 days before
v=1is deprecated - Be 180 days before
v=1is removed
Additive changes (new fields, new events, new endpoints) are not breaking and will be released without a version bump.