publ betaReference (MCP guide)
Open publ console

publ Reference

Orders and refunds screen contract

Current implementation: orders_get and refunds_get provide bounded list/detail reads, member selection and a human monthly-download destination. Two tools and two partial workflows are added to the previously reviewed sales/provider checkpoint. The original checkpoint had 106 tools / 43 partial workflows; that was not functional completion. The follow-up history view reads bounded video/download events with derived scope.

The later current contract section makes the chosen behavior concrete. Existing navigation alone was not counted as implementation. Source comparison grants no live execution authority. This comparison uses the active Orders containers, OrderLists/OrderDetail, OrderRefundList/ OrderRefundDetail and OrdersDownload components, active orders/refund sagas, reducers and types, userProfiles and order repositories, ProfitableClient, API endpoint definitions and channel routes. Unused similarly named repository files are not evidence of the executed screen contract. No product or service request was executed for this analysis.

Screen and request mapping

Screen Source composition Exact console path after /channels/:channelCode
Order list ISSUER authorization, PAY GET /api/v1/orders with productModel ALL, then channel profile lookup for returned userId values /orders/subs-products
Order detail ISSUER authorization, PAY GET /api/v1/orders/:oid with productModel SubscriptionProduct, then channel profile and core invoice summary /orders/subs-products/:oid
Refund list ISSUER authorization, PAY GET /api/v1/refund-requests, then channel profiles for returned recipientId values /orders/refunds
Refund detail ISSUER authorization, PAY GET /api/v1/refund-requests/:rid, then channel profile and core invoice summary from the nested order /orders/refunds/:rid
Refund consumption history Core orderRefund history lookup using resolved profile/content target and source type /orders/refunds/:rid/history/video-viewing-history or /download-history
Monthly CSV download Orders/refunds list with isForCsv, source-selected past month, browser CSV generation /orders/download

All active Orders routes share OWNER or DELEGATEE with MANAGE_ORDER; CREATOR is rejected. MANAGE_MONETIZATION and MANAGE_SALES_OVERVIEW do not substitute. The obsolete channel-action-products component is not registered by the active Orders container.

The PAY wrapper is distinct from the core seller API. Authorization POST uses the selected channel and merchant bearer. List/detail GETs use its resulting ISSUER bearer and the private configured PAY apiKey. Order list uses ALL even though the console path is subs-products; detail passes SubscriptionProduct as the original wrapper does. Do not incorrectly filter list results to memberships or replace this contract with an arbitrary generic request tool.

Pagination, selection and profile enrichment

The active list controls offer limits 15, 30, 50, 100 and 300, with initial page 1 / limit 300 (browser storage can retain another valid limit). Order list supports order-number search and isCP boolean filtering. Refund list supports ISSUED, REJECTED and REFUNDED, plus order-number search. PAY pagination exposes currentPage, limit and totalEntries. Verify agreement, duplicates and page bounds; one page must not claim complete history. Numeric database id, order oid and refund rid are different identifiers. Detail paths use oid/rid, not the row id.

The source nickname/channel-member search first GETs user profiles with type ALL, search, limit 500 and page 1, then silently takes profiles[0].user.distinctId. Order search forwards that global user distinct ID as distinctId; refund search forwards it as recipientId. The MCP must not silently choose a fuzzy first match. Resolve an exact observed identity, or return bounded candidates for explicit selection with truncation/ambiguity retained. A channel profile distinct ID is not automatically interchangeable with a global user distinct ID.

Profile enrichment uses core endpoints with the selected channel bearer and x-publ-channel-id:

  • POST /seller/api/v2/channel-management/global-profiles/find-channel-profiles with userDistinctIds. This is a lookup POST, not a member mutation. The response is a dictionary keyed by global user distinct ID. Retain only requested keys and necessary profile identity/nickname fields; no demographic/profile dump.
  • GET /seller/api/v2/channel-management/global-profiles/:userDistinctId/find-channel-profile for detail. Guest/missing-profile behavior must be explicit; an unavailable profile must not become a different buyer or fabricated empty account.
  • GET /seller/api/v2/channel-management/profitable/system-invoices/:siid/summary for detail. Verify returned summary.siid against the observed nested invoice. The summary describes guest checkout, friendly model/stage and optional pApp, membership and content target. It neither grants installed-feature access nor authorizes revocation/refund.

