Disputes on marketplace orders
RekberPay's mediation team decides every marketplace dispute. You open it for the buyer or the seller, add evidence, and follow the outcome by webhook. You never decide it yourself.
Who can open a dispute
| Who | How |
|---|---|
| You, for the buyer or the seller | POST .../dispute with raised_by |
| The buyer, signed in on RekberPay | From the order on RekberPay |
| The buyer, after your confirm | Bukan saya, ajukan sengketa in the email, then the same button on the release notice page |
A milestone can be disputed while it is paid, shipped or release_pending. Earlier or later answers 409 INVALID_STATE.
1. Open the dispute
curl -X POST "https://api.rekberpay.com/v1/enterprise/platform/deals/$DEAL_ID/milestones/$MS_ID/dispute" \
-H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY" \
-H "Idempotency-Key: $(uuidgen | tr 'A-Z' 'a-z')" \
-H "Content-Type: application/json" \
-d '{
"reason": "The lens mount is cracked. Photos sent to the seller on 21 October.",
"raised_by": "buyer"
}'reasonis 10 to 700 characters, without<or>.raised_byisbuyerorseller.- The milestone becomes
disputed, and the dealdisputed. - Every timer stops: the time left on the automatic release (or on your pending confirm) is kept, and
auto_release_atandrelease_atare cleared. Nothing can be released while the dispute is open. - A pending partner confirm is cancelled. The
dispute.openedevent says so withrelease_cancelled: true. - The buyer and the seller get an in-app notice (live mode only).
2. Add evidence
Send a short statement and the files that support it. Only RekberPay's mediation team sees them; they never show in your document list.
curl -X POST "https://api.rekberpay.com/v1/enterprise/platform/deals/$DEAL_ID/milestones/$MS_ID/dispute/evidence" \
-H "Authorization: Bearer $REKBERPAY_WORKSPACE_KEY" \
-H "Idempotency-Key: $(uuidgen | tr 'A-Z' 'a-z')" \
-F "note=Buyer photos of the cracked mount, and the courier receipt." \
-F "[email protected]" \
-F "[email protected]"{ "success": true, "data": { "milestone_id": "4f5a6b7c-8d9e-4fa0-b1c2-d3e4f5a6b7c8", "status": "disputed", "files_added": 2 } }multipart/form-datawith onenotepart (3 to 700 characters, without<or>) and 1 to 5 parts namedfiles.- JPG, PNG, WebP or PDF, 10 MB each. RekberPay checks the real file type, re-encodes images and cleans PDFs. At most 50 files per dispute (
409 EVIDENCE_LIMIT_REACHED). - Only while the dispute is open (
409 NOT_DISPUTED). - Use a new
Idempotency-Keyfor every upload. The key is bound to the milestone, not to the files, so a reused key replays the first answer and stores nothing new.
3. The decision
The mediation team reads both sides and decides. A large decision needs a second RekberPay administrator before it takes effect. You get dispute.resolved with outcome and the amounts. A release also sends milestone.released; a refund or split sends no other event, so dispute.resolved is the one to act on.
outcome | Milestone after | Where the money goes |
|---|---|---|
release | released | The seller's partner balance gets payout_amount (amount minus the seller's fee share). You also get milestone.released |
refund | refunded | The buyer's partner balance gets the amount plus the buyer_fee share they paid. The payment method fee is not refunded |
split | released | Part goes back to the buyer, the rest to the seller (see below). refund_amount on the milestone shows the buyer's part |
resume | shipped | Nothing moves. The automatic release restarts with the time that was left. Only for a milestone that was shipped |
A refund goes to the buyer's partner balance at RekberPay, not back to the card or bank account they paid from. You can pay it out to the buyer like any other balance (Balances and withdrawals).
What dispute.resolved tells you
The money fields depend on the outcome. Amounts are whole rupiah.
outcome | Money fields |
|---|---|
release | payout_amount |
refund | refund_amount (the principal), buyer_fee_refunded (the buyer's fee share) and buyer_credit, their sum, which lands in the buyer's partner balance |
split | refund_amount, buyer_fee_refunded, buyer_credit, plus seller_credit and fee_revenue (what RekberPay kept) |
resume | none: auto_release_at and timer_remaining_seconds |
refund_amount is the principal only, the same number as refund_amount on the milestone. The buyer fee comes back on top of it, so for a full refund buyer_credit is more than refund_amount. Every field is described in the payload reference.
How a split adds up
The team picks refund_amount, from 1 rupiah to the amount minus 1. The fees are shared in the same proportion:
- the buyer gets
refund_amountplus the same share of theirbuyer_fee, rounded down - the seller gets the rest of the
amount, minus the share of theseller_feeon the part they keep (that fee share is rounded up) - RekberPay keeps what remains of the fee
Example: amount 1.000.000, buyer_fee 10.000, seller_fee 10.000 and a refund_amount of 400.000. The event says buyer_fee_refunded 4.000, buyer_credit 404.000, seller_credit 594.000 and fee_revenue 12.000. Together they add up to the 1.010.000 the buyer paid.
After a resume
The milestone is shipped again with auto_release_at = now plus the time that was left when the dispute opened. A dispute opened during your pending confirm gets the full shipping clock again from the resume (72 hours with a tracking number, 36 without, by default), or the time that was left if that is longer, because the parcel is still on its way and your confirm no longer stands. If there was no clock (the hour setting was 0), the milestone waits for the buyer's confirm or yours.
Deal status
The deal is disputed while any milestone is. When every milestone is finished, the deal is completed if at least one was released, otherwise cancelled. So an order whose only milestone was refunded ends as cancelled.
Checklist
- Open the dispute as soon as the buyer reports a problem, before the clock or your confirm releases the money.
- Add evidence from both sides. The team decides on what it can see.
- Use a new
Idempotency-Keyfor each evidence upload. - Handle
dispute.resolvedfor every outcome, includingsplitandresume.