.. _partner_api: Merchant-Partner API ==================== Merchant partners can create payments for their assigned merchants and read partner-scoped reports. These endpoints use the five HMAC signing headers from :ref:`authentication`, not dashboard JWT authentication. Sign the full path, including ``/external/partner`` for reporting or ``/external/v1`` for payment creation, and the exact query string. This API is separate from acquisition-partner onboarding. A partner account must be active and the key must have the scope required by the route. Merchant keys cannot access partner reporting routes; partner keys cannot access the merchant-only GET routes under ``/external/v1``. Scopes and Routes ----------------- .. list-table:: :class: partner-routes :widths: 40 30 30 :header-rows: 1 * - Method and path - Required scope - Success response * - ``POST /external/v1/payments/prompt`` - ``payment_prompts:write`` - 201 ``{ prompt, checkoutUrl }`` * - ``GET /external/partner/overview`` - ``partner_overview:read`` - 200 ``{ partner, metrics, attention, volumeTrend }`` * - ``GET /external/partner/merchants`` - ``partner_merchants:read`` - 200 ``{ data, total, page, limit }`` * - ``GET /external/partner/merchants/:merchantId`` - ``partner_merchants:read`` - 200 merchant details, branches, aggregates and recent payments * - ``GET /external/partner/payments`` - ``partner_payments:read`` - 200 ``{ data, total, page, limit }`` * - ``GET /external/partner/payment-filters`` - ``partner_payments:read`` - 200 ``{ merchants: [{ id, name }], blockchainIds }`` * - ``GET /external/partner/payments/:paymentId`` - ``partner_payments:read`` - 200 partner payment reporting row * - ``GET /external/partner/team`` - ``partner_team:read`` - 200 ``{ data }`` Partner developer keys are currently restricted to ``partner_overview:read``, even if other scopes are stored on the key. Partner owner keys can use the partner scope set above. The application rate limiter and structured :doc:`errors ` also apply to these routes. Create on Behalf of a Merchant ------------------------------ Use the :ref:`external_payments_api` create contract, adding ``merchantId``. The ID must be a UUID for an active merchant assigned to your partner. Missing ``merchantId`` returns E1001; an unowned merchant returns E3001. The target merchant's default Main branch, onboarding, network configuration and redirect allowlist apply. .. code-block:: typescript // Use partner credentials with the signed-fetch helper. // Load a persisted key for this intended payment; reuse on retries. const response = await miraclePayFetch( "POST", "/external/v1/payments/prompt", { merchantId: "550e8400-e29b-41d4-a716-446655440000", amount: 1099, // $10.99 in cents customerReferenceId: "order_12345", }, { "Idempotency-Key": idempotencyKey }, ); if (!response.ok) { const { error } = await response.json(); throw new Error(`${error.errorCode}: ${error.message}`); } const { prompt, checkoutUrl } = await response.json(); The response uses the same cents-based payment object as merchant creation. To read it afterwards using partner credentials, use ``GET /external/partner/payments/:paymentId`` and its reporting contract below. A linked merchant can instead use its own key only when its partner has enabled self-service API payments. Otherwise merchant payment routes return E2103. That setting does not replace ownership checks on partner-key creation. Reporting Queries ----------------- Both merchant and payment lists use ``page`` (minimum 1, default 1) and ``limit`` (1–100, default 20), not merchant payment cursors. Responses contain ``data``, ``total``, ``page`` and ``limit``. Lists are ordered newest-first by creation time. Merchant list accepts ``search`` (name, email or ID, at most 255 characters) and ``actionRequired=true`` to restrict results to merchants awaiting verification. Partner payment list accepts: .. list-table:: :widths: 26 74 :header-rows: 1 * - Parameter - Meaning * - ``search`` - Partial match across merchant name/ID, payment ID, address, transaction hash and customer reference. * - ``status`` - ``pending``, ``successful``, ``unsuccessful``, ``expired`` or ``cancelled``. * - ``transactionId`` - Partial payment ID, not a blockchain transaction hash. * - ``merchantId`` - Exact merchant UUID. * - ``merchantName`` - Partial merchant name. * - ``addressSearch`` - Partial deposit address. * - ``txHash`` - Partial transaction hash. * - ``blockchainId`` - Supported blockchain ID. * - ``startDate``, ``endDate`` - ISO date/time bounds on creation time, inclusive. Text filters have a 255-character maximum. ``actionRequired`` is inherited by the payment query DTO but does not filter payment results. Detail path IDs must be UUIDs; unowned or missing details return E3001. Reporting Response Differences ------------------------------ .. warning:: Partner reporting is not the canonical merchant payment DTO. Payment reporting ``amount`` and ``commissionAmount`` are database decimal USD values in **dollars**, not integer cents. Do not reuse the merchant DTO's money decoder. Partner overview and merchant aggregate volumes also use dollars. Payment creation still takes and returns cents. Partner payment list rows and payment detail contain these fields: .. code-block:: text id, amount, commissionAmount, tokenAmount, status, sessionStatus, flow, paymentSystem, blockchainId, address, transactionHash, customerReferenceId, note, createdAt, expiresAt, paidAt, branchId, branchName, merchantId, merchantName There is no ``object: "payment_prompt"`` discriminator on these reporting rows. They expose reporting fields such as ``paymentSystem`` and ``address`` that merchant payment responses deliberately omit. Do not assume ``settlementModel``, ``lastError`` or ``cancellationReason`` are present. Overview metrics include ``totalMerchants``, ``approvedMerchants``, ``actionRequired``, ``volume30d``, ``totalVolume`` and ``totalPayments``. Merchant detail includes branches, merchant payment aggregates and up to ten recent payment entities, rather than the canonical merchant DTO. ``payment-filters`` returns assigned merchant choices and the non-null blockchain IDs present in the partner's payment history; it is not an active-network discovery endpoint.