# Merchant Protocol

Date: 2026-09-05  
Status: Payment Protocol V1 merchant surface. IMPLEMENTED.

A central merchant service is not required.

```
Merchant
  → own Payment Service (LocalMerchant)
  → own / trusted Node
  → Decentralized Network
```

or

```
Merchant
  → Wallet
  → Public Node
```

Blockchain semantics do not change.

## Flow

1. `createInvoice` → canonical PaymentRequest + QR + URI
2. The customer wallet parses, displays, and signs the request
3. The signed tx goes to the node `/tx` or to P2P
4. The merchant verifies with `GET /payments/:paymentId` (own node)
5. The invoice is paid only after `FINALIZED` plus the amount policy

The local invoice map is not consensus state.

## Verification

The merchant checks:

- the transaction exists and is canonical
- recipient / chain / network
- payment bind (`tx.data`)
- amount: MATCH / UNDER / OVER
- block and `finalityProof`

Mempool = PENDING. Block without QC = INCLUDED. Gateway = OPTIONAL observation.

## Refunds

A new transfer. The `PAYMENT_REFUND` data field is optional metadata.

## Policy (application)

UNDERPAYMENT → not paid  
OVERPAYMENT → paid; excess is tracked  
MULTIPLE → more than one finalized tx for the same paymentId  
PARTIAL = underpayment

## POS webhook (application layer)

A POS device does not connect to a central payment company. The merchant runs
their own `merchant-pos` service:

1. `POST /v1/pos/devices` — register the device + `webhookUrl` (`apiKey`, `webhookSecret`)
2. `POST /v1/pos/invoices` — canonical PaymentRequest + QR
3. The customer wallet pays; the node is observed via `GET /payments/:id`
4. On status change, an HMAC-signed webhook is sent (`payment.finalized` only if the policy marks paid)

The webhook sets `authoritative: false`. The gateway is not authority.
Details: https://ibrese.com/docs/pos/
