Skip to content

PH-03 — Canonical Payment Hub Domain Model

Payment Hub · Working Draft · Revised Working Copy v7 · Updated September 3, 2026

1. Objective

Provide the canonical payment records, identifiers, relationships, current state, and durable persistence used across DragonPay payment Products.

PH-03 separates:

  • the overall payment outcome requested by the customer or Product;
  • the business operations required during that payment's lifecycle;
  • the logical movements of value required by those operations;
  • the technical attempts DragonPay makes to execute those movements; and
  • the transactions recognized by external CU/provider systems.

DragonPay uses one canonical hierarchy:

Payment Request — Payment Action — Payment Leg — Execution Attempt — Provider Transaction

PH-03 establishes:

  • stable DragonPay identity for canonical payment objects;
  • durable persistence of accepted payment requests and subsequent payment activity;
  • explicit parent/child relationship rules;
  • current normalized state and reason information;
  • idempotent handling of logical requests and commands;
  • preservation of retries and uncertain execution outcomes;
  • association of Product configuration, Parties, Payment Instruments, Product-specific information, and external references;
  • provider-neutral representation of payment activity; and
  • consistent retrieval of the complete canonical payment.

PH-03 owns current canonical payment state.

PH-04 owns workflow progression and determines what happens next.
PH-07 owns routing decisions.
PH-08 owns provider/CU execution and normalization of external results.
PH-09 owns immutable lifecycle history when that capability is implemented.
PH-10 owns reconciliation.

The exact persistence technology, database schema, locking mechanism, idempotency implementation, API shape, event mechanism, and service decomposition are Engineering decisions provided the requirements in this epic are preserved.


2. Ownership boundaries

Owner Responsibility
PH-03 Canonical Payment Request, Payment Action, Payment Leg, Execution Attempt, Provider Transaction, their identities, relationships, current state, and associated payment references.
Payment Product epics Define Product-specific payment behavior, supported Action/Leg meanings, Product-specific data, and customer-facing outcome.
PH-02 Provides the Tenant Product configuration version governing new payment activity.
PH-04 Determines lifecycle progression and when Actions, Legs, Attempts, retries, returns, reversals, corrections, or other operations are required.
PH-05 Owns Parties and Payment Instruments referenced by canonical payments.
PH-07 Owns the Route Decision used for payment execution.
PH-08 Executes payment instructions through CU/provider Connections and supplies normalized execution results to the canonical model.
PH-09 Owns immutable payment lifecycle history when that capability is implemented.
PH-10 Owns reconciliation results and reconciliation state.

PH-03 is the authoritative DragonPay representation of the payment itself. Other capabilities may contribute information to it but do not maintain independent competing canonical payment records.


3. Canonical payment model

Payment Request
└── Payment Action
    └── Payment Leg
        └── Execution Attempt
            └── Provider Transaction

3.1 Payment Request

A Payment Request represents the overall payment outcome requested by the customer or Product.

Examples:

  • send $100 to another person;
  • pay a merchant;
  • deliver a specified amount to a cross-border recipient.

One Payment Request remains the stable DragonPay anchor for the full lifecycle of that payment.

A Payment Request may require multiple business operations over time without creating a replacement Payment Request.

3.2 Payment Action

A Payment Action represents a distinct business operation performed as part of a Payment Request.

Examples may include:

  • transfer;
  • funding;
  • payout;
  • authorization;
  • capture;
  • refund;
  • return;
  • reversal; or
  • adjustment.

The owning Product determines which Action types are valid and how they relate to each other.

A follow-on business operation creates a new Action rather than rewriting the original Action.

3.3 Payment Leg

A Payment Leg represents one logical movement of value required by an Action.

A Leg identifies the business movement that DragonPay must route, execute, observe, and, where applicable, reconcile independently.

A Leg is not an API call, file submission, core posting command, or other technical execution step.

Technical execution steps belong beneath the Leg as Execution Attempts.

One Action may contain multiple Legs when the Product requires multiple distinct movements of value.

3.4 Execution Attempt

An Execution Attempt represents one authorized technical attempt to execute all or part of a Payment Leg through a selected execution path.

Examples include:

  • an initial CU-core posting;
  • an external rail submission;
  • a later authorized retry;
  • a failover execution;
  • another distinct technical step required to complete the Leg.

