/api/qmail/raida/payments/send

GET POST

Send a Payment Tell (tell_type 3) — a direct coin transfer over the Tell channel with no message body, only a 1-byte purpose code. The core funds a fresh single-use locker from the sender's wallet and tells the recipient's beacon RAIDA; the recipient's client claims the coins into its wallet automatically. Async: returns a task_id immediately.

Description

A payment tell is the money-moving counterpart of an email tell. There is no upload step and no manifest — the fixed 194-byte tell carries the sender identity (AN-authenticated), a timestamp, the funded locker key, and one purpose byte. The recipient's transaction log shows who paid, when, how much, and the purpose label (e.g. “Subscription payment”); nothing appears in their mail inbox. See the payment-tell wire format.

Primary use case — subscription payouts: a webserver holding subscriber mailbox addresses calls this endpoint once per member each month with purpose=0. Each member's client auto-claims the coins; the sender can later verify pickup by peeking the locker (empty = claimed).

Minimum Payment: 5000 CC — No Inbox Fee

Payment tells are exempt from the recipient's inbox fee (they carry no message), but a flat minimum of 5000 CC is enforced so the channel cannot spray dust-value notifications. Below-minimum amounts are rejected locally with HTTP 400, and by the beacon with ERROR_PAYMENT_INSUFFICIENT (168).

One Recipient Per Call

Exactly one recipient per payment tell — each payee gets their own funded locker. Paying N subscribers means N calls. Comma/semicolon-separated to lists are rejected.

Parameters

Parameter Type Required Description
to string Yes Recipient QMail address (or contact resolvable by the standard address parser). Exactly one recipient; lists are rejected with HTTP 400.
amount string (decimal CC) Yes Payment amount in CC, e.g. 5000 or 7500.25 (0.0001 CC granularity). Must be at least 5000 CC.
purpose integer 0–255 No Payment purpose code shown in the recipient's transaction log. Default 255 (unspecified). See the registry below.
wallet_path / wallet string No Wallet that funds the payment locker. Defaults to Default.
debug boolean No Per-request LOG_DEBUG verbosity (grep QMAIL-PAYMENT in main.log).

Purpose codes

CodeNameMeaning
0subscriptionSubscription payment
1invoiceInvoice payment
2gift_tipGift / tip
3refundRefund
4payrollPayroll
5purchasePurchase
255unspecifiedUnspecified

Response

Returns HTTP 200 immediately with a task_id; poll /api/system/tasks?id=<task_id>. The worker funds the locker, then sends the tell to the recipient's beacon RAIDA.

Task Poll — Accepted

{
  "status": "success",
  "task_id": "task_3fa2b911",
  "progress": 100,
  "message": "Payment tell accepted",
  "data": {
    "payment_id": "9f2ab3c4d5e6f7a8b9c0d1e2f3a4b5c6",
    "server_status": 250,
    "retry_queued": false,
    "recipient_sn": 4321,
    "amount_units": 500000000000
  }
}

Task Poll — Beacon Unreachable, Queued for Retry (still success)

The locker is already funded; the pending-tell retry worker re-sends automatically. This is not a failure — do not re-call /raida/payments/send, or the recipient will be paid twice.

{
  "status": "success",
  "task_id": "task_3fa2b911",
  "progress": 100,
  "message": "Payment locker funded; tell queued for retry",
  "data": {
    "payment_id": "9f2ab3c4d5e6f7a8b9c0d1e2f3a4b5c6",
    "retry_queued": true
  }
}

Errors

  • HTTP 400 — invalid to address, invalid amount, “Amount below minimum payment of 5000 CC”, or invalid purpose.
  • Task failed — insufficient wallet funds to fund the locker, or a permanent beacon rejection: ERROR_PAYMENT_INSUFFICIENT (168, below-minimum locker), ERROR_SENDER_BLACKLISTED (236, the recipient blacklisted this sender).
  • Temporary beacon conditions (ERROR_PAYMENT_PROCESSING, 167; network timeouts) end as the queued-for-retry success above.

Examples

# Monthly subscription payout loop (one call per member)
for ADDR in $(cat subscribers.txt); do
  curl -s "http://localhost:8081/api/qmail/raida/payments/send?to=$ADDR&amount=5000&purpose=0"
done

# Poll a payout task
curl "http://localhost:8081/api/system/tasks?id=<TASK_ID>"

Important Notes

How the Recipient Receives It

The recipient's beacon loop recognizes tell_type 3, skips the mail-download flow, claims the locker (13-of-25 consensus), grades the coins into the wallet, and records the payment in qmail_received_tells with its purpose and amount. Received payments are listed by /api/qmail/db/payments/list; a claim that failed (e.g. client offline mid-claim) can be re-driven manually with /api/qmail/raida/payments/claim.

Delivery Confirmation Without a Receipt Protocol

Peek the payment locker after sending: an empty locker means the recipient claimed it. The send is also recorded in the local qmail_sent_payments table with the payment GUID, recipient, amount, purpose, and locker key.