openapi: 3.1.0
info:
  title: Merqo Finance market API (DRAFT)
  version: 0.3.3-draft
  description: |-
    How a market offers Merqo Finance deferred payment to its buyers, and what Merqo Finance sends back to the market.

    Every call carries the market's signed token (its own key); every write carries an Idempotency-Key, and a repeat with the same key and body returns the first answer. Merqo Finance signs each callback it sends and publishes its public keys at GET /.well-known/finect-keys. Events can also be pulled with GET /v1/events. Amounts are in tiyin. Errors are returned in the Problem shape described in the components.
servers:
- url: https://{platformHost}
  description: Merqo Finance platform entry (pilot)
  variables:
    platformHost:
      default: platform.finect.example
- url: https://{standHost}
  description: 'Test stand for the market''s developers (row 16): every method on synthetic data plus the levers'
  variables:
    standHost:
      default: stand.finect.example
security:
- serviceToken: []
tags:
- name: buyer
  description: 'Rows 1, 3-9: the buyer''s deal (act.kind BUYER)'
- name: supplier
  description: 'Rows 2, 10, 12-14: the supplier, its consent per deal and its payouts (act.kind SUPPLIER)'
- name: events
  description: Callbacks and their pull fallback
- name: stand
  description: 'Row 16: test stand only'