A retry or new technical submission creates a new Attempt. It does not replace the prior Attempt or create another business Action.

An Attempt may fail before an external Provider Transaction exists.

3.5 Provider Transaction

A Provider Transaction represents a transaction that an authoritative CU core, processor, provider, network, or other external payment system recognizes as existing.

It is separate from DragonPay's Execution Attempt because:

  • an Attempt may never reach the provider;
  • an Attempt may have an uncertain outcome;
  • an external transaction may later be discovered after the original Attempt; and
  • the provider's lifecycle and identifiers are not DragonPay's canonical identity.

A Provider Transaction retains both DragonPay-normalized state and the external state/reference evidence needed to understand the provider's result.


4. Relationship rules

The following are Product/domain invariants:

  1. One Payment Request may contain multiple Payment Actions over its lifecycle.
  2. One Payment Action belongs to exactly one Payment Request.
  3. One Payment Action may contain one or more Payment Legs.
  4. One Payment Leg belongs to exactly one Payment Action.
  5. One Payment Leg may contain multiple Execution Attempts.
  6. One Execution Attempt belongs to exactly one Payment Leg.
  7. A Provider Transaction is associated with the Execution Attempt that produced or first discovered it.
  8. Canonical parent relationships do not change after object creation.
  9. A new business lifecycle operation creates a new Action.
  10. A new logical movement creates a new Leg.
  11. A new authorized technical submission or retry creates a new Attempt.
  12. Replaying the same logical request does not create another canonical object.
  13. External/provider identifiers never replace DragonPay canonical identifiers.
  14. Only Actions and Legs that DragonPay must manage distinctly for the Product are represented as separate canonical objects.

Product-specific technical behavior does not create additional canonical layers unless DragonPay has a real business/domain need to manage that concept independently.


5. Required canonical data

The items below define the information DragonPay must retain for the canonical model. They are not a prescribed physical database schema.

5.1 Payment Request

A Payment Request retains at least:

Data Purpose
DragonPay Payment Request identity Stable canonical payment identifier.
Tenant CU customer owning the payment.
Product / use case Product that initiated the payment and applicable Product use case.
Requested amount and currency Primary requested payment outcome.
Current status and reason Current normalized state of the overall payment.
Product configuration version Configuration governing the payment when processing began.
Workflow/Product-processing version when needed Allows historical payment behavior to be interpreted correctly.
Customer/client reference when supplied Caller-facing business reference without replacing DragonPay identity.
Requested/effective date when applicable Product-required payment timing.
Product-specific payment data reference Allows Product data without expanding the canonical core model.
Correlation/trace context Connects processing related to the same payment.
Creation/update information Operational and historical interpretation of current state.

Payment Request identity, Tenant ownership, and the configuration identity governing the payment are not silently changed after creation.

5.2 Payment Action

A Payment Action retains at least:

Data Purpose
DragonPay Action identity Stable Action identifier.
Parent Payment Request Business payment to which the Action belongs.
Action type Product-defined business operation.
Action order/relationship Allows multiple lifecycle operations to be understood in context.
Related prior Action when applicable Connects refunds, returns, reversals, captures, corrections, or other follow-on operations.
Amount/currency when applicable Value governed by the Action.
Current status and reason Current normalized Action state.
Product-specific Action information when required Supports Product behavior without changing the canonical core.

5.3 Payment Leg

A Payment Leg retains at least:

Data Purpose
DragonPay Leg identity Stable logical-movement identifier.
Parent Payment Action Action requiring the movement.
Leg type Product-defined meaning of the movement.
Leg order when needed Relationship among multiple movements under the Action.
Source and destination Party references Parties participating in the logical movement.
Source and destination Payment Instrument references when applicable Instruments involved in the movement.
Amount and currency Value represented by the Leg.
Current status and reason Current normalized Leg state.
Product-specific Leg information when required Supports Product behavior without adding Product-specific canonical fields.

Routing, Connection, Connector, provider endpoint, and other execution selections are not attributes defining the logical Leg.

5.4 Execution Attempt

An Execution Attempt retains enough information to establish:

