What P2P is

People depositing pay the customers who are withdrawing. One transfer closes both records.

Before

Everything ran through the central account

The depositor paid into the central account, which then paid the withdrawer in a second hop. The central account had to hold a float at all times, and every baht paid out was the merchant’s own money.

With P2P

The depositor pays the withdrawer directly

The platform matches someone depositing with someone withdrawing the same amount and lets them transfer between themselves. The central account only steps in when the match falls short.

How the money travels

The top route is the old one, the bottom route is P2P

Before — two hops through the central account

DepositorCentral accountWithdrawing customer

The central account has to keep a float sitting there

With P2P — direct, one hop

DepositorWithdrawing customer

This one transfer closes the deposit and the withdrawal together

When the two sides meet

Same row, same moment. Read across and you can see who is waiting on what.

Deposit side

Another system opens a deposit session for the depositor

Withdrawal side

The merchant creates a withdrawal; the amount is reserved

Deposit side

The platform matches them; the depositor sees the customer account and a QR

Withdrawal side

One leg opens for this depositor

Deposit side

Must transfer within 10 minutes from the registered account, then attach the slip

Withdrawal side

Waiting. Nothing has happened yet

Deposit side

The slip clears and the deposit order is credited

PAYMENT_PAID

Withdrawal side

This leg counts as funded

WITHDRAWAL_PARTIALLY_FUNDED

Deposit side

Done, as far as this depositor is concerned

Withdrawal side

Short of the amount, a new leg opens for the next person; once it is covered, the withdrawal closes

WITHDRAWAL_COMPLETED

One withdrawal, filled by several people

Legs open as people actually arrive rather than being split up front, so one withdrawal can end with a single depositor or with several.

WITHDRAWAL10,000 THB ACME-W-2026-000456 MATCH · ขา 14,000 THB PAYMENTผู้ฝาก A MATCH · ขา 23,500 THB PAYMENTผู้ฝาก B MATCH · ขา 32,500 THB PAYMENTUSER134 แต่ละขานับเวลาแยกกัน · payment 1 ใบ ผูกกับ match 1 ใบเสมอ

When the match falls short

Each side has its own way out, and neither is spelled out in the payload.

Deposit side

Falls back to the bank channel

With nobody to match, the platform switches to the bank channel within the same request and the same order. You still get one PAYMENT_PAID; deposit_type tells you which route it took.

Withdrawal side

The central account covers the gap

After 30 minutes unconfirmed with the amount still short, the central account transfers only the remainder through the bank. The withdrawal still ends as WITHDRAWAL_COMPLETED; summary.channel reads HYBRID.

When the depositor says they paid but the system has not seen it

That leg goes into dispute, and everything stays silent until someone decides it.

  1. 1

    The depositor reports a problem

    The leg is locked, stops counting down to expiry, and no webhook announces that a dispute was opened.

  2. 2

    A platform admin has to decide it

    The merchant cannot decide it, the platform does not resolve it automatically, and no SLA guarantees when it lands.

  3. 3

    The decision cannot be reversed

    Decided for the depositor, the deposit side gets PAYMENT_PAID while the withdrawal side stays silent until the record closes.

A leg closed by dispute resolution does not send WITHDRAWAL_PARTIALLY_FUNDED, unlike a leg that settles normally and announces every time. Totalling funded amounts from that event alone leaves one leg out.

What the merchant has to fund

THB_P2P credit is a pre-funded balance. Two things are debited from it.

The fee on every transaction

The payment is credited in full; the fee comes out of the credit separately.

What the central account transfers instead

Much larger than the fee, and absent from the webhook payload — reconcile it from balance history.

Running out of credit means you cannot create new transactions. The arithmetic is on THB_P2P credit

Webhooks P2P produces

One endpoint receives both sides; tell them apart by the event inside.

eventsidemeans
PAYMENT_PAIDDeposit sideA leg cleared, or an admin decided a dispute for the depositor. Post the deposit side here.
PAYMENT_FAILEDDeposit sideA duplicate slip — the only case that produces this event.
WITHDRAWAL_PARTIALLY_FUNDEDWithdrawal sideProgress report for a settled leg. Never post to your ledger from this.
WITHDRAWAL_COMPLETEDWithdrawal sideTerminal. The customer received the full amount, from depositors alone or with the central account covering the gap.
WITHDRAWAL_COMPLETED_PARTIALLYWithdrawal sideTerminal. The customer received part of it; the rest is refunded to the merchant.
WITHDRAWAL_REJECTWithdrawal sideTerminal. Nothing was paid out and the full amount is refunded.