paths:
  /v1/deferral-conditions:
    get:
      operationId: getDeferralConditions
      tags:
      - buyer
      summary: Row 1. Can this buyer pay this supplier with «Рассрочка Merqo Finance», and at what price for 15 and 30 days
      description: |
        Called when the basket shows the payment methods, once per supplier group. AVAILABLE carries both terms with the buyer's price (the market marks 15 days by default); UNAVAILABLE carries the reason and the market does not show «Рассрочка Merqo Finance» for this supplier: the supplier is not connected yet (IN_PROGRESS) or was rejected (SUPPLIER_NOT_CONNECTED), or is suspended, or a refusal code (OVERDUE_DEBT; a code with `reapplyAfterOn`; DEFERRAL_UNAVAILABLE without a date = the free Merqo Finance sum does not cover the deal; the cap sum is never returned). No answer (timeout, 5xx) = the market does not show the method (AC-11); the regular payment keeps working. Pure read: nothing is stored or reserved.
      parameters:
      - $ref: '#/components/parameters/CommonRequestId'
      - name: buyerInn
        in: query
        required: true
        schema:
          $ref: '#/components/schemas/DealsInn'
      - name: buyerMarketCompanyRef
        in: query
        required: true
        schema:
          $ref: '#/components/schemas/MarketRef'
        description: the buyer company id on the market
      - name: supplierMarketRef
        in: query
        required: true
        schema:
          $ref: '#/components/schemas/MarketRef'
      - name: orderAmountTiyin
        in: query
        required: true
        schema:
          $ref: '#/components/schemas/CommonMoneyTiyin'
      responses:
        '200':
          description: Available with two terms, or unavailable with the reason
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeferralConditions'
              examples:
                available:
                  value:
                    availability: AVAILABLE
                    terms:
                    - term: DAYS_15
                      priceTiyin: 1010000000
                    - term: DAYS_30
                      priceTiyin: 1030000000
                    unavailableReason: null
                    refusalCode: null
                    reapplyAfterOn: null
                fundingShort:
                  value:
                    availability: UNAVAILABLE
                    terms: []
                    unavailableReason: REFUSED
                    refusalCode: DEFERRAL_UNAVAILABLE
                    reapplyAfterOn: null
        '400':
          $ref: '#/components/responses/CommonBadRequest'
        '401':
          $ref: '#/components/responses/CommonUnauthorized'
        '403':
          $ref: '#/components/responses/CommonForbidden'
        '429':
          $ref: '#/components/responses/CommonTooManyRequests'
        '500':
          $ref: '#/components/responses/CommonInternalError'
        '503':
          $ref: '#/components/responses/CommonServiceUnavailable'
  /v1/market-deals/{marketDealRef}/supplier-consent:
    post:
      operationId: recordSupplierConsent
      tags:
      - supplier
      summary: 'WILL CHANGE: Row 2. The supplier accepted «Рассрочка Merqo Finance» on THIS deal in the order confirmation window'
      description: |
        The market shows the current terms (getCurrentSupplierTerms) with their version in the window where the supplier confirms the order the buyer sent with the instalment; «Принять» sends this call, then the supplier confirms the order as usual. Consent is per deal: no connection step, no account-owner rule. Kept with who, when, version and deal, never deleted. A version that is not the current one = 409 TERMS_VERSION_OUTDATED («условия обновились»): the market shows the new text and asks again. A supplier not CONNECTED = 409 SUPPLIER_NOT_CONNECTED; a suspended one = 409 SUPPLIER_SUSPENDED. Name and phone of the user are personal data: masked in every log line. A supplier who does not accept is not forced: no call; the market offers the buyer the regular payment.
      parameters:
      - $ref: '#/components/parameters/MarketDealRef'
      - $ref: '#/components/parameters/CommonIdempotencyKey'
      - $ref: '#/components/parameters/CommonRequestId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SupplierDealConsent'
      responses:
        '200':
          $ref: '#/components/responses/Ack'
        '400':
          $ref: '#/components/responses/CommonBadRequest'
        '401':
          $ref: '#/components/responses/CommonUnauthorized'
        '403':
          $ref: '#/components/responses/CommonForbidden'
        '409':
          $ref: '#/components/responses/CommonConflict'
        '422':
          $ref: '#/components/responses/CommonUnprocessableEntity'
        '500':
          $ref: '#/components/responses/CommonInternalError'
        '503':
          $ref: '#/components/responses/CommonServiceUnavailable'
  /v1/applications:
    post:
      operationId: createMarketApplication
      tags:
      - buyer
      summary: 'WILL CHANGE: Row 3. After the supplier confirmed the order: the application with the deal and the term; scoring starts'
      description: |
        Body = the deal (deals.yaml DealContext), the term the buyer picked in the basket, and the applicant data the scoring and the contract need (director PINFL, payer phone, market user id, language, delivery address; personal data: masked in every log line). Needs the supplier consent on this marketDealRef (row 2) first, else 409 SUPPLIER_CONSENT_MISSING. market-api stores the context and calls the deal module (deals.yaml createDealContext + createApplication; scoring BEFORE any contract): the answer is IN_REVIEW («ожидает решения») with the application number `dealId`, or REFUSED at once (admission) with the code and `reapplyAfterOn`, or UNAVAILABLE with DEFERRAL_UNAVAILABLE when the free Merqo Finance sum does not cover the deal (the market offers the regular payment). The decision comes later as APPLICATION_RESULT (row 4). One LIVE application per market deal: the same marketDealRef with the same body returns the same answer; with a different body = 409 CONTEXT_CONFLICT; the same Idempotency-Key with a different body = 409 IDEMPOTENCY_CONFLICT. A missing or invalid field (INN, IKPU) = 400 VALIDATION_FAILED naming it in Problem.errors (common.yaml); 422 is a business rule only. Answer within 2 s.
      parameters:
      - $ref: '#/components/parameters/CommonIdempotencyKey'
      - $ref: '#/components/parameters/CommonRequestId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MarketApplication'
            example:
              term: DAYS_15
              directorPinfl: '30000000000001'
              payerPhone: '+998900000001'
              marketUserRef: mu-501
              language: RU
              deliveryAddress: Synthetic city, Synthetic street 1
              context:
                marketDealRef: md-9001
                marketOrderNumber: ZK-100001
                buyerInn: '300000001'
                buyerMarketCompanyRef: mc-1001
                buyerFirstOrderOn: '2026-03-14'
                supplierMarketRef: ms-2001
                supplierInn: '300000002'
                supplierName: Synthetic Supply LLC
                lines:
                - name: Synthetic flour 50 kg
                  category: Bakery
                  ikpu: '10000000000000001'
                  quantity: '20'
                  unitPriceTiyin: 50000000
                orderAmountTiyin: 1000000000
                marketPercentBps: 300
                language: RU
                returnUrl: https://market.example/orders/ZK-100001
                occurredAt: '2026-10-05T09:00:00Z'
      responses:
        '200':
          description: In review, refused at once, or unavailable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApplicationAnswer'
              examples:
                inReview:
                  value:
                    marketDealRef: md-9001
                    dealId: dl-7001
                    result: IN_REVIEW
                    refusalCode: null
                    reapplyAfterOn: null
                unavailable:
                  value:
                    marketDealRef: md-9001
                    dealId: null
                    result: UNAVAILABLE
                    refusalCode: DEFERRAL_UNAVAILABLE
                    reapplyAfterOn: null
        '400':
          $ref: '#/components/responses/CommonBadRequest'
        '401':
          $ref: '#/components/responses/CommonUnauthorized'
        '403':
          $ref: '#/components/responses/CommonForbidden'
        '409':
          $ref: '#/components/responses/CommonConflict'
        '413':
          $ref: '#/components/responses/CommonPayloadTooLarge'
        '422':
          $ref: '#/components/responses/CommonUnprocessableEntity'
        '429':
          $ref: '#/components/responses/CommonTooManyRequests'
        '500':
          $ref: '#/components/responses/CommonInternalError'
        '503':
          $ref: '#/components/responses/CommonServiceUnavailable'
  /v1/applications/{dealId}/deferral-contract:
    get:
      operationId: getMarketDeferralContract
      tags:
      - buyer
      summary: Row 4. The deferral contract file of an approved application (re-read of the file in APPLICATION_RESULT)
      description: Body = deals.yaml DeferralContract (PDF, numbered by the deal). Not APPROVED = 409 WRONG_STATE; another market's deal = 404. The market's moderator loads it into Didox for the buyer to sign.
      parameters:
      - name: dealId
        in: path
        required: true
        schema:
          $ref: '#/components/schemas/CommonId'
      - $ref: '#/components/parameters/CommonRequestId'
      responses:
        '200':
          description: The contract file
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DealsDeferralContract'
        '401':
          $ref: '#/components/responses/CommonUnauthorized'
        '404':
          $ref: '#/components/responses/CommonNotFound'
        '409':
          $ref: '#/components/responses/CommonConflict'
        '500':
          $ref: '#/components/responses/CommonInternalError'
  /v1/applications/{dealId}/cancellation:
    post:
      operationId: cancelApplication
      tags:
      - buyer
      summary: 'Row 5. The application is withdrawn: the order is cancelled, or the buyer changed his mind before signing'
      description: 'dealId = the application number. Body = MarketCancelRequest: the reason (ORDER_CANCELLED, or BUYER_CHOSE_PREPAYMENT = the buyer gave the instalment up before signing; the market turns the order into a full prepayment, nothing is cancelled at the market) and who initiated it. Idempotent by key.'
      parameters:
      - name: dealId
        in: path
        required: true
        schema:
          $ref: '#/components/schemas/CommonId'
      - $ref: '#/components/parameters/CommonIdempotencyKey'
      - $ref: '#/components/parameters/CommonRequestId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MarketCancelRequest'
            example:
              reason: ORDER_CANCELLED
              initiatedBy: BUYER
              occurredAt: '2026-10-05T10:00:00Z'
      responses:
        '200':
          $ref: '#/components/responses/Ack'
        '400':
          $ref: '#/components/responses/CommonBadRequest'
        '401':
          $ref: '#/components/responses/CommonUnauthorized'
        '404':
          $ref: '#/components/responses/CommonNotFound'
        '409':
          $ref: '#/components/responses/CommonConflict'
        '500':
          $ref: '#/components/responses/CommonInternalError'
        '503':
          $ref: '#/components/responses/CommonServiceUnavailable'
  /v1/market-deals/{marketDealRef}/supplier-contract:
    post:
      operationId: postSupplierContractSigned
      tags:
      - buyer
      summary: 'WILL CHANGE: Row 6. The supplier signed the sale contract with our LLC in the market''s flow'
      description: With the approval and the buyer's signature this concludes the deal (status CONCLUDED). Body = deals.yaml SupplierContractSigned. Idempotent by key.
      parameters:
      - $ref: '#/components/parameters/MarketDealRef'
      - $ref: '#/components/parameters/CommonIdempotencyKey'
      - $ref: '#/components/parameters/CommonRequestId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DealsSupplierContractSigned'
            example:
              documentRef: SC-2026-000123
              signedAt: '2026-10-05T11:00:00Z'
      responses:
        '200':
          $ref: '#/components/responses/Ack'
        '400':
          $ref: '#/components/responses/CommonBadRequest'
        '401':
          $ref: '#/components/responses/CommonUnauthorized'
        '404':
          $ref: '#/components/responses/CommonNotFound'
        '409':
          $ref: '#/components/responses/CommonConflict'
        '500':
          $ref: '#/components/responses/CommonInternalError'
        '503':
          $ref: '#/components/responses/CommonServiceUnavailable'
  /v1/market-deals/{marketDealRef}/buyer-contract:
    post:
      operationId: postBuyerContractSigned
      tags:
      - buyer
      summary: Row 6. The buyer signed our deferral contract in Didox (the market's moderator loaded it there)
      description: |
        Only on an APPROVED application, else 409 WRONG_STATE. `documentRef` = the deferral contract number (its number in getMarketDeferralContract), else 422. With the supplier contract this concludes the deal (status CONCLUDED): the goods ship without prepayment. Idempotent by key.
      parameters:
      - $ref: '#/components/parameters/MarketDealRef'
      - $ref: '#/components/parameters/CommonIdempotencyKey'
      - $ref: '#/components/parameters/CommonRequestId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BuyerContractSigned'
            example:
              documentRef: DR-7001
              signedAt: '2026-10-05T12:00:00Z'
      responses:
        '200':
          $ref: '#/components/responses/Ack'
        '400':
          $ref: '#/components/responses/CommonBadRequest'
        '401':
          $ref: '#/components/responses/CommonUnauthorized'
        '404':
          $ref: '#/components/responses/CommonNotFound'
        '409':
          $ref: '#/components/responses/CommonConflict'
        '422':
          $ref: '#/components/responses/CommonUnprocessableEntity'
        '500':
          $ref: '#/components/responses/CommonInternalError'
        '503':
          $ref: '#/components/responses/CommonServiceUnavailable'
  /v1/market-deals/{marketDealRef}/events:
    post:
      operationId: postDealEvent
      tags:
      - buyer
      summary: 'WILL CHANGE: Rows 8 and 9. Shipped, delivered, act, invoice accepted by the buyer, replacement act, deal closed, dispute opened or resolved'
      description: |
        Body = deals.yaml MarketDealEvent. The act starts every term: the buyer's payment date and the supplier's 20 days. INVOICE_ACCEPTED (the buyer accepted the supplier's invoice, `invoiceRef` = its number) is the second condition of the payout. DEAL_CLOSED (24 hours after the act, or the buyer confirmed earlier) opens the supplier's payout once the invoice is accepted. DISPUTE_OPENED stops the buyer's term and freezes the payout; DISPUTE_RESOLVED with SUPPLIER resumes the term with a new date, REPLACEMENT waits for REPLACEMENT_ACT_SIGNED and restarts every term from it, RETURN annuls the deal. Idempotent by key. Out of order: market-api answers 200 (stored), holds an event the deal cannot apply yet and applies it in the order of `occurredAt`; an event still held after 24 h raises an alert in the Merqo Finance workplace.
      parameters:
      - $ref: '#/components/parameters/MarketDealRef'
      - $ref: '#/components/parameters/CommonIdempotencyKey'
      - $ref: '#/components/parameters/CommonRequestId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DealsMarketDealEvent'
            examples:
              act:
                value:
                  kind: ACT_SIGNED
                  occurredAt: '2026-10-07T15:00:00Z'
                  actRef: act-55001
                  invoiceRef: null
                  closeKind: null
                  disputeReason: null
                  disputeOutcome: null
              invoiceAccepted:
                value:
                  kind: INVOICE_ACCEPTED
                  occurredAt: '2026-10-07T16:00:00Z'
                  actRef: null
                  invoiceRef: INV-55001
                  closeKind: null
                  disputeReason: null
                  disputeOutcome: null
              closed:
                value:
                  kind: DEAL_CLOSED
                  occurredAt: '2026-10-08T15:00:00Z'
                  actRef: null
                  invoiceRef: null
                  closeKind: WINDOW_EXPIRED
                  disputeReason: null
                  disputeOutcome: null
              disputeOpened:
                value:
                  kind: DISPUTE_OPENED
                  occurredAt: '2026-10-07T18:00:00Z'
                  actRef: null
                  invoiceRef: null
                  closeKind: null
                  disputeReason: 'Synthetic: packaging damaged'
                  disputeOutcome: null
              disputeResolved:
                value:
                  kind: DISPUTE_RESOLVED
                  occurredAt: '2026-10-09T10:00:00Z'
                  actRef: null
                  invoiceRef: null
                  closeKind: null
                  disputeReason: null
                  disputeOutcome: SUPPLIER
      responses:
        '200':
          $ref: '#/components/responses/Ack'
        '400':
          $ref: '#/components/responses/CommonBadRequest'
        '401':
          $ref: '#/components/responses/CommonUnauthorized'
        '404':
          $ref: '#/components/responses/CommonNotFound'
        '409':
          $ref: '#/components/responses/CommonConflict'
        '500':
          $ref: '#/components/responses/CommonInternalError'
        '503':
          $ref: '#/components/responses/CommonServiceUnavailable'
  /v1/market-deals/{marketDealRef}/cancellation:
    post:
      operationId: postDealCancellation
      tags:
      - buyer
      summary: 'Row 5. The deal is cancelled: before or after acceptance, by whom'
      description: 'BEFORE_ACCEPTANCE cancels the deal (status CANCELLED, reason ORDER_CANCELLED). AFTER_ACCEPTANCE = 422 CANCEL_AFTER_ACT_NOT_SUPPORTED: a return after the act goes through the dispute outcome RETURN.'
      parameters:
      - $ref: '#/components/parameters/MarketDealRef'
      - $ref: '#/components/parameters/CommonIdempotencyKey'
      - $ref: '#/components/parameters/CommonRequestId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DealCancellation'
            example:
              stage: BEFORE_ACCEPTANCE
              cancelledBy: BUYER
              occurredAt: '2026-10-06T08:00:00Z'
      responses:
        '200':
          $ref: '#/components/responses/Ack'
        '400':
          $ref: '#/components/responses/CommonBadRequest'
        '401':
          $ref: '#/components/responses/CommonUnauthorized'
        '404':
          $ref: '#/components/responses/CommonNotFound'
        '409':
          $ref: '#/components/responses/CommonConflict'
        '422':
          $ref: '#/components/responses/CommonUnprocessableEntity'
        '500':
          $ref: '#/components/responses/CommonInternalError'
        '503':
          $ref: '#/components/responses/CommonServiceUnavailable'
  /v1/supplier-terms/current:
    get:
      operationId: getCurrentSupplierTerms
      tags:
      - supplier
      summary: 'WILL CHANGE: Row 10. The current terms of «Рассрочка Merqo Finance» for suppliers: text RU and UZ and the version'
      description: Both languages come in one answer; the market shows the one of its user in the order confirmation window, with the version, and sends that version with the consent (row 2).
      parameters:
      - $ref: '#/components/parameters/CommonRequestId'
      responses:
        '200':
          description: The current version
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SupplierTerms'
              example:
                version: '2026-10-01'
                textRu: Синтетический текст условий.
                textUz: Sintetik shartlar matni.
                publishedAt: '2026-10-01T00:00:00Z'
        '401':
          $ref: '#/components/responses/CommonUnauthorized'
        '500':
          $ref: '#/components/responses/CommonInternalError'
        '503':
          $ref: '#/components/responses/CommonServiceUnavailable'
  /v1/market-deals/{marketDealRef}/payout-quote:
    get:
      operationId: getMarketPayoutQuote
      tags:
      - supplier
      summary: 'WILL CHANGE: Row 12. Payout sums of one deal, computed by Merqo Finance'
      description: |
        Body = deals.yaml PayoutQuote. Merqo Finance computes every sum; the market shows them and never computes. Full payout = price minus the market fee, from day 20 after the act; early = full minus 1% of the price, before day 20. A payout is authorised only after the act AND the invoice accepted by the buyer (row 8 INVOICE_ACCEPTED). `blockReason` says why no request is possible now (no act, invoice not accepted, not closed, dispute open). The market re-reads this before its batch: a manual decision on a suspended supplier's request shows here as payoutState AUTHORISED or NOT_AUTHORISED with `notAuthorisedReason` (A17a, no separate message; text payout_manual_refused).
      parameters:
      - $ref: '#/components/parameters/MarketDealRef'
      - $ref: '#/components/parameters/CommonRequestId'
      responses:
        '200':
          description: The sums
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DealsPayoutQuote'
        '401':
          $ref: '#/components/responses/CommonUnauthorized'
        '404':
          $ref: '#/components/responses/CommonNotFound'
        '500':
          $ref: '#/components/responses/CommonInternalError'
        '503':
          $ref: '#/components/responses/CommonServiceUnavailable'
  /v1/market-deals/{marketDealRef}/payout-requests:
    post:
      operationId: requestMarketPayout
      tags:
      - supplier
      summary: 'WILL CHANGE: Row 13. Payout request with the sum shown to the supplier and «no open dispute»'
      description: |
        Body = deals.yaml PayoutRequest, answer = deals.yaml PayoutDecision. Merqo Finance checks the act, the invoice accepted by the buyer (else REFUSED_INVOICE_NOT_ACCEPTED), the closure, the flag, its own dispute events and the sum. AUTHORISED: the market pays from the shared account. SUM_MISMATCH: the current sum comes back, nothing is authorised (A18). MANUAL_REVIEW: the supplier is suspended (A17a). REFUSED_*: the reason (A19). The request day decides early or full; there is no separate choice. Same key with another body = 409 IDEMPOTENCY_CONFLICT.
      parameters:
      - $ref: '#/components/parameters/MarketDealRef'
      - $ref: '#/components/parameters/CommonIdempotencyKey'
      - $ref: '#/components/parameters/CommonRequestId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DealsPayoutRequest'
            example:
              shownAmountTiyin: 960000000
              noOpenDispute: true
              requestedAt: '2026-10-09T09:00:00Z'
      responses:
        '200':
          description: The decision on this request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DealsPayoutDecision'
        '400':
          $ref: '#/components/responses/CommonBadRequest'
        '401':
          $ref: '#/components/responses/CommonUnauthorized'
        '404':
          $ref: '#/components/responses/CommonNotFound'
        '409':
          $ref: '#/components/responses/CommonConflict'
        '500':
          $ref: '#/components/responses/CommonInternalError'
        '503':
          $ref: '#/components/responses/CommonServiceUnavailable'
  /v1/market-deals/{marketDealRef}/payout-result:
    post:
      operationId: postMarketPayoutResult
      tags:
      - supplier
      summary: 'WILL CHANGE: Row 14. The market paid the supplier (with the payment order number) or did not'
      description: Body = deals.yaml PayoutResult. There is no refund after a payout. The same result again with another Idempotency-Key = 200 Ack with duplicate true; a different result or sum on a deal already PAID = 409 PAYOUT_ALREADY_RECORDED.
      parameters:
      - $ref: '#/components/parameters/MarketDealRef'
      - $ref: '#/components/parameters/CommonIdempotencyKey'
      - $ref: '#/components/parameters/CommonRequestId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DealsPayoutResult'
            example:
              result: PAID
              amountTiyin: 960000000
              paymentOrderRef: '000451'
              paidOn: '2026-10-10'
              reason: null
      responses:
        '200':
          $ref: '#/components/responses/Ack'
        '400':
          $ref: '#/components/responses/CommonBadRequest'
        '401':
          $ref: '#/components/responses/CommonUnauthorized'
        '404':
          $ref: '#/components/responses/CommonNotFound'
        '409':
          $ref: '#/components/responses/CommonConflict'
        '500':
          $ref: '#/components/responses/CommonInternalError'
        '503':
          $ref: '#/components/responses/CommonServiceUnavailable'
  /v1/market-status-exports:
    post:
      operationId: postStatusExport
      tags:
      - buyer
      summary: 'Row 15 (PROVISIONAL: the market has not agreed to send it). Daily export of order statuses for reconciliation'
      description: No export by the agreed hour = an alert to the Merqo Finance accountant. Mismatches go to the daily reconciliation in the workplace, not back to the market.
      parameters:
      - $ref: '#/components/parameters/CommonIdempotencyKey'
      - $ref: '#/components/parameters/CommonRequestId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StatusExport'
            example:
              exportDate: '2026-10-09'
              items:
              - marketDealRef: md-9001
                marketOrderNumber: ZK-100001
                marketStage: SHIPMENT
                marketStatusCode: ACCEPTED
      responses:
        '200':
          $ref: '#/components/responses/Ack'
        '400':
          $ref: '#/components/responses/CommonBadRequest'
        '401':
          $ref: '#/components/responses/CommonUnauthorized'
        '409':
          $ref: '#/components/responses/CommonConflict'
        '413':
          $ref: '#/components/responses/CommonPayloadTooLarge'
        '500':
          $ref: '#/components/responses/CommonInternalError'
        '503':
          $ref: '#/components/responses/CommonServiceUnavailable'
  /v1/events:
    get:
      operationId: listMarketEvents
      tags:
      - events
      summary: 'Pull fallback of the callbacks (rows 4, 7, 11): every event Merqo Finance sent to this market, oldest first'
      description: Same envelopes as the callbacks. The market keeps the last nextCursor and asks again; an empty page = nothing new.
      parameters:
      - $ref: '#/components/parameters/CommonLimit'
      - $ref: '#/components/parameters/CommonCursor'
      - $ref: '#/components/parameters/CommonRequestId'
      responses:
        '200':
          description: A page of events
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MarketEventPage'
        '400':
          $ref: '#/components/responses/CommonBadRequest'
        '401':
          $ref: '#/components/responses/CommonUnauthorized'
        '500':
          $ref: '#/components/responses/CommonInternalError'
        '503':
          $ref: '#/components/responses/CommonServiceUnavailable'
  /v1/stand/levers:
    post:
      operationId: pullStandLever
      tags:
      - stand
      summary: 'Row 16. Test stand only: approve, refuse, sign the supplier or the buyer contract, suspend or resume a supplier, shift time'
      description: Exists only on the stand server; the pilot answers 404. All data on the stand is synthetic.
      parameters:
      - $ref: '#/components/parameters/CommonIdempotencyKey'
      - $ref: '#/components/parameters/CommonRequestId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StandLever'
            example:
              lever: APPROVE
              marketDealRef: md-9001
              supplierMarketRef: null
              refusalCode: null
              shiftHours: null
      responses:
        '200':
          $ref: '#/components/responses/Ack'
        '400':
          $ref: '#/components/responses/CommonBadRequest'
        '401':
          $ref: '#/components/responses/CommonUnauthorized'
        '404':
          $ref: '#/components/responses/CommonNotFound'
        '422':
          $ref: '#/components/responses/CommonUnprocessableEntity'
        '500':
          $ref: '#/components/responses/CommonInternalError'
webhooks:
  marketEvent:
    post:
      operationId: onMarketEvent
      tags:
      - events
      summary: 'Rows 4, 7, 11. Merqo Finance -> market: application result, deal status, supplier suspended or resumed'
      description: 'Signed callback (iss finect, bodySha256), one envelope per event, at least once: dedupe by eventId; apply DEAL_STATUS only by sequence.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MarketEventEnvelope'
      responses:
        '204':
          description: Received (any 2xx); anything else = Merqo Finance retries
components:
  securitySchemes:
    serviceToken:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: 'service-auth.yaml is the one source of iss, aud and kinds: the market token (class MARKET) has aud platform; callbacks carry iss finect and are body-bound.'
  parameters:
    MarketDealRef:
      name: marketDealRef
      in: path
      required: true
      description: 'The market''s internal deal id: the key of the deal at Merqo Finance (row 3).'
      schema:
        $ref: '#/components/schemas/MarketRef'
    CommonRequestId:
      name: X-Request-Id
      in: header
      required: false
      description: Set by the edge when absent; passed through every service and callback; echoed in every response and in Problem.requestId.
      schema:
        type: string
        minLength: 1
        maxLength: 128
        pattern: ^[A-Za-z0-9._-]+$
    CommonIdempotencyKey:
      name: Idempotency-Key
      in: header
      required: true
      description: Client-chosen key, unique per logical operation of this caller. See semantics 3 above.
      schema:
        type: string
        minLength: 1
        maxLength: 128
        pattern: ^[\x21-\x7E]+$
    CommonLimit:
      name: limit
      in: query
      required: false
      description: Page size. A list operation that pages takes both Limit and Cursor.
      schema:
        type: integer
        minimum: 1
        maximum: 200
        default: 50
    CommonCursor:
      name: cursor
      in: query
      required: false
      description: Opaque cursor from the previous page (`nextCursor`); absent = first page.
      schema:
        $ref: '#/components/schemas/CommonCursor'
  responses:
    Ack:
      description: 'Stored (or already stored with the same key: `duplicate` true)'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Ack'
    CommonBadRequest:
      description: Malformed request; code VALIDATION_FAILED, `errors` names the fields.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/CommonXRequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/CommonProblem'
    CommonUnauthorized:
      description: No or invalid credentials (service-auth); code UNAUTHORIZED.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/CommonXRequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/CommonProblem'
    CommonForbidden:
      description: Authenticated but not allowed this action (e.g. publish allowlist). Another company's object is 404, never 403.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/CommonXRequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/CommonProblem'
    CommonTooManyRequests:
      description: Rate limit; code RATE_LIMITED; wait Retry-After seconds.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/CommonXRequestId'
        Retry-After:
          $ref: '#/components/headers/CommonRetryAfter'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/CommonProblem'
    CommonInternalError:
      description: Unexpected failure; code INTERNAL. Safe to retry with the same Idempotency-Key.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/CommonXRequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/CommonProblem'
    CommonServiceUnavailable:
      description: A dependency is down; code UNAVAILABLE; wait Retry-After seconds and retry with the same key.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/CommonXRequestId'
        Retry-After:
          $ref: '#/components/headers/CommonRetryAfter'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/CommonProblem'
    CommonConflict:
      description: IDEMPOTENCY_CONFLICT (same key, different payload) or a state conflict named by `code`.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/CommonXRequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/CommonProblem'
    CommonUnprocessableEntity:
      description: Well-formed but refused by a business rule; `code` names the rule.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/CommonXRequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/CommonProblem'
    CommonPayloadTooLarge:
      description: Body over the edge limit; code PAYLOAD_TOO_LARGE.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/CommonXRequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/CommonProblem'
    CommonNotFound:
      description: Not found, or not the caller's (scope inside the query).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/CommonXRequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/CommonProblem'
  schemas:
    MarketRef:
      type: string
      description: An id minted by the market (deal, company, supplier); opaque to Merqo Finance.
      minLength: 1
      maxLength: 128
      pattern: ^[A-Za-z0-9._:-]+$
    TermPrice:
      type: object
      required:
      - term
      - priceTiyin
      properties:
        term:
          $ref: '#/components/schemas/DealsTerm'
        priceTiyin:
          $ref: '#/components/schemas/CommonMoneyTiyin'
          description: 'what the buyer pays by the payment date: the order sum plus 1% (15 days) or 3% (30 days), rounded down to the tiyin'
    DeferralConditions:
      type: object
      required:
      - availability
      - terms
      - unavailableReason
      - refusalCode
      - reapplyAfterOn
      properties:
        availability:
          type: string
          enum:
          - AVAILABLE
          - UNAVAILABLE
        terms:
          type: array
          maxItems: 2
          items:
            $ref: '#/components/schemas/TermPrice'
          description: both terms when AVAILABLE; empty when UNAVAILABLE
        unavailableReason:
          type:
          - string
          - 'null'
          enum:
          - SUPPLIER_NOT_CONNECTED
          - SUPPLIER_SUSPENDED
          - REFUSED
          - null
          description: null when AVAILABLE; SUPPLIER_NOT_CONNECTED = connection IN_PROGRESS or REJECTED (the underwriter checks the supplier); REFUSED = see refusalCode. The supplier also consents per deal (row 2)
        refusalCode:
          anyOf:
          - $ref: '#/components/schemas/DecisionsRefusalCode'
          - type: 'null'
          description: 'with REFUSED: OVERDUE_DEBT, a code with reapplyAfterOn, or DEFERRAL_UNAVAILABLE without a date (free Merqo Finance sum short)'
        reapplyAfterOn:
          type:
          - string
          - 'null'
          format: date
          description: «подать снова можно после»; null unless the code carries a date
    DealCancellation:
      type: object
      required:
      - stage
      - cancelledBy
      - occurredAt
      properties:
        stage:
          type: string
          enum:
          - BEFORE_ACCEPTANCE
          - AFTER_ACCEPTANCE
        cancelledBy:
          $ref: '#/components/schemas/Initiator'
        occurredAt:
          $ref: '#/components/schemas/CommonTimestamp'
    SupplierDealConsent:
      type: object
      required:
      - supplierMarketRef
      - supplierInn
      - acceptedBy
      - acceptedAt
      - termsVersion
      properties:
        supplierMarketRef:
          $ref: '#/components/schemas/MarketRef'
        supplierInn:
          $ref: '#/components/schemas/DealsInn'
        acceptedBy:
          $ref: '#/components/schemas/AccountUser'
        acceptedAt:
          $ref: '#/components/schemas/CommonTimestamp'
        termsVersion:
          type: string
          minLength: 1
          maxLength: 32
          description: the version shown in the window (getCurrentSupplierTerms)
    MarketApplication:
      type: object
      additionalProperties: false
      required:
      - context
      - term
      - directorPinfl
      - payerPhone
      - marketUserRef
      - language
      - deliveryAddress
      properties:
        context:
          $ref: '#/components/schemas/DealsDealContext'
        term:
          $ref: '#/components/schemas/DealsTerm'
        directorPinfl:
          type: string
          pattern: ^[0-9]{14}$
          description: PINFL of the buyer company director; personal data, masked in logs
        payerPhone:
          type: string
          pattern: ^\+998[0-9]{9}$
          description: phone of the payer at the buyer; personal data, masked in logs (last 4 kept)
        marketUserRef:
          $ref: '#/components/schemas/MarketRef'
          description: the market id of the user who sent the order
        language:
          type: string
          enum:
          - RU
          - UZ
          description: the buyer language for texts and the contract
        deliveryAddress:
          type: string
          minLength: 1
          maxLength: 512
    Initiator:
      type: string
      description: who initiated a cancellation
      enum:
      - BUYER
      - SUPPLIER
      - MARKET
    MarketCancelRequest:
      type: object
      additionalProperties: false
      required:
      - reason
      - initiatedBy
      - occurredAt
      properties:
        reason:
          $ref: '#/components/schemas/DealsCancelReason'
        initiatedBy:
          $ref: '#/components/schemas/Initiator'
        occurredAt:
          $ref: '#/components/schemas/CommonTimestamp'
    ApplicationAnswer:
      type: object
      required:
      - marketDealRef
      - dealId
      - result
      - refusalCode
      - reapplyAfterOn
      properties:
        marketDealRef:
          $ref: '#/components/schemas/MarketRef'
        dealId:
          anyOf:
          - $ref: '#/components/schemas/CommonId'
          - type: 'null'
          description: the application number; null when UNAVAILABLE
        result:
          type: string
          enum:
          - IN_REVIEW
          - REFUSED
          - UNAVAILABLE
        refusalCode:
          anyOf:
          - $ref: '#/components/schemas/DecisionsRefusalCode'
          - type: 'null'
          description: 'with REFUSED: the admission code; with UNAVAILABLE: DEFERRAL_UNAVAILABLE'
        reapplyAfterOn:
          type:
          - string
          - 'null'
          format: date
    BuyerContractSigned:
      type: object
      additionalProperties: false
      required:
      - documentRef
      - signedAt
      properties:
        documentRef:
          type: string
          minLength: 1
          maxLength: 64
          description: the deferral contract number
        signedAt:
          $ref: '#/components/schemas/CommonTimestamp'
    SupplierTerms:
      type: object
      required:
      - version
      - textRu
      - textUz
      - publishedAt
      properties:
        version:
          type: string
          minLength: 1
          maxLength: 32
        textRu:
          type: string
        textUz:
          type: string
        publishedAt:
          $ref: '#/components/schemas/CommonTimestamp'
    AccountUser:
      type: object
      required:
      - role
      - fullName
      - phone
      properties:
        role:
          type: string
          enum:
          - OWNER
          - MANAGER
          - OBSERVER
          description: role in the supplier's market account (recorded; any role that may confirm orders may accept)
        fullName:
          type: string
          minLength: 1
          maxLength: 256
          description: 'personal data: masked in logs'
        phone:
          type: string
          pattern: ^\+998[0-9]{9}$
          description: 'personal data: masked in logs (last 4 kept)'
    StatusExportItem:
      type: object
      required:
      - marketDealRef
      - marketOrderNumber
      - marketStage
      - marketStatusCode
      properties:
        marketDealRef:
          $ref: '#/components/schemas/MarketRef'
        marketOrderNumber:
          type: string
          maxLength: 64
        marketStage:
          type: string
          maxLength: 64
          description: the market's own stage code (its list)
        marketStatusCode:
          type: string
          maxLength: 64
          description: the market's own status code (its list, not a Merqo Finance code)
    StatusExport:
      type: object
      required:
      - exportDate
      - items
      properties:
        exportDate:
          type: string
          format: date
        items:
          type: array
          maxItems: 100000
          items:
            $ref: '#/components/schemas/StatusExportItem'
    StandLever:
      type: object
      required:
      - lever
      - marketDealRef
      - supplierMarketRef
      - refusalCode
      - shiftHours
      properties:
        lever:
          type: string
          enum:
          - APPROVE
          - REFUSE
          - SIGN_SUPPLIER_CONTRACT
          - SIGN_BUYER_CONTRACT
          - CONNECT_SUPPLIER
          - REJECT_SUPPLIER
          - SUSPEND_SUPPLIER
          - RESUME_SUPPLIER
          - SHIFT_TIME
        marketDealRef:
          anyOf:
          - $ref: '#/components/schemas/MarketRef'
          - type: 'null'
          description: the deal the lever acts on; null for SHIFT_TIME and the supplier levers
        supplierMarketRef:
          anyOf:
          - $ref: '#/components/schemas/MarketRef'
          - type: 'null'
          description: with the supplier levers CONNECT_SUPPLIER, REJECT_SUPPLIER, SUSPEND_SUPPLIER, RESUME_SUPPLIER
        refusalCode:
          anyOf:
          - $ref: '#/components/schemas/DecisionsRefusalCode'
          - type: 'null'
          description: with REFUSE
        shiftHours:
          type:
          - integer
          - 'null'
          minimum: 1
          maximum: 2160
          description: with SHIFT_TIME
    Ack:
      type: object
      required:
      - receivedAt
      - duplicate
      properties:
        receivedAt:
          $ref: '#/components/schemas/CommonTimestamp'
        duplicate:
          type: boolean
          description: 'true when this key was already stored: nothing changed twice'
    ApplicationResultEvent:
      type: object
      description: 'Row 4: the decision, on every change. `result` is IN_REVIEW, APPROVED or REFUSED (the deals.yaml values NOT_ISSUED and AWAITING_SIGNATURE are not sent on the market path). APPROVED carries the deferral contract file; the market''s moderator loads it into Didox.'
      required:
      - dealId
      - marketDealRef
      - marketOrderNumber
      - result
      - term
      - priceTiyin
      - refusalCode
      - refusalTextRu
      - refusalTextUz
      - companyLimitTiyin
      - reapplyAfterOn
      - decidedAt
      - deferralContract
      properties:
        dealId:
          $ref: '#/components/schemas/CommonId'
          description: the Merqo Finance deal = the application number
        marketDealRef:
          $ref: '#/components/schemas/MarketRef'
        marketOrderNumber:
          type: string
          maxLength: 64
          description: the deal number ZK- shown to people
        result:
          $ref: '#/components/schemas/DealsApplicationResult'
        term:
          anyOf:
          - $ref: '#/components/schemas/DealsTerm'
          - type: 'null'
          description: the term the buyer picked; null before that
        priceTiyin:
          $ref: '#/components/schemas/CommonMoneyTiyinOrNull'
          description: the buyer's price for that term
        refusalCode:
          anyOf:
          - $ref: '#/components/schemas/DecisionsRefusalCode'
          - type: 'null'
          description: 'with REFUSED: one of the six codes; texts by code in texts/market-api.texts.json'
        refusalTextRu:
          type:
          - string
          - 'null'
          description: 'with REFUSED: the text of the code (texts/market-api.texts.json), date filled in'
        refusalTextUz:
          type:
          - string
          - 'null'
        companyLimitTiyin:
          $ref: '#/components/schemas/CommonMoneyTiyinOrNull'
          description: 'with REFUSED: the company limit the order did not fit; whether and how to show it is the market''s choice. null otherwise (APPROVED shows «одобрен лимит» without a sum)'
        reapplyAfterOn:
          type:
          - string
          - 'null'
          format: date
          description: with REFUSED where the code carries a date
        decidedAt:
          $ref: '#/components/schemas/CommonTimestampOrNull'
          description: date and time of the decision; null while IN_REVIEW
        deferralContract:
          anyOf:
          - $ref: '#/components/schemas/DealsDeferralContract'
          - type: 'null'
          description: 'with APPROVED: the contract file; null otherwise'
    SupplierConnectionEvent:
      type: object
      description: 'Row 11: the supplier connection status (IN_PROGRESS while the underwriter checks the supplier, then CONNECTED or REJECTED) and suspension or resumption by Merqo Finance. Only CONNECTED makes the method available for this supplier.'
      required:
      - supplierMarketRef
      - state
      - changedAt
      properties:
        supplierMarketRef:
          $ref: '#/components/schemas/MarketRef'
        state:
          type: string
          enum:
          - IN_PROGRESS
          - CONNECTED
          - REJECTED
          - SUSPENDED
          description: IN_PROGRESS = the check runs, the market shows «подключение в процессе»; CONNECTED = connected or resumed; REJECTED = not connected, neutral plaque; SUSPENDED = the method disappears for this supplier
        changedAt:
          $ref: '#/components/schemas/CommonTimestamp'
    MarketEventEnvelope:
      type: object
      description: One event to the market (callback body and pull item). Exactly one of the three bodies is set, the one `kind` names.
      required:
      - eventId
      - kind
      - occurredAt
      - applicationResult
      - dealStatus
      - supplierConnection
      properties:
        eventId:
          $ref: '#/components/schemas/CommonId'
        kind:
          type: string
          enum:
          - APPLICATION_RESULT
          - DEAL_STATUS
          - SUPPLIER_CONNECTION
        occurredAt:
          $ref: '#/components/schemas/CommonTimestamp'
        applicationResult:
          anyOf:
          - $ref: '#/components/schemas/ApplicationResultEvent'
          - type: 'null'
        dealStatus:
          anyOf:
          - $ref: '#/components/schemas/DealsDealStatusEvent'
          - type: 'null'
          description: 'row 7: the market status of the deal'
        supplierConnection:
          anyOf:
          - $ref: '#/components/schemas/SupplierConnectionEvent'
          - type: 'null'
    MarketEventPage:
      type: object
      required:
      - items
      - nextCursor
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/MarketEventEnvelope'
        nextCursor:
          $ref: '#/components/schemas/CommonNextCursor'
    DealsInn:
      type: string
      description: 9 digits (legal entity) or 14 (individual entrepreneur). An INN identifies a company; logged in clear.
      pattern: ^([0-9]{9}|[0-9]{14})$
    CommonMoneyTiyin:
      type: integer
      format: int64
      description: Money in whole tiyin (1 sum = 100 tiyin). Never a float. JS-safe range.
      minimum: 0
      maximum: 9007199254740991
    CommonProblem:
      type: object
      description: RFC 9457 problem details + Merqo Finance `code` and `requestId`. `title` is the HTTP reason phrase, not a user text.
      required:
      - type
      - title
      - status
      - detail
      - instance
      - code
      - requestId
      - errors
      properties:
        type:
          type: string
          format: uri-reference
          description: about:blank unless a problem type page exists
        title:
          type: string
        status:
          type: integer
          minimum: 400
          maximum: 599
        detail:
          type:
          - string
          - 'null'
          description: developer text; never personal data
        instance:
          type:
          - string
          - 'null'
        code:
          $ref: '#/components/schemas/CommonCode'
        requestId:
          type: string
          description: echo of X-Request-Id
        errors:
          type:
          - array
          - 'null'
          description: field errors on 400/422; null otherwise
          items:
            $ref: '#/components/schemas/CommonFieldError'
    CommonCode:
      type: string
      description: Machine code, UPPER_SNAKE. Display texts (ru, uz) live apart from the API, never inside it (tester Q04).
      pattern: ^[A-Z][A-Z0-9_]*$
    CommonFieldError:
      type: object
      required:
      - path
      - code
      properties:
        path:
          type: string
          description: JSON pointer of the offending field in the request, e.g. /orderLines/0/ikpu
        code:
          $ref: '#/components/schemas/CommonCode'
    CommonId:
      type: string
      description: Opaque id minted by the owning service. Never an INN, PINFL, phone or a database sequence number.
      pattern: ^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$
    DealsDeferralContract:
      type: object
      additionalProperties: false
      required:
      - number
      - dealId
      - issuedAt
      - buyerInn
      - orderAmountTiyin
      - priceTiyin
      - term
      - format
      - documentBase64
      properties:
        number:
          type: string
          description: the contract number = Deal.deferralContractNumber (numbered by the deal)
        dealId:
          $ref: '#/components/schemas/CommonId'
        issuedAt:
          $ref: '#/components/schemas/CommonTimestamp'
        buyerInn:
          $ref: '#/components/schemas/DealsInn'
        orderAmountTiyin:
          $ref: '#/components/schemas/CommonMoneyTiyin'
        priceTiyin:
          $ref: '#/components/schemas/CommonMoneyTiyin'
        term:
          $ref: '#/components/schemas/DealsTerm'
        format:
          type: string
          enum:
          - PDF
          description: the document format; PDF = application/pdf
        documentBase64:
          type: string
          contentEncoding: base64
          description: the document itself
    CommonTimestamp:
      type: string
      format: date-time
      description: UTC instant, ISO-8601 with Z. Local time is a display matter of the client.
      pattern: Z$
    DealsTerm:
      type: string
      description: 'v1 terms: DAYS_15 = 15 days for 1%, DAYS_30 = 30 days for 3%. Extension is off in v1.'
      enum:
      - DAYS_15
      - DAYS_30
    DealsSupplierContractSigned:
      type: object
      additionalProperties: false
      required:
      - documentRef
      - signedAt
      properties:
        documentRef:
          type: string
          description: number of the supplier contract in the market flow
        signedAt:
          $ref: '#/components/schemas/CommonTimestamp'
    DealsMarketDealEvent:
      type: object
      additionalProperties: false
      required:
      - kind
      - occurredAt
      - actRef
      - invoiceRef
      - closeKind
      - disputeReason
      - disputeOutcome
      properties:
        kind:
          type: string
          enum:
          - SHIPPED
          - DELIVERED
          - ACT_SIGNED
          - REPLACEMENT_ACT_SIGNED
          - INVOICE_ACCEPTED
          - DEAL_CLOSED
          - DISPUTE_OPENED
          - DISPUTE_RESOLVED
        occurredAt:
          $ref: '#/components/schemas/CommonTimestamp'
        actRef:
          type:
          - string
          - 'null'
          description: act reference for ACT_SIGNED and REPLACEMENT_ACT_SIGNED; null otherwise
        invoiceRef:
          type:
          - string
          - 'null'
          maxLength: 64
          description: the supplier invoice number for INVOICE_ACCEPTED (the buyer accepted it); null otherwise
        closeKind:
          type:
          - string
          - 'null'
          enum:
          - CONFIRMED_BY_BUYER
          - WINDOW_EXPIRED
          - null
          description: for DEAL_CLOSED; null otherwise
        disputeReason:
          type:
          - string
          - 'null'
          maxLength: 500
          description: the buyer's reason as the market records it, for DISPUTE_OPENED; null otherwise
        disputeOutcome:
          type:
          - string
          - 'null'
          enum:
          - SUPPLIER
          - REPLACEMENT
          - RETURN
          - null
          description: for DISPUTE_RESOLVED; null otherwise
    DealsPayoutQuote:
      type: object
      description: |
        Sum = price - market % (from day 20) or price - market % - 1% of the price (earlier; Merqo Finance keeps the 1%), the 1% rounded DOWN in the supplier's favour. Price = the goods price `orderAmountTiyin` (never the buyer price with our 1% or 3%); market % = DealContext.marketPercentBps of it, rounded DOWN to the tiyin like the 1% (the supplier's favour). Day 20 counts from the act.
      required:
      - dealId
      - dealClosed
      - windowEndsAt
      - blockReason
      - payoutState
      - earlyAmountTiyin
      - fullAmountTiyin
      - fullOn
      - authorisedAmountTiyin
      - notAuthorisedReason
      properties:
        dealId:
          $ref: '#/components/schemas/CommonId'
        dealClosed:
          type: boolean
          description: act + 24-hour window over and the market closed the deal
        windowEndsAt:
          $ref: '#/components/schemas/CommonTimestampOrNull'
          description: act + 24 calendar hours; null before the act
        blockReason:
          type:
          - string
          - 'null'
          enum:
          - NO_ACT
          - INVOICE_NOT_ACCEPTED
          - NOT_CLOSED
          - DISPUTE_OPEN
          - null
          description: why no payout can be requested now; null when it can (act + invoice accepted by the buyer + closed + no dispute)
        payoutState:
          $ref: '#/components/schemas/DealsPayoutState'
        earlyAmountTiyin:
          $ref: '#/components/schemas/CommonMoneyTiyinOrNull'
          description: null when the deal is not closed or day 20 has come
        fullAmountTiyin:
          $ref: '#/components/schemas/CommonMoneyTiyinOrNull'
        fullOn:
          type:
          - string
          - 'null'
          format: date
          description: day 20 from the act
        authorisedAmountTiyin:
          $ref: '#/components/schemas/CommonMoneyTiyinOrNull'
          description: set once AUTHORISED
        notAuthorisedReason:
          type:
          - string
          - 'null'
          description: the Product owner's reason on NOT_AUTHORISED; null otherwise
    CommonTimestampOrNull:
      type:
      - string
      - 'null'
      format: date-time
      description: Timestamp, or null = no value.
      pattern: Z$
    DealsPayoutState:
      type: string
      description: |
        The supplier payout state. MANUAL_REVIEW = the supplier is suspended, a request waits for a manual decision by Merqo Finance; NOT_AUTHORISED = Merqo Finance refused it with a reason.
      enum:
      - WAITING_REQUEST
      - REQUESTED_EARLY
      - REQUESTED_FULL
      - MANUAL_REVIEW
      - AUTHORISED
      - NOT_AUTHORISED
      - PAID
    CommonMoneyTiyinOrNull:
      type:
      - integer
      - 'null'
      format: int64
      description: MoneyTiyin, or null = no value.
      minimum: 0
      maximum: 9007199254740991
    DealsPayoutRequest:
      type: object
      additionalProperties: false
      required:
      - shownAmountTiyin
      - noOpenDispute
      - requestedAt
      properties:
        shownAmountTiyin:
          $ref: '#/components/schemas/CommonMoneyTiyin'
        noOpenDispute:
          type: boolean
          description: 'the market''s flag: no open dispute on this deal'
        requestedAt:
          $ref: '#/components/schemas/CommonTimestamp'
    DealsPayoutDecision:
      type: object
      required:
      - outcome
      - currentAmountTiyin
      - quote
      properties:
        outcome:
          type: string
          enum:
          - AUTHORISED
          - REFUSED_OPEN_DISPUTE
          - REFUSED_NOT_CLOSED
          - REFUSED_INVOICE_NOT_ACCEPTED
          - SUM_MISMATCH
          - MANUAL_REVIEW
        currentAmountTiyin:
          $ref: '#/components/schemas/CommonMoneyTiyinOrNull'
          description: the current sum, always set on SUM_MISMATCH
        quote:
          $ref: '#/components/schemas/DealsPayoutQuote'
    DealsPayoutResult:
      type: object
      additionalProperties: false
      required:
      - result
      - amountTiyin
      - paymentOrderRef
      - paidOn
      - reason
      properties:
        result:
          type: string
          enum:
          - PAID
          - NOT_PAID
        amountTiyin:
          $ref: '#/components/schemas/CommonMoneyTiyin'
        paymentOrderRef:
          type:
          - string
          - 'null'
        paidOn:
          type:
          - string
          - 'null'
          format: date
        reason:
          type:
          - string
          - 'null'
          description: for NOT_PAID
    CommonCursor:
      type: string
      description: Opaque page cursor; the client never parses or builds it.
      minLength: 1
      maxLength: 512
    DecisionsRefusalCode:
      type: string
      description: |
        The one source of the refusal codes: the deal, market and buyer contracts reference it. Five working codes and the general DEFERRAL_UNAVAILABLE («Отсрочка сейчас недоступна»); there is no ADDITIONAL_CHECK_REQUIRED - waiting shows the status «на рассмотрении». RU and UZ texts are not here. A new code changes the market contract.
      enum:
      - OVERDUE_DEBT
      - INSUFFICIENT_HISTORY
      - AMOUNT_ABOVE_LIMIT
      - COMPANY_NOT_VERIFIED
      - CATEGORY_NO_DEFERRAL
      - DEFERRAL_UNAVAILABLE
    DealsDealContext:
      type: object
      additionalProperties: false
      required:
      - marketDealRef
      - marketOrderNumber
      - buyerInn
      - buyerMarketCompanyRef
      - buyerFirstOrderOn
      - supplierMarketRef
      - supplierInn
      - supplierName
      - lines
      - orderAmountTiyin
      - marketPercentBps
      - language
      - returnUrl
      - occurredAt
      properties:
        marketDealRef:
          type: string
          minLength: 1
          maxLength: 128
          description: the market's internal deal id = the key of the context
        marketOrderNumber:
          type: string
          description: public order number shown to people
        buyerInn:
          $ref: '#/components/schemas/DealsInn'
        buyerMarketCompanyRef:
          type: string
          description: the buyer company id at the market
        buyerFirstOrderOn:
          type:
          - string
          - 'null'
          format: date
          description: date of the first order at the market; null = unknown
        supplierMarketRef:
          type: string
        supplierInn:
          $ref: '#/components/schemas/DealsInn'
        supplierName:
          type: string
        lines:
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/DealsOrderLine'
        orderAmountTiyin:
          $ref: '#/components/schemas/CommonMoneyTiyin'
        marketPercentBps:
          type: integer
          minimum: 0
          maximum: 10000
          description: the market's percentage on this deal, basis points
        language:
          type:
          - string
          - 'null'
          enum:
          - RU
          - UZ
          - null
          description: null = the market path has no Merqo Finance screen to localise (the buyer path is at the market, P7)
        returnUrl:
          type:
          - string
          - 'null'
          format: uri
          description: back to the market, checked against the market host allow-list; null on the market-only path (P7)
        occurredAt:
          $ref: '#/components/schemas/CommonTimestamp'
    DealsOrderLine:
      type: object
      additionalProperties: false
      required:
      - name
      - category
      - ikpu
      - quantity
      - unitPriceTiyin
      properties:
        name:
          type: string
          minLength: 1
        category:
          type: string
        ikpu:
          type: string
          pattern: ^[0-9]{17}$
          description: product classifier code (17 digits)
        quantity:
          type: string
          pattern: ^[0-9]+(\.[0-9]{1,3})?$
          description: decimal as a string (kg, pieces); never a float
        unitPriceTiyin:
          $ref: '#/components/schemas/CommonMoneyTiyin'
    DealsCancelReason:
      type: string
      description: Reason on market status CANCELLED (ORDER_CANCELLED; BUYER_CHOSE_PREPAYMENT = the buyer changed his mind and the market turns the order into a full prepayment) and ANNULLED (GOODS_RETURNED).
      enum:
      - ORDER_CANCELLED
      - GOODS_RETURNED
      - BUYER_CHOSE_PREPAYMENT
    DealsApplicationResult:
      type: string
      description: |
        The application result "результат по заявке", sent to the market by a separate method (market-api.yaml). NOT_ISSUED = the buyer reached the transition point but did not pick a term.
      enum:
      - NOT_ISSUED
      - AWAITING_SIGNATURE
      - IN_REVIEW
      - APPROVED
      - REFUSED
    DealsDealStatusEvent:
      type: object
      description: |
        Body of the market method "статус сделки", one per change. Delivered by the callback and re-read by the events pull. The market applies an event only when `sequence` is greater than the last one it received for this deal. ru/uz texts are not here.
      required:
      - eventId
      - dealId
      - marketDealRef
      - code
      - dueDate
      - amountDueTiyin
      - remainderTiyin
      - claimFiledOn
      - cancelReason
      - sequence
      - occurredAt
      properties:
        eventId:
          $ref: '#/components/schemas/CommonId'
        dealId:
          $ref: '#/components/schemas/CommonId'
        marketDealRef:
          type: string
        code:
          $ref: '#/components/schemas/DealsMarketStatusCode'
        dueDate:
          type:
          - string
          - 'null'
          format: date
        amountDueTiyin:
          $ref: '#/components/schemas/CommonMoneyTiyinOrNull'
        remainderTiyin:
          $ref: '#/components/schemas/CommonMoneyTiyinOrNull'
        claimFiledOn:
          type:
          - string
          - 'null'
          format: date
          description: for CLAIM_FILED
        cancelReason:
          oneOf:
          - $ref: '#/components/schemas/DealsCancelReason'
          - type: 'null'
          description: for CANCELLED and ANNULLED
        sequence:
          type: integer
          format: int64
          minimum: 1
        occurredAt:
          $ref: '#/components/schemas/CommonTimestamp'
    DealsMarketStatusCode:
      type: string
      description: |
        The codes of the market method "статус сделки". Every value is a deal state or a collection state value. Not sent to the market: SHIPPED, DELIVERED (the market's own events), the deal closure after the window, CLOSED, and collection stages other than CLAIM_FILED.
      enum:
      - CONCLUDED
      - IN_TERM
      - DISPUTED
      - PARTIALLY_PAID
      - OVERDUE
      - CLAIM_FILED
      - REPAID
      - CANCELLED
      - ANNULLED
    CommonNextCursor:
      type:
      - string
      - 'null'
      description: 'Cursor of the next page; null on the last page. A page body is { items: [...], nextCursor }.'
      maxLength: 512
  headers:
    CommonXRequestId:
      description: The request id of this call (see parameter RequestId).
      schema:
        type: string
    CommonRetryAfter:
      description: Seconds to wait before a retry.
      schema:
        type: integer
        minimum: 0