Data Purpose
DragonPay Attempt identity Stable identity for this execution attempt.
Parent Payment Leg Logical movement being executed.
Attempt order/relationship Distinguishes sequential attempts, retries, failovers, or execution steps.
Execution purpose Why this Attempt exists.
Route Decision reference Route authorized for the Attempt.
Connection/Connector identity Technical path actually used.
External idempotency/submission reference when applicable Allows safe interaction with downstream systems.
Current status and reason Current normalized execution state.
Handoff certainty Whether DragonPay knows if execution reached the external system.
Prior related Attempt when applicable Preserves retry/failover/correction lineage.
Relevant execution times Submission, response, resolution, or other significant timing.
Protected execution-evidence reference Allows investigation without placing sensitive provider payloads in the canonical object.

5.5 Provider Transaction

A Provider Transaction retains enough information to establish:

Data Purpose
DragonPay Provider Transaction identity Stable DragonPay identity for the external transaction.
Originating/discovering Attempt Connects external recognition to DragonPay execution history.
External system/Connection Namespace in which the provider transaction exists.
External transaction reference Authoritative provider/CU/network identifier.
Related external references when applicable Parent, trace, network, authorization, return, or other provider relationship.
Amount/currency Value recognized externally.
Normalized DragonPay state/reason Provider-neutral interpretation.
Original external state/reason Evidence of what the provider actually reported.
Relevant external lifecycle times Accepted/completed/returned/etc. when supplied.
Mapping/normalization reference when needed Supports later interpretation of normalization behavior.
Protected provider-evidence reference Allows investigation without embedding sensitive raw provider payloads.

DragonPay must be able to recognize repeated reports of the same external transaction within the applicable external-system namespace without creating uncontrolled duplicate Provider Transactions.


6. Payment context and supporting associations

The canonical payment must be able to associate, as applicable:

  • PH-05 Parties and their roles in the payment;
  • PH-05 Payment Instruments and their roles in the payment;
  • Product-specific Request, Action, or Leg information;
  • Product configuration governing the payment;
  • client/CU/core/network/provider references;
  • approved historical display information needed to understand the payment later; and
  • protected evidence stored by the capability that owns that evidence.

These associations must preserve the meaning of the payment at the time it was processed.

For example, a later change to a Party display name or Payment Instrument should not make historical payment information misleading.

Sensitive account credentials, card credentials, authentication secrets, and other protected values are not copied into the canonical payment merely for convenience.

The exact supporting-record/schema design is an Engineering decision.


7. Durable persistence, idempotency, and write safety

Payment processing is a distributed, failure-prone operation. PH-03 therefore requires explicit persistence and write-safety guarantees.

Durable canonical persistence

Once DragonPay accepts creation of a canonical Payment Request or other canonical payment object, that object must be durably persisted.

A service restart, retry, duplicate request, worker failure, or transient infrastructure failure must not cause DragonPay to lose an accepted payment identity or replace it with a different logical payment.

Idempotent creation

Creation of canonical payment objects must be idempotent for one logical request or command.

For the same logical request:

  • DragonPay returns or resolves to the same canonical object;
  • a duplicate Payment Request, Action, Leg, or Attempt is not created merely because a request was retried; and
  • conflicting reuse of the same logical idempotency identity with materially different request content is rejected rather than silently applied to the existing object.

The exact idempotency-record structure, fingerprint algorithm, storage location, and implementation pattern are Engineering decisions and should follow DragonPay shared standards.

Execution retries

Idempotent replay is different from a newly authorized payment-execution retry.

A replay of the same execution instruction resolves to the same Attempt.

A genuinely new authorized retry, failover, continuation, or corrective execution creates a new Execution Attempt and preserves the prior Attempt.

Concurrent updates

Concurrent or stale processing must not silently overwrite newer canonical payment state.

Engineering must use an established concurrency-control pattern appropriate to the selected persistence architecture.

The Product requirement is preservation of correct canonical state and detection of conflicting/stale writes, not a particular locking or version-column mechanism.

External duplicate protection

DragonPay must distinguish:

  • duplicate delivery/reporting of the same external transaction; from
  • a genuinely different external transaction.

External transaction identity is interpreted within the applicable provider/CU/Connection namespace rather than assumed globally unique.


8. Canonical state and outcome semantics

Each of PH-03's five canonical objects maintains the current normalized state and, where applicable, a controlled reason describing that state.

