Skip to content

feat: separation of concerns between pos and management services - #12

Merged
bosbaber merged 4 commits into
mainfrom
stephan/mer-141
Nov 2, 2026
Merged

bosbaber merged 4 commits into
mainfrom
stephan/mer-141

Conversation

@bosbaber

@bosbaber bosbaber commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

TL;DR - Separates the concerns between the services provided to POS devices on untrusted networks, and those for management purposes typically on trusted networks.

What this PR does

API is now split by responsibility

  • merchant-pos-api.yaml (new): what POS terminals call
    • onboarding
    • POST /v1/transactions/authorize. Public, with X-API-Key on authorize.
  • merchant-api.yaml (no authentication)
    • management of merchants
    • locations
    • terminals
    • models

Paths and operations do not change.

Contract changes to review

  1. requestId is generated by the terminal, not the server. It is sent on as cardAuthorization.requestId.
  2. The incoming payment requires walletAddress, instead of the nonexistent paymentPointerUrl.
  3. The incoming payment id and walletAddress are format: uri, and walletAddress drops minLength: 1.
  4. data is required in the authorization response.
  5. Onboarding uses wallet address URLs, not payment pointers.
  6. Onboarding declares 409, and authorize declares 401.

Also

  • Tags are kebab-case, as in Open Payments. AuthorizeTransaction is now authorizeTransaction.
  • Stale onboarding paths and the LINKED example are fixed.

Impact on merchant-api

  • Generate from both files.
  • WalletAddress and Data are no longer pointers, so remove the & in the authorization handler.

@bosbaber bosbaber self-assigned this Oct 29, 2026
merchant-pos-api.yaml holds the endpoints that POS terminals call:
terminal onboarding and transaction authorization. merchant-api.yaml
keeps the management of merchants, locations, terminals and
manufacturer models.

- Authorization declares the X-API-Key scheme; onboarding is public.
- The management API declares no scheme yet and must not be exposed
  publicly.
- Tags are PascalCase and the authorize operationId is camelCase.
- Fix stale onboarding paths and the onboarding status example.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

A critical unsatisfiable-schema defect requires paymentPointerUrl on AuthorizationIncomingPayment despite it being undefined and blocked by additionalProperties: false, guaranteeing validation failure on every successful authorize response, alongside unresolved documentation mismatches.

3 open issues
What changed in this PR

This PR implements separation of concerns by splitting the single Merchant API spec into two OpenAPI 3.0.3 documents: a new merchant-pos-api.yaml that contains the POS-device-facing endpoints (terminal onboarding + transaction authorization) and their supporting schemas, and the existing merchant-api.yaml which is trimmed down to merchant/location/terminal/manufacturer-model management. The POS spec adds an X-API-Key security scheme (with the onboarding endpoints marked public), while the management spec documents that it currently has no auth scheme. Tags in the management spec are renamed (Point of Sale (POS) → Terminal, POS Manufacturer Models → ManufacturerModel) and the POS onboarding tag/endpoints are removed, with cross-references pointing to the new file.

Changes:

  • Added merchant-pos-api.yaml containing the onboarding and /v1/transactions/authorize endpoints plus all Onboarding*, Authorization*, Field*, WrappedKeys and Problem schemas.
  • Removed those endpoints/schemas from merchant-api.yaml and updated its intro/onboarding docs to reference the new file.
  • Renamed tags and normalized the authorize operationId (AuthorizeTransaction → authorizeTransaction).
File Description
merchant-pos-api.yaml New POS-facing spec with onboarding + authorization paths, schemas, examples, and API-key security.
merchant-api.yaml Removed POS endpoints/schemas, renamed tags consistently, and updated cross-references/auth notes.

Notes from the review:

  • I verified all internal $refs in the new POS spec resolve, confirmed no dangling references to the removed schemas remain in merchant-api.yaml, and confirmed the tag renames are applied consistently across all operations.
  • I flagged one functional bug (AuthorizationIncomingPayment requires a paymentPointerUrl property that doesn't exist with additionalProperties: false, making it unsatisfiable) and two documentation/example inconsistencies (an undocumented 409 status in the onboarding token description, and a non-UUID requestId example that conflicts with the declared format: uuid and stated conventions).

Review effort: Balanced

Comment thread merchant-pos-api.yaml Resolved
Comment thread merchant-pos-api.yaml Resolved
Comment thread merchant-pos-api.yaml Resolved
- requestId is generated by the terminal and is sent on as
  cardAuthorization.requestId.
- The incoming payment id and walletAddress are URIs.
- Onboarding uses wallet address URLs instead of payment pointers.
- data is required in the authorization response.
- Tags are kebab-case.
@bosbaber
bosbaber requested a balanced review from Copilot October 29, 2026 17:12
@bosbaber
bosbaber marked this pull request as ready for review October 29, 2026 17:15

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

An unresolved active finding remains, flagging that the documented issuer-result path omits the transactionResponse wrapper and should be corrected before approval.

No open issues 🎉

1 previously missed issue

In code that hasn't changed since last review

Low severity Incorrect authorization response path in POS docs

merchant-pos-api.yaml:131

Minor documentation inaccuracy: the response body is wrapped in transactionResponse, so the issuer result lives at transactionResponse.data.authorization (AuthorizationResponse → transactionResponse → data → authorization), not data.authorization. Consider updating the path so consumers of this standalone POS spec can locate the result correctly.

3 resolved since last review

Review effort: Balanced

@bosbaber
bosbaber merged commit 13065fa into main Nov 2, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants