S
docs.syncra.money
Operations

Deal history and details (Deals)

The PayIn and PayOut UNION listing, deal details, filters, and pagination in the Syncra Merchant API V2

Managing and monitoring deals (Deals)

To keep payments and payouts under control, Syncra Merchant API V2 provides methods for retrieving detailed information about a specific deal and for listing (history) deals with flexible filtering, plus CSV export and aggregated turnover.


Deal details

GET /api/v1/p2p/merchant/deals/{deal_id}

Path parameters

NameTypeRequiredDescription
deal_idstring(UUID)YesThe system identifier of the deal (for example, 9512d99a-3bbc-4a32-acae-d6ad8bb7e32f).

Successful response example (200 OK)

The response is a MerchantDealInfo object (proto, 12 fields) in the top-level deal field (no data wrapper). The deal identifier is deal_id (NOT id). The payment page URL is payment_url (NOT payment_page_url).

{
  "deal": {
    "deal_id": "7ac148fe-19a3-45bb-b992-019fac55b721",
    "status": "COMPLETED",
    "amount": "250050",
    "currency": "RUB",
    "created_at": "2026-07-12T17:20:00Z",
    "client_id": "player_user_9921",
    "deal_type": "PAYIN",
    "updated_at": "2026-07-12T17:24:12Z",
    "payment_url": "https://checkout.syncra.money/pay/a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
    "target_requisite": "",
    "received_amount": "250050",
    "amount_match_status": "full"
  }
}

MerchantDealInfo fields (proto)

FieldTypeDescription
deal_idstring(UUID)Deal identifier. Always deal_id, not id.
statusstringStatus: OrderStatus (PayIn) or PayOutStatus (PayOut) — the full list is in the Status mapping reference.
amountint64The amount in minor units (kopecks/cents/satoshi).
currencystringISO 4217 currency code.
created_atstring(RFC3339)Deal creation time (UTC).
client_idstringThe payer's identifier in the merchant's system (may be empty).
deal_typestringDirection: "PAYIN" or "PAYOUT".
updated_atstring(RFC3339)Last update time (UTC).
payment_urlstringHosted payform URL ({checkout_base}/pay/{hash}). Populated for PayIn only; empty for PAYOUT.
target_requisitestringRecipient payment details (an echo of the payout request, unmasked). Populated for PAYOUT only; empty for PayIn.
received_amountint64The amount actually received from the payer (reconciliation data from the bank or provider). 0/empty until reconciliation reports back. PayIn only.
amount_match_statusstringAmount match result: full / partial / overpaid (strictly lowercase; partial = less than declared was received); empty if reconciliation did not run. PayIn only.

idempotency_key is not part of the MerchantDealInfo proto and is not returned in the response. It is an internal request field used only for deal-creation idempotency.


Deal listing (UNION)

A paginated history of payments and payouts with filtering by dates, statuses, and operation types. The listing is a union of two sources: inbound payments (p2p_orders, deal_type=PAYIN) and payouts (p2p_payouts, deal_type=PAYOUT) merged into a single chronological list (newest first).

GET /api/v1/p2p/merchant/deals

Query parameters

FieldTypeRequiredDescription
deal_typestringNoOperation type: "PAYIN" or "PAYOUT". Without the filter, both directions are returned.
statusesarrayNoDB status names (a repeated parameter, for example statuses=COMPLETED&statuses=EXPIRED). PayIn: INITIALIZED, ESCROW_LOCKED, PAYMENT_NOTIFIED, PAYMENT_VERIFIED, COMPLETED, EXPIRED, APPEALED, REFUND_PENDING, SPAM_REJECTED, SOFT_DISPUTED, CANCELLED; PayOut: INITIALIZED, MATCHED, UNASSIGNED, PROCESSING, COMPLETED, FAILED, EXPIRED.
created_afterstring(RFC3339)NoLower bound of creation time (inclusive).
created_beforestring(RFC3339)NoUpper bound of creation time (inclusive).
page_sizeint32NoItems per page (default 50, maximum 250).
page_tokenstringNoAn opaque next-page cursor from the previous response (next_page_token). An empty string = the first/last page (AIP-158).
merchant_idstring(UUID)NoAdvisory field: silently ignored (see the note below).

GET /deals?merchant_id=<any> (in the body or query) is silently ignored: the real scope is always determined by the HMAC identity of the signed token (claims-win). The merchant_id field is advisory for admin impersonation; under regular HMAC authentication the passed value (including a malformed one or another merchant's) does not affect the result and raises no error.

Response example (200 OK, live staging response)

{
  "data": [
    {
      "deal_id": "9512d99a-3bbc-4a32-acae-d6ad8bb7e32f",
      "status": "EXPIRED",
      "amount": "100000",
      "currency": "RUB",
      "created_at": "2026-08-23T19:04:28Z",
      "client_id": "",
      "deal_type": "PAYIN",
      "updated_at": "2026-08-23T19:14:34Z",
      "payment_url": "",
      "target_requisite": "",
      "received_amount": "0",
      "amount_match_status": ""
    },
    {
      "deal_id": "7e40a4f8-b4ec-406c-8bb1-1e1ab4949a2f",
      "status": "MATCHED",
      "amount": "96971",
      "currency": "RUB",
      "created_at": "2026-08-23T19:04:17Z",
      "client_id": "",
      "deal_type": "PAYOUT",
      "updated_at": "2026-08-23T19:04:17Z",
      "payment_url": "",
      "target_requisite": "2202201234567890",
      "received_amount": "0",
      "amount_match_status": ""
    }
  ],
  "next_page_token": "2026-08-23T19:04:17Z|7e40a4f8-b4ec-406c-8bb1-1e1ab4949a2f"
}

Response fields

FieldTypeDescription
dataMerchantDealInfo[]A page of deals; the element structure is identical to GET /deals/{deal_id}.
next_page_tokenstringThe next-page cursor. An empty string = the last page. Treat it as opaque — the format changes.

The listing is served in the single envelope {"data": [...], "next_page_token": ""} (like all Merchant API listings — see the Overview). The envelope carries no other fields: total_count exists only in the internal gRPC contract and is not exposed over HTTP — count the selection size from pages or turnover aggregates. payment_url is present only on PAYIN deals, target_requisite — only on PAYOUT deals (an unmasked echo of the recipient details from the payout request). received_amount / amount_match_status are populated only after deposit reconciliation (PayIn).

Pagination and edge cases

  • A malformed page_token → 400 Bad Request (problem+json, live response):
{
  "type": "about:blank",
  "title": "Bad Request",
  "status": 400,
  "detail": "{\"code\":3,\"message\":\"invalid page_token\",\"details\":[]}",
  "instance": "/api/v1/p2p-engine"
}
  • Unknown filter values (deal_type=BOGUS, statuses=NOT_A_STATUS) do not raise an error — a 200 is returned with empty data and next_page_token: "".
  • Another merchant's deal_id in GET /deals/{deal_id} → 404 Not Found (deal not found) — IDOR protection collapses "does not exist" and "someone else's" into a single response.

Deal statistics (planned)

The statistics endpoint is not implemented in the current API version. The POST /api/v1/p2p/merchant/deals/statistics method is absent from the gRPC specification and returns 404 Not Found until implemented. For aggregates use turnover, for export use CSV export. Watch the changelog for updates.

As an alternative, use GET /deals with the created_after / created_before and statuses filters, daily turnover, or CSV export, and aggregate the data on your side.

On this page