The exact complete status vocabulary may evolve as supported Products establish common needs, but the following semantics are required.

Payment Request

Represents the overall current outcome/progression of the Product payment.

Its state is determined from Product behavior and the relevant underlying Actions/workflow. It is not automatically copied from the newest child object.

Payment Action

Represents the current state of that business lifecycle operation.

A later refund, return, reversal, or correction does not rewrite the status/history of the prior Action into the new operation.

Payment Leg

Represents the current outcome of the logical value movement.

Technical attempts may change while the same Leg remains the logical movement being executed.

Execution Attempt

Must distinguish at least:

  • not yet successfully submitted;
  • execution in progress;
  • known successful/accepted result;
  • known unsuccessful result; and
  • OUTCOME_UNKNOWN, where DragonPay cannot determine whether external handoff or transaction creation occurred.

OUTCOME_UNKNOWN is not equivalent to FAILED.

DragonPay must not automatically retry an uncertain external submission as though failure were known.

A later authoritative result may resolve the existing Attempt.

Provider Transaction

Maintains DragonPay's normalized interpretation of the external transaction while retaining the original external status/reason supplied by the authoritative system.

Unknown or unmapped external results are not silently converted into success or failure.

Reconciliation

Reconciliation state belongs to PH-10 and is not substituted for the canonical payment/execution state defined here.


9. Lifecycle history and events

PH-03 owns current canonical state.

When DragonPay's lifecycle history or downstream event consumers require payment changes, canonical creations and material state changes must be available through the shared DragonPay event/evidence mechanism.

PH-03 does not define a separate Product-specific event delivery protocol.

Transactional event publication, outbox behavior, event envelopes, retry/deduplication mechanics, and similar delivery guarantees follow applicable shared Engineering/STD requirements.

PH-09, when implemented, owns immutable payment lifecycle history rather than PH-03 maintaining a second historical-state model.


10. Reference example — Claim-based P2P

The initial P2P Product demonstrates why the canonical layers are distinct.

Customer request

John requests to send $100 to Sally.

This is one Payment Request.

Transfer Action

DragonPay creates the Product's P2P transfer Payment Action.

Funding Leg

The Product requires funds to move from John's source account into the CU's normal pending-P2P accounting mechanism.

That logical movement is a Funding Leg.

Execution through the CU/core is represented by one or more Execution Attempts.

If the CU/core recognizes a transaction, DragonPay records the corresponding Provider Transaction.

Recipient claim wait

After funding, the Product may wait for Sally to claim the payment.

The wait is PH-04 orchestration state. It is not another PH-03 canonical payment object.

Payout Leg

Once Sally supplies an eligible destination, the transfer requires a second logical movement from the CU-controlled pending-P2P mechanism to Sally's destination.

That is a separate Payout Leg because it:

  • has a different source/destination;
  • occurs at a different time;
  • may use a different route;
  • is executed independently; and
  • has an independently meaningful outcome.

A same-CU payout and an external ACH payout may therefore be different execution paths for the same logical Payout Leg.

Return to sender

If the Product requires funded money to be returned to John after an expired/failed claim, DragonPay creates a new corrective Return Action with its own Return Leg and execution history.

The original transfer/funding records are preserved rather than rewritten.


11. Product stories

PH03-01 — Create and Persist the Canonical Payment Request

Objective

Create one durable DragonPay payment identity for the overall payment outcome requested by a Product/customer.

Required behavior

  • Create one Payment Request for one logical payment request.
  • Associate it with the owning Tenant and Product.
  • Retain the requested payment amount/currency and other Product-required request information.
  • Bind the Product configuration version governing the payment when Product processing begins.
  • Assign a stable DragonPay Payment Request identity.
  • Persist an accepted Payment Request durably.
  • Handle replay of the same logical request idempotently.
  • Reject conflicting reuse of an idempotency identity rather than creating or modifying an unrelated payment.
  • Preserve Payment Request identity and Tenant ownership for its lifetime.

Acceptance

  • Retrying the same logical payment request does not create another Payment Request.
  • A successfully accepted request remains retrievable after process/service restart.
  • A later Product configuration change does not silently change the configuration associated with the existing payment.
  • Conflicting reuse of the same logical idempotency identity is rejected.
  • The Request cannot be reassigned to another Tenant.

PH03-02 — Represent Payment Actions and Legs

