Returns & Disputes
Free for sellers, fair for buyers. Buyer pays return shipping. Item price always refunded from escrow. Seller never owes money.
Decisions locked (2026-04-28): Return window 24 hours, low-value auto-approve threshold IDR 50,000, Biteship reverse label v1 build scope confirmed. All implementation gaps closed as of PS-311→PS-320 sprint (2026-05-12): return window 24h live (PS-155, 2026-05-05); reason enforcement live, changed_mind rejected at API layer (PS-316); auto-approve IDR 50k live, AUTO_APPROVE_THRESHOLD = 50_000 in routes-orders.tsx (PS-312); reverse label generation live, POST /orders/:id/return-label (PS-313); admin evidence viewer, deadline countdown, and received stat card live (PS-317, PS-318, PS-319).
The decision tree
Core principles
1. Sellers never owe money
On any approved return, seller loses the sale (no payout) but never has to pay anything out of pocket. Item price refund always comes from escrow.
2. Buyers always get item price back
On any approved return, buyer gets full item price refunded. Buyer's loss is forward shipping + protection fee + return shipping (~IDR 30,000-40,000 typical).
3. SEKEN keeps protection fee
The IDR 6,500 BPF is the price of dispute resolution service, kept whether the transaction smooths out or escalates.
4. Biteship is pass-through
SEKEN doesn't profit from return shipping. Buyer pays Biteship rate directly via aggregation (IDR 12-25k typical).
Five scenarios
Scenario 1, Smooth transaction
Outcome: No return requested, 24hr passes, order auto-completes.
| Party | Result |
|---|---|
| Buyer | Got the item, no refund |
| Seller | Receives item price |
| SEKEN | Keeps ~IDR 10,065 (BPF + markups) |
| Biteship | Keeps forward shipping |
Scenario 2, Seller fault (returned)
Trigger: Item not as described, fake, damaged, or wrong item sent. Buyer requests return within 24hr with evidence.
| Party | Result |
|---|---|
| Buyer | Refunded item price only |
| Seller | Nothing (item returned) |
| SEKEN | Keeps ~IDR 10,065 |
| Biteship | Keeps forward shipping + return shipping |
Buyer's loss: Forward shipping + BPF + return shipping (~30-40k typical).
Scenario 3, Lost in transit
Trigger: Biteship marks item lost, no delivery confirmation after extended timeout.
| Party | Result |
|---|---|
| Buyer | Refunded item price |
| Seller | Nothing |
| SEKEN | Keeps ~IDR 10,065 |
| Biteship | Forward shipping (claim back via SLA) |
Scenario 4, Buyer remorse (not allowed)
Trigger: Buyer changed mind, item doesn't fit, color looks different. Not a valid return reason by default.
| Party | Result |
|---|---|
| Buyer | No refund |
| Seller | Receives item price |
| SEKEN | Keeps ~IDR 10,065 |
| Biteship | Keeps forward shipping |
Future opt-in: "Return Plus" feature, buyer pays extra IDR 5,000-10,000 at checkout for 7-day no-questions returns. Pure margin for SEKEN.
Scenario 5, Low-value item (auto-approve)
Trigger: Item under IDR 50,000. Auto-approves refund without seller decision to reduce dispute friction on small claims.
| Party | Result |
|---|---|
| Buyer | Refunded automatically |
| Seller | Nothing |
| SEKEN | Keeps ~IDR 10,065 |
| Biteship | Keeps forward shipping |
Refund matrix
| Component | Refunded on approved return? | Why |
|---|---|---|
| Item price | ✅ Yes, full | Held in escrow until completion |
| Forward shipping | ❌ No | Already paid to Biteship |
| Buyer Protection Fee | ❌ No | SEKEN's service revenue |
| Return shipping | ❌ No | Buyer pays Biteship at return moment |
| Asuransi | ❌ No | Already paid to Biteship insurance |
Allowed return reasons
| Reason | Allowed? | Notes |
|---|---|---|
| Item not as described | ✅ | Photo evidence required |
| Counterfeit / fake | ✅ | Photo evidence required |
| Hidden damage not in photos | ✅ | Photo evidence required |
| Wrong item sent | ✅ | Photo evidence required |
| Buyer changed mind | ❌ | Not allowed by default |
| Doesn't fit | ❌ | Not allowed by default |
| Color looks different | ❌ | Not allowed by default |
Return shipping via Biteship
When return is approved, buyer sees auto-aggregated cheapest options:
○ GoSend (same-day) IDR 12,000 ✨ cheapest
○ JNE Reguler (2-3 days) IDR 18,000
○ J&T Express (2 days) IDR 22,000
[Pay & generate return label]
Biteship API picks cheapest per route. Label generated in-app. Buyer pays via same payment methods used at checkout.
Status: ✅ Live as of PS-313 (2026-05-12). Endpoint: POST /orders/:id/return-label in routes-orders.tsx. Idempotent, returns existing return_label_url if already generated. Reuses createBiteshipOrder with buyer as origin and seller as destination; persists return_label_url, return_tracking_no, and return_biteship_order_id to shipping_details.
Dispute escalation
If seller rejects return, the case escalates to ops:
Ops decision criteria:
- Photo evidence comparison (listing vs received)
- Chat history review
- Buyer purchase history (return rate, dispute rate)
- Seller reputation (review score, dispute history)
- Item category norms
Why this model works
For sellers
- 100% free, always
- Keep full listing price on smooth sales
- No frozen payouts, no surprise debits, no negative balances
- Lose only the sale if return is approved
For buyers
- Item price guaranteed back
- Cheapest possible return shipping (Biteship aggregation)
- Easy in-app return label generation
- Better return UX than any Indonesian marketplace
For SEKEN
- No chasing sellers for money we don't have
- Protection fee is clean revenue, not an insurance pool
- Biteship is pass-through (no P&L impact on shipping)
- Sustainable unit economics from day one
Comparison to Vinted
Same core model (free sellers, buyer pays return). SEKEN improves on Vinted by:
| Aspect | Vinted | SEKEN |
|---|---|---|
| Return window | 48 hours | 24 hours (reduces fraud) |
| Return shipping cost | €5-10 EU pricing | IDR 12-25k via Biteship aggregation |
| Cheapest option picker | Buyer figures it out | In-app aggregation |
| Framing | "Buyer protection insurance" | Honest "service fee" |
Brand voice on returns
Buyer-facing:
"Harga barang dijamin balik. Ongkir & service fee jalan terus, karena layanan dan kurir udah kerja."
Seller-facing:
"Gratis selamanya. Kalau ada return, kamu cuma kehilangan penjualan, bukan uang dari kantong."
Marketing positioning:
"Buyer protection beneran. Return paling murah di Indonesia, langsung dari app."
Future enhancements (not in scope for v1)
- Trust Score system (lower protection fee for proven sellers)
- Return Plus opt-in (7-day no-questions returns for +5-10k)
- Mandatory measurements + condition guide on listings
- Second Chance lane (relist instead of return)
- Reverse logistics network (pickup-on-next-delivery)
Where to look in the codebase
| What you want | Where it lives |
|---|---|
| Return request + reason enforcement | supabase/functions/server/interface/http/routes-orders.tsx, POST /orders/:id/request-return |
| Auto-approve threshold (IDR 50k) | routes-orders.tsx, AUTO_APPROVE_THRESHOLD = 50_000 constant before the seller-decision flow |
| Reverse label generation | routes-orders.tsx, POST /orders/:id/return-label |
| Admin decision endpoint | supabase/functions/server/interface/http/routes-admin-extended.tsx, PUT /admin/orders/:id/return-decision |
| Admin returns panel (React) | src/app/components/admin/ReturnRefundManager.tsx |
Next: Money Flow →