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
| Name | Type | Required | Description |
|---|---|---|---|
deal_id | string(UUID) | Yes | The 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)
| Field | Type | Description |
|---|---|---|
deal_id | string(UUID) | Deal identifier. Always deal_id, not id. |
status | string | Status: OrderStatus (PayIn) or PayOutStatus (PayOut) — the full list is in the Status mapping reference. |
amount | int64 | The amount in minor units (kopecks/cents/satoshi). |
currency | string | ISO 4217 currency code. |
created_at | string(RFC3339) | Deal creation time (UTC). |
client_id | string | The payer's identifier in the merchant's system (may be empty). |
deal_type | string | Direction: "PAYIN" or "PAYOUT". |
updated_at | string(RFC3339) | Last update time (UTC). |
payment_url | string | Hosted payform URL ({checkout_base}/pay/{hash}). Populated for PayIn only; empty for PAYOUT. |
target_requisite | string | Recipient payment details (an echo of the payout request, unmasked). Populated for PAYOUT only; empty for PayIn. |
received_amount | int64 | The amount actually received from the payer (reconciliation data from the bank or provider). 0/empty until reconciliation reports back. PayIn only. |
amount_match_status | string | Amount 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/dealsQuery parameters
| Field | Type | Required | Description |
|---|---|---|---|
deal_type | string | No | Operation type: "PAYIN" or "PAYOUT". Without the filter, both directions are returned. |
statuses | array | No | DB 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_after | string(RFC3339) | No | Lower bound of creation time (inclusive). |
created_before | string(RFC3339) | No | Upper bound of creation time (inclusive). |
page_size | int32 | No | Items per page (default 50, maximum 250). |
page_token | string | No | An opaque next-page cursor from the previous response (next_page_token). An empty string = the first/last page (AIP-158). |
merchant_id | string(UUID) | No | Advisory 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
| Field | Type | Description |
|---|---|---|
data | MerchantDealInfo[] | A page of deals; the element structure is identical to GET /deals/{deal_id}. |
next_page_token | string | The 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 — a200is returned with emptydataandnext_page_token: "". - Another merchant's
deal_idinGET /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.