Payment forms

Manual, admin-managed payment methods (bank transfer, Pago Móvil, Zelle, …). The client reads the account details, pays out-of-band, then reports the operation values; an admin approves or rejects later. Paths are relative to the /api/v1 prefix; all routes require Authorization: Bearer {token}.

Forms appear in the order picker via Payment methods. Interactive online charges are under Payments. See also the order lifecycle.

See Common errors.

Endpoints

Method URI Role Description
GET /payment-forms any List active payment forms
GET /orders/{orderId}/payment/form any What to show/fill and how much to pay
POST /orders/{orderId}/payment/form any Report a manual payment

The interactive endpoints require the order to use the PAYMENT_FORM method, be in WAITING_FOR_PAYMENT, belong to the caller, and have a form associated.


GET /payment-forms

Lists active payment forms (ordered by sort_order, then name) for the order picker.

Response 200

{
  "forms": [
    {
      "id": 3,
      "name": "Transferencia BDV",
      "internal_name": "bdv_transfer",
      "category": "bank_transfer",
      "currency": "VES",
      "icon": "bank"
    }
  ]
}

category is one of pago_movil, binance, bank_transfer, zelle, other; currency is USD, VES, or USDT.


GET /orders/{orderId}/payment/form

Returns everything the client needs to pay: the form summary, the account details to display, the fields to fill, and the amount due. amount.usd is canonical; when the form settles in VES, a bs amount at the current BCV rate is included (referential — fixed when reported).

Response 200

{
  "form": {
    "id": 3,
    "name": "Transferencia BDV",
    "internal_name": "bdv_transfer",
    "category": "bank_transfer",
    "currency": "VES"
  },
  "display": [
    { "type": "text", "index": 0, "label": "Banco", "content": "Banco de Venezuela" },
    { "type": "text", "index": 1, "label": "Cuenta", "content": "0102-0000-00-0000000000" }
  ],
  "fields": [
    { "index": 2, "label": "NÂş de operaciĂłn", "required": true, "hint": "Ăšltimos 6 dĂ­gitos", "input_type": "numeric" }
  ],
  "amount": {
    "usd": 20.2,
    "currency": "VES",
    "bs": 740.0,
    "bcv_rate": 36.63
  }
}

amount.bs and amount.bcv_rate are present only for VES forms.

Errors

Status Body When
404 { "error": "NotFound", "message": "Orden no encontrada." } Unknown order, or not owned by the caller
422 { "error": "Unprocessable", "message": "…" } Order isn't PAYMENT_FORM, not WAITING_FOR_PAYMENT, or has no form

POST /orders/{orderId}/payment/form

Reports the manual payment. The values carry one entry per filled field; a per-field rule failure returns the standard 422 ValidationError envelope keyed by field index. The payment moves to PROCESSING (pending admin approval).

Request body

Field Type Required Rules
values array yes at least 1 entry
values[].index integer yes a field index from the form schema (unknown indexes are ignored)
values[].value string yes the reported value

Response 200

{
  "payment": {
    "id": 9,
    "status": "PROCESSING",
    "method": "PAYMENT_FORM",
    "internal_type": "form:bank_transfer",
    "reference": "A1B2C3D4E5F6",
    "amount_usd": 20.2,
    "amount_bs": 740.0,
    "currency": "VES"
  }
}

amount_bs is null for non-VES forms.

Errors

Status Body When
404 { "error": "NotFound", "message": "Orden no encontrada." } Unknown order, or not owned by the caller
422 { "error": "Unprocessable", "message": "…" } Order isn't PAYMENT_FORM/WAITING_FOR_PAYMENT, has no form, or there's no reportable charge
422 { "error": "ValidationError", "details": { "fieldErrors": { "2": ["…"] } } } A reported value failed the schema rules

Examples

# Show what to pay and how
curl /api/v1/orders/42/payment/form -H "Authorization: Bearer {client_token}"

# Report the bank-operation number
curl -X POST /api/v1/orders/42/payment/form \
  -H "Authorization: Bearer {client_token}" \
  -H "Content-Type: application/json" \
  -d '{"values": [{"index": 2, "value": "123456"}]}'