Objective

Represent the business operations and logical value movements required to fulfill or correct a Payment Request.

Required behavior

  • Allow one Payment Request to contain multiple Product-defined Actions.
  • Allow an Action to reference an applicable prior Action when it represents a follow-on business operation.
  • Allow one Action to contain one or more Product-defined Legs.
  • Represent each Leg as one logical movement of value.
  • Keep technical execution details out of the definition of the Leg.
  • Create new Actions for new business lifecycle operations rather than rewriting prior Actions.
  • Create new Legs only when DragonPay must manage a distinct logical movement.
  • Preserve stable Action/Leg identities and parent relationships.
  • Apply idempotent creation semantics to logical Action and Leg requests.

Acceptance

  • A retry of technical execution does not create another Action or Leg.
  • A corrective Return can exist as a new Action related to the original payment activity.
  • Funding and recipient payout can be represented as separate P2P Legs when they are distinct logical movements.
  • Actions/Legs cannot be re-parented after creation.
  • Replaying the same logical Action/Leg creation does not create a duplicate.

PH03-03 — Track Execution Attempts and Provider Transactions

Objective

Preserve what DragonPay attempted to execute and what authoritative external systems subsequently recognized.

Required behavior

  • Create a distinct Execution Attempt for each newly authorized technical submission, retry, failover, continuation, or other separately meaningful execution attempt.
  • Preserve the execution path and evidence necessary to understand what was attempted.
  • Treat replay/redelivery of the same intended submission idempotently rather than creating another Attempt.
  • Record uncertainty when DragonPay cannot determine whether an external handoff occurred.
  • Do not treat uncertain outcome as confirmed failure.
  • Allow later authoritative evidence to resolve an existing uncertain Attempt.
  • Create a Provider Transaction when evidence establishes that an authoritative external transaction exists.
  • Recognize repeated reports of the same external transaction without creating uncontrolled duplicates.
  • Retain both normalized and original external transaction state.
  • Preserve Attempt and Provider Transaction identities/history rather than replacing prior execution records.

Acceptance

  • A confirmed pre-submission failure can exist without a Provider Transaction.
  • An uncertain post-handoff result remains distinguishable from FAILED.
  • A later provider inquiry can associate a discovered transaction with the original Attempt.
  • A newly authorized retry creates a new Attempt.
  • Redelivery of the original submission does not.
  • Duplicate provider messages/reports for one external transaction do not create duplicate Provider Transactions.

PH03-04 — Maintain Durable Canonical State Safely

Objective

Maintain one trustworthy current representation of each canonical payment object despite retries, concurrency, partial failures, and asynchronous execution.

Required behavior

  • Persist the current normalized state and reason of each canonical object.
  • Prevent stale or conflicting writes from silently replacing newer canonical state.
  • Preserve stable canonical identity throughout state changes.
  • Maintain idempotent behavior for create commands and repeated processing.
  • Distinguish newly authorized payment activity from replay of already accepted activity.
  • Keep unknown external outcomes unresolved until authoritative information supports a resolution.
  • Preserve provider-original result information when normalizing external state.
  • Make material canonical changes available to downstream history/event capabilities through applicable shared platform standards.

Acceptance

  • Concurrent processing cannot silently overwrite a newer canonical payment result.
  • Reprocessing an accepted logical command does not create duplicate canonical payment activity.
  • A later result can resolve an uncertain Attempt without creating a replacement Attempt.
  • Provider state is not guessed when the external result is unknown.
  • Current state remains retrievable even when immutable payment history capability is not yet deployed.

PH03-05 — Associate Payment Context and External References

Objective

Associate the information required to interpret and operate a payment without embedding Product- or provider-specific schemas into the canonical hierarchy.

Required behavior

  • Associate relevant Parties and Payment Instruments with the payment.
  • Associate Product-specific data with the applicable Request, Action, or Leg.
  • Retain the Product/configuration references needed to interpret payment behavior.
  • Associate client, CU, core, network, processor, and provider references where applicable.
  • Preserve approved historical payment-display information when current Party/Instrument data may later change.
  • Keep DragonPay canonical identifiers authoritative.
  • Prevent sensitive credentials or unmasked protected Payment Instrument data from being copied unnecessarily into canonical payment records.
  • Enforce Tenant isolation for all references and lookups.