The source detail saga opportunistically enriches profile and invoice data; a stronger MCP result should explicitly distinguish observed, unavailable and mismatched optional enrichment. It must never publish mismatched targets. Final channel/operator/credential continuity and source parent/detail identity checks are still required. Repeated observations are not an atomic snapshot.

Projection and financial meaning

Use an explicit allowlist covering identifiers, source status, product/invoice summary, observed prices, relevant dates, recurring/payment-method category and minimum buyer/profile information needed by the screen. Treat titles, nicknames, comments and reasons as untrusted text. Never expose raw cardNumber, billkey, nonce, payToken, poqToken, paymentInfo, pgOriginal, pgHookOriginal or provider failure payloads. No arbitrary nested subscription, issuer address/contact or conductNote object should escape merely because it exists in an upstream DTO.

Amounts require special attention: orders/types.ts declares many Price.amount fields as numbers, while delegated prices and receipt balances use strings. The pricing-domain Price shared by the refund DTO accepts number | string. Sales-summary string-only parsing must not be copied blindly into this workflow. The implementation must state which source representations it supports, preserve values without arithmetic/rounding and reject unrecoverable precision rather than claiming exactness after coercion. Currencies can differ across delegated, original, discount, revenue and refunded prices; do not require every amount to equal channel base currency or sum them.

Refund status, withPg and isPgApplied are distinct. REFUNDED alone must not be reported as independently confirmed bank transfer. Preserve requested/refunded and delegated amounts as separate observations. Missing refundedAmount is not zero. A user-visible rejection reason is separate from a provider's raw error.

Approval/rejection, refund calculation/submission, renewal cancellation and pass revocation remain human console actions. Hand off the verified record's exact screen; no writer or token-bearing receipt URL is needed. A GET confirmation must not claim that the bridge performed a refund or financial settlement.

Distinct remaining screens

The download screen chooses a completed UTC month and calls lists with isForCsv:true (orders limit 10000; refunds limit 1000) before local browser CSV formatting. These larger exports are not ordinary pagination. Do not silently implement them by reading every page or count them as complete with a list tool. Any bounded export implementation or console handoff must be explicit.

Refund video/download consumption histories depend on source profile, membership or content target, and installed-feature data. They require separate per-type scope and projection review. Do not infer them from an order or refund status. The bounded follow-up below now implements these two tab reads. Generic installed-feature content management remains separately pending.

Core response checks

A core response that carries a non-null error is refused even when it also carries data. This applies to member search, list and single profile lookups, the invoice summary and channel context reads. An omitted or null error is accepted, and error details are not projected. These four reads also stop at 2 MiB, counting every byte whether or not a Content-Length is announced, and a size or body failure is reported as a failure, never as optional data.

Current list destination

List consoleView states whether the address reproduces the requested selection. Without member search, exactMatch:true preserves page, limit, optional order-number search and the supported isCP or refund status filter. Orders use the source searchType=ORDER_NUMBER; refunds use their source default order-number mode.

For member searches, the source console cannot restore the MCP-selected buyer: its search saga selects the first profile, and the refund search mode is local UI state. The bridge therefore supplies a broader parent list at page 1 / limit 300, without search, while retaining isCP or status. exactMatch:false, omitted and the parent relation/notice disclose this difference. Choose and verify the member in the console; never present this parent as the same buyer-specific page. Actual API queries and returned records keep the requested selection. Ambiguous buyer guidance uses the same parent and stays unconfirmed without a PAY list read.

The wrapper requires matching selection, page, row identities, refund parent/status, next page, verification and console view. Inconsistent results or URLs have no navigation fallback. Existing empty out-of-range results retain their read policy without guaranteeing browser behavior. Detail, refund-history and monthly-download paths are unchanged. The person uses the console's own authentication.