Skip to content

Handling disputes ​

A dispute stops the money from moving while RekberPay looks at what happened. In this run Rina paid Rp300.000 for a logo design from Budi, the work did not match the brief, and she opens a dispute.

When a dispute is possible ​

Either party can open one while the escrow is paid, sent or received. Before payment, cancel the escrow instead. After release, the money has left escrow and a dispute is no longer possible.

1. Open the dispute ​

bash
curl -X POST https://api.rekberpay.com/v1/escrows/55555551-5555-4555-8555-555555555555/dispute \
  -H "Authorization: Bearer $REKBERPAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "reason_category": "item_not_as_described",
    "description": "Logo yang dikirim tidak sesuai brief: warna dan font berbeda dari yang disepakati."
  }'
js
const res = await fetch('https://api.rekberpay.com/v1/escrows/55555551-5555-4555-8555-555555555555/dispute', {
    method: 'POST',
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_API_KEY}`,
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        reason_category: "item_not_as_described",
        description: "Logo yang dikirim tidak sesuai brief: warna dan font berbeda dari yang disepakati."
    }),
});
const data = await res.json();
python
import os

import requests

resp = requests.post(
    "https://api.rekberpay.com/v1/escrows/55555551-5555-4555-8555-555555555555/dispute",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_API_KEY']}",
    },
    json={
        "reason_category": "item_not_as_described",
        "description": "Logo yang dikirim tidak sesuai brief: warna dan font berbeda dari yang disepakati.",
    },
    timeout=30,
)
print(resp.status_code, resp.json())
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/escrows/55555551-5555-4555-8555-555555555555/dispute');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_API_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'reason_category' => 'item_not_as_described',
        'description' => 'Logo yang dikirim tidak sesuai brief: warna dan font berbeda dari yang disepakati.',
    ]),
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

201 Created

json
{
    "success": true,
    "data": {
        "id": "77777771-7777-4777-8777-777777777777",
        "escrow_id": "55555551-5555-4555-8555-555555555555",
        "initiator_id": "11111110-1111-4111-8111-111111111111",
        "reason_category": "item_not_as_described",
        "description": "Logo yang dikirim tidak sesuai brief: warna dan font berbeda dari yang disepakati.",
        "status": "open",
        "priority": "normal",
        "resolution_note": null,
        "resolved_by": null,
        "resolved_at": null,
        "created_at": "2026-10-13T14:23:18.823Z",
        "updated_at": "2026-10-13T14:23:18.823Z"
    }
}

The escrow is now disputed and both sides and RekberPay are notified. A second dispute on the same escrow is refused:

409 Conflict

json
{
    "success": false,
    "error": {
        "code": "NOT_DISPUTABLE",
        "message": "Cannot dispute escrow in state: disputed. Must be: paid, sent, received"
    }
}

description is required:

400 Bad Request

json
{
    "success": false,
    "error": {
        "code": "INVALID_BODY",
        "message": "Validasi gagal",
        "details": {
            "formErrors": [],
            "fieldErrors": {
                "description": [
                    "Too small: expected string to have >=1 characters"
                ]
            }
        }
    }
}

2. Add evidence ​

Upload files with POST /v1/upload/escrow, then post them in the dispute thread. Both parties and RekberPay staff write in the same thread.

bash
curl -X POST https://api.rekberpay.com/v1/disputes/77777771-7777-4777-8777-777777777777/messages \
  -H "Authorization: Bearer $REKBERPAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Saya lampirkan brief awal dan hasil yang diterima.",
    "evidence_urls": [
      "https://api.rekberpay.com/uploads/escrow/1791901398283_862e8cf475cf7693efed4855a91995d0_7e10e097a2087a40e3e8e3b659df3f65.png"
    ]
  }'
js
const res = await fetch('https://api.rekberpay.com/v1/disputes/77777771-7777-4777-8777-777777777777/messages', {
    method: 'POST',
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_API_KEY}`,
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        message: "Saya lampirkan brief awal dan hasil yang diterima.",
        evidence_urls: [
            "https://api.rekberpay.com/uploads/escrow/1791901398283_862e8cf475cf7693efed4855a91995d0_7e10e097a2087a40e3e8e3b659df3f65.png"
        ]
    }),
});
const data = await res.json();
python
import os

import requests