Acceptance

  • A later Party/profile change does not make historical payment information misleading.
  • Product/provider-specific data can be represented without adding Product-only fields to the canonical hierarchy.
  • External references can locate the associated DragonPay payment without becoming its primary identity.
  • Cross-Tenant reference lookup cannot reveal another CU's payment information.

PH03-06 — Retrieve the Canonical Payment

Objective

Provide authorized DragonPay capabilities and operations with a consistent view of the current payment and its complete canonical hierarchy.

Required behavior

  • Retrieve a Payment Request by DragonPay identity.
  • Retrieve the Request with its Actions, Legs, Attempts, Provider Transactions, and applicable supporting references.
  • Resolve authorized external references to their applicable canonical payment object.
  • Expose the current normalized state and unresolved execution uncertainty needed by downstream DragonPay capabilities.
  • Preserve the stored hierarchy rather than requiring callers to reconstruct it from unrelated system records.
  • Apply PH-01 Tenant authorization and appropriate masking.

Acceptance

  • DragonPay can retrieve one coherent Request → Action → Leg → Attempt → Provider Transaction view.
  • An unresolved Attempt is visible as uncertain rather than presented as failed.
  • Historical/in-flight processing can identify the Product configuration governing the payment.
  • External-reference retrieval remains Tenant-authorized.
  • The same canonical hierarchy supports the initial P2P Product without requiring Product-specific canonical payment tables.

12. Deferred / Engineering-owned detail

The following are intentionally not Product-prescribed by PH-03:

  • physical database/schema design;
  • ORM/entity implementation;
  • exact API paths and service boundaries;
  • record_version versus another concurrency mechanism;
  • exact idempotency table/receipt structure;
  • idempotency fingerprint construction;
  • transactional outbox implementation;
  • detailed event taxonomy/envelope;
  • database uniqueness/index strategy;
  • exact supporting-reference table structure;
  • ProductExtension storage representation;
  • provider evidence storage architecture;
  • complete universal status enumeration before supported Products establish the common vocabulary; and
  • implementation sequencing/test structure.

Engineering must choose established, proven patterns that satisfy the durable persistence, idempotency, concurrency, payment identity, and uncertain-outcome requirements defined by this epic.


13. Scope boundaries

Out of scope

  • Product workflow sequencing, waits, timers, or determination of what happens next.
  • Product-specific eligibility or business-rule implementation.
  • Party or Payment Instrument onboarding and validation.
  • Policy, risk, limits, or velocity decisions.
  • Route eligibility and route selection.
  • Connector/Connection implementation.
  • CU/provider-specific submission mechanics.
  • File/batch execution.
  • Provider-specific status mapping implementation.
  • Immutable payment history implementation.
  • Reconciliation processing.
  • Notification delivery.
  • Case workflow.
  • Customer balances, wallets, settlement accounting, prefunding, reserves, liquidity, or custody of customer funds.

14. PH-03 completion criteria

PH-03 is complete for the initial Product scope when:

  • DragonPay durably represents Payment Request, Payment Action, Payment Leg, Execution Attempt, and Provider Transaction with stable canonical identities and relationships;
  • accepted logical payment requests survive failures/restarts and are not duplicated by request replay;
  • idempotent creation protects Requests, Actions, Legs, and Attempts from duplicate logical processing;
  • conflicting reuse of an idempotency identity is detected rather than silently applied;
  • stale/concurrent writes cannot silently corrupt canonical current state;
  • a Payment Request can support the business Actions and logical Legs required by the initial P2P Product;
  • a Leg can retain multiple separately authorized execution Attempts without rewriting prior attempts;
  • uncertain external handoff remains distinguishable from known failure;
  • a later authoritative external result can resolve the original Attempt and associate the applicable Provider Transaction;
  • Provider Transactions retain both normalized DragonPay outcome and applicable original external evidence;
  • Product configuration, Party, Payment Instrument, Product-specific, and external-reference context can be associated without making the canonical core provider-specific;
  • the complete current canonical hierarchy can be retrieved within Tenant authorization boundaries; and
  • PH-03 states the required payment-domain and persistence guarantees while allowing Engineering to select proven implementation patterns for database persistence, idempotency, concurrency, APIs, and event delivery.