resp = requests.post(
    "https://api.rekberpay.com/v1/disputes/77777771-7777-4777-8777-777777777777/messages",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_API_KEY']}",
    },
    json={
        "message": "Saya lampirkan brief awal dan hasil yang diterima.",
        "evidence_urls": [
            "https://api.rekberpay.com/uploads/escrow/1791901398283_862e8cf475cf7693efed4855a91995d0_7e10e097a2087a40e3e8e3b659df3f65.png",
        ],
    },
    timeout=30,
)
print(resp.status_code, resp.json())
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/disputes/77777771-7777-4777-8777-777777777777/messages');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_API_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'message' => 'Saya lampirkan brief awal dan hasil yang diterima.',
        'evidence_urls' => [
            'https://api.rekberpay.com/uploads/escrow/1791901398283_862e8cf475cf7693efed4855a91995d0_7e10e097a2087a40e3e8e3b659df3f65.png',
        ],
    ]),
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

201 Created

json
{
    "success": true,
    "data": {
        "id": "99999991-9999-4999-8999-999999999999",
        "dispute_id": "77777771-7777-4777-8777-777777777777",
        "sender_id": "11111110-1111-4111-8111-111111111111",
        "body": "Saya lampirkan brief awal dan hasil yang diterima.",
        "attachment_url": "https://api.rekberpay.com/uploads/escrow/1791901398283_862e8cf475cf7693efed4855a91995d0_7e10e097a2087a40e3e8e3b659df3f65.png?exp=1791979200000&sig=c0ffee5b1a9e3d7f4a2c8e6b0d9f1a3c5e7b9d1f3a5c7e9b1d3f5a7c9e1b3d5",
        "created_at": "2026-10-13T14:23:18.835Z"
    }
}

3. Follow the thread ​

Poll the messages. Send the newest created_at you have as after so each poll returns only new messages.

bash
curl "https://api.rekberpay.com/v1/disputes/77777771-7777-4777-8777-777777777777/messages?limit=20" \
  -H "Authorization: Bearer $REKBERPAY_API_KEY"
js
const res = await fetch('https://api.rekberpay.com/v1/disputes/77777771-7777-4777-8777-777777777777/messages?limit=20', {
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_API_KEY}`,
    },
});
const data = await res.json();
python
import os

import requests

resp = requests.get(
    "https://api.rekberpay.com/v1/disputes/77777771-7777-4777-8777-777777777777/messages?limit=20",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_API_KEY']}",
    },
    timeout=30,
)
print(resp.status_code, resp.json())
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/disputes/77777771-7777-4777-8777-777777777777/messages?limit=20');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_API_KEY'),
    ],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

200 OK

json
{
    "success": true,
    "data": [
        {
            "id": "99999991-9999-4999-8999-999999999999",
            "dispute_id": "77777771-7777-4777-8777-777777777777",
            "sender_id": "11111110-1111-4111-8111-111111111111",
            "body": "Saya lampirkan brief awal dan hasil yang diterima.",
            "attachment_url": "https://api.rekberpay.com/uploads/escrow/1791901398283_862e8cf475cf7693efed4855a91995d0_7e10e097a2087a40e3e8e3b659df3f65.png?exp=1791979200000&sig=c0ffee5b1a9e3d7f4a2c8e6b0d9f1a3c5e7b9d1f3a5c7e9b1d3f5a7c9e1b3d5",
            "created_at": "2026-10-13T14:23:18.835Z",
            "sender_email": "[email protected]",
            "sender_full_name": "Rina Wijaya",
            "sender_role": "user",
            "sender_participant_role": "buyer"
        },
        {
            "id": "aaaaaaa1-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
            "dispute_id": "77777771-7777-4777-8777-777777777777",
            "sender_id": "44444440-4444-4444-8444-444444444444",
            "body": "Revisi bisa saya kirim besok pagi.",
            "attachment_url": null,
            "created_at": "2026-10-13T14:23:18.841Z",
            "sender_email": null,
            "sender_full_name": "Budi Santoso",
            "sender_role": "user",
            "sender_participant_role": "seller"
        }
    ]
}

4. Read the outcome ​

RekberPay resolves the dispute by releasing the money to the seller, refunding the buyer or holding it. Read the dispute (or the escrow) to see where it stands:

bash
curl https://api.rekberpay.com/v1/disputes/77777771-7777-4777-8777-777777777777 \
  -H "Authorization: Bearer $REKBERPAY_API_KEY"
js
const res = await fetch('https://api.rekberpay.com/v1/disputes/77777771-7777-4777-8777-777777777777', {
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_API_KEY}`,
    },
});
const data = await res.json();
python
import os

import requests

resp = requests.get(
    "https://api.rekberpay.com/v1/disputes/77777771-7777-4777-8777-777777777777",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_API_KEY']}",
    },
    timeout=30,
)
print(resp.status_code, resp.json())
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/disputes/77777771-7777-4777-8777-777777777777');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_API_KEY'),
    ],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

200 OK

json
{
    "success": true,
    "data": {
        "id": "77777771-7777-4777-8777-777777777777",
        "escrow_id": "55555551-5555-4555-8555-555555555555",
        "initiator_id": "11111110-1111-4111-8111-111111111111",
        "reason_category": "item_not_as_described",
        "description": "Logo yang dikirim tidak sesuai brief: warna dan font berbeda dari yang disepakati.",
        "status": "open",
        "priority": "normal",
        "resolution_note": null,
        "resolved_by": null,
        "resolved_at": null,
        "created_at": "2026-10-13T14:23:18.823Z",
        "updated_at": "2026-10-13T14:23:18.823Z",
        "item_name": "Jasa desain logo toko",
        "amount": "300000.00",
        "escrow_status": "disputed",
        "buyer_id": "11111110-1111-4111-8111-111111111111",
        "seller_id": "44444440-4444-4444-8444-444444444444",
        "buyer_email": "[email protected]",
        "buyer_full_name": "Rina Wijaya",
        "seller_email": null,
        "seller_full_name": "Budi Santoso"
    }
}

When it is resolved, status changes and resolution_note explains the decision. The escrow becomes released, refunded or hold.

List every dispute ​

bash
curl "https://api.rekberpay.com/v1/disputes?limit=5" \
  -H "Authorization: Bearer $REKBERPAY_API_KEY"
js
const res = await fetch('https://api.rekberpay.com/v1/disputes?limit=5', {
    headers: {
        Authorization: `Bearer ${process.env.REKBERPAY_API_KEY}`,
    },
});
const data = await res.json();
python
import os

import requests

resp = requests.get(
    "https://api.rekberpay.com/v1/disputes?limit=5",
    headers={
        "Authorization": f"Bearer {os.environ['REKBERPAY_API_KEY']}",
    },
    timeout=30,
)
print(resp.status_code, resp.json())
php
<?php

$ch = curl_init('https://api.rekberpay.com/v1/disputes?limit=5');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('REKBERPAY_API_KEY'),
    ],
]);
$response = json_decode(curl_exec($ch), true);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);

200 OK

json
{
    "success": true,
    "data": [
        {
            "id": "77777771-7777-4777-8777-777777777777",
            "escrow_id": "55555551-5555-4555-8555-555555555555",
            "initiator_id": "11111110-1111-4111-8111-111111111111",
            "reason_category": "item_not_as_described",
            "description": "Logo yang dikirim tidak sesuai brief: warna dan font berbeda dari yang disepakati.",
            "status": "open",
            "priority": "normal",
            "resolution_note": null,
            "resolved_by": null,
            "resolved_at": null,
            "created_at": "2026-10-13T14:23:18.823Z",
            "updated_at": "2026-10-13T14:23:18.823Z",
            "item_name": "Jasa desain logo toko",
            "amount": "300000.00",
            "escrow_status": "disputed",
            "buyer_id": "11111110-1111-4111-8111-111111111111",
            "seller_id": "44444440-4444-4444-8444-444444444444",
            "buyer_email": "[email protected]",
            "buyer_full_name": "Rina Wijaya",
            "seller_email": null,
            "seller_full_name": "Budi Santoso"
        }
    ],
    "pagination": {
        "page": 1,
        "limit": 5,
        "total": "1"
    }
}

Tips ​

  • Open a dispute only after talking in the escrow chat; many problems are solved there.
  • Put the facts and the evidence in the first message: what was agreed, what arrived, and photos or files.
  • Do not open a second escrow for the same order while a dispute is open.

Next steps ​

Escrow, payment services and B2B deals for Indonesian businesses.