# POST /api/transactions

Create transaction

Creates and processes a new payment transaction. A merchant may configure a card acceptance policy that refuses cards by funding source (credit, debit, prepaid), issued entity (consumer, commercial, GSA) or issuer country, judged from the card's BIN. A card the policy refuses is rejected with HTTP 400 and no `validationErrors`, because the request names no field to correct: the card itself is what the merchant will not take. No transaction is created and nothing is sent to a processor, so present a different card rather than retrying the same one. The refusal arrives under one of two codes, and an integrator should handle both. `Transactions:CardNotAcceptedByMerchantPolicy` is the ordinary case, refused before the request is accepted, and carries a `reason` of `FundingSource`, `IssuedEntity`, `IssuerCountry` or `UnknownBin`. `CardNotAcceptedByMerchantPolicy` is the same refusal reached later, by the orchestrator, for a payload whose card details only become readable after the gateway decrypts them; it follows the orchestrator's own unprefixed code spelling and carries the reason in its message rather than as a datum. A merchant that has configured no policy accepts every card and never produces either code. A merchant may also configure a cash policy, which applies to a cash sale or authorization: one that declares `tender` as `Cash` or carries no `cardData`, `checkData` or `tokenData`. A cash sale the policy refuses is rejected with HTTP 400 before anything is stored, under one of three codes, each with a `reason` datum: `Transactions:CashAmountExceedsMerchantPolicy` when the amount is above the merchant's maximum cash sale (an amount equal to it is accepted), `Transactions:CashRegisterRequiredByMerchantPolicy` when the merchant requires a till and the request names no `register` with an `id`, and `Transactions:CashSourceNotAllowedByMerchantPolicy` when the merchant accepts cash only at the Virtual Terminal, which refuses every cash sale submitted through the API. A cash sale that reaches processing by another route is refused by the orchestrator under the same three codes without the `Transactions:` prefix. A merchant that has configured no cash policy never produces any of them. A merchant whose 3-D Secure policy mode is `Require` refuses a card sale or authorization that arrives without a completed authentication: the orchestrator rejects it with HTTP 400 under `ThreeDSecureAuthenticationRequired`, no authorization is attempted, and resubmitting without authenticating the cardholder is refused again. Merchant-initiated transactions are exempt, and a merchant on any other mode never produces this code.

**Operation ID:** `transactionsCreate`

## Authorization

Requires: Transactions.Payments.Create, merchant scope.

Required permissions:
- `Transactions.Payments.Create`

## Parameters

| Name | In | Required | Type | Description |
| --- | --- | --- | --- | --- |
| suppressNulls | query | no | boolean | If true, omit properties with null values. |

## Request Body

**Content type:** `application/json`

Schema: `TransactionCreateDto`

Properties:
- `currentStage` (object): Gets or sets the current stage of the transaction within the create or update workflow.
- `history` (array<TransactionHistoryItem>): Gets or sets the transaction history entries associated with the transaction.
- `appliedPatches` (array<TransactionPatchSnapshot>): Gets or sets the collection of patch snapshots that have been applied to the transaction.
- `merchantId` (string(uuid)): The unique identifier of the merchant associated with the transaction.
- `transactionType` (object): The type of transaction being performed. Conditional: When RequestedSplitTenderTotal is not null. Must equal Sale. Conditional: Conditional (see validator source).
- `description` (string): Optional free-text description of what this payment is for, at most 100 characters.
- `merchantReference` (string): Optional merchant-supplied reference for reconciliation, at most 25 characters, letters  and digits only.
- `tender` (object): Optionally declares that this transaction is taken in cash. The only accepted value is  `Cash`. Omit the field for every card, check, and token transaction.
- `cardData` (object): Card data associated with the transaction. Conditional: When CardData is not null. Required: Conditional (see validator source).
- `checkData` (object): Check data associated with the transaction. Conditional: When CheckData is not null. Conditional: Conditional (see validator source). Conditional: When TransactionType == VoucherClear. Required: When TransactionType == Payout.
- `cashData` (object): Cash sale details: the cash handed over, the change returned, and when the cash was taken.
- `tokenData` (object): Tokenized payment details, used to charge a stored credential instead of raw card data. Conditional: When TokenData is not null.
- `deviceData` (object): Device data for the transaction. Conditional: When DeviceData is not null.
- `fsa` (object): FSA (Flexible Spending Account) data for the transaction.
- `lodging` (object): Lodging detail for a stay-related transaction, for merchants transacting under a lodging  industry. Conditional: When Lodging is not null.
- `softDescriptor` (object): Soft descriptor information for the transaction.
- `duplicateCheck` (boolean): Indicates whether to perform a duplicate check for the transaction. Omit the field to  let the merchant's screening configuration decide, which is what happens today. Send  false to waive the check, which the merchant must have permitted. Sending true never  turns screening on for a merchant who has not configured it.
- `register` (object): Register information for the transaction.
- `invoiceData` (object): Invoice data associated with the transaction, carrying the customer and the amounts. Required: Conditional (see validator source).
- `originalTransaction` (object): Data about the original transaction, if applicable.
- `customFields` (array<TrxCustomField>): Custom fields for the transaction. Conditional: When CustomFields is not null.
- `signatureData` (object): Signature data for the transaction.
- `level2Data` (object): Level 2 data for the transaction (e.g., tax, purchase order).
- `level3Data` (object): Level 3 data for the transaction (e.g., line item details).
- `ebt` (object): EBT voucher data for the transaction (offline SNAP / Cash voucher-clear flow).
- `useInterchangeDefaults` (boolean): Indicates whether to use interchange defaults for the transaction.
- `skipOrderDataDefaults` (boolean): When true, the server does not apply the merchant's configured Level 2/3 defaults to  the transaction. Set by the Virtual Terminal when the operator chose "Enter Manually"  in the BIN-driven prompt. API submissions usually leave this null.
- `captureType` (object): The capture type for the transaction.
- `responseData` (object): Response data for the transaction.
- `settleData` (object): Settlement data for the transaction.
- `processorKey` (string): The processor type key (e.g. "tsys", "fiserv") that processed this transaction.  Display-only: set during authorization and not modifiable via create/update.
- `sourceData` (object): Gets or sets the source data associated with the transaction. Conditional: When SourceData is not null.
- `tags` (array<EntityTag>): Tags associated with the transaction.
- `notes` (array<EntityNote>): Notes associated with the transaction.
- `merchantTransactionId` (integer(int64)): The unique identifier of the merchant transaction.
- `idempotencyKey` (string): Your own identifier for this create request, used to make a retry safe. Send the same value  again and the gateway returns the transaction the first request produced instead of charging a  second time. This is the recommended pattern for reconciling a create whose response you never  received.
- `receiptIds` (array<string>): List of receipt IDs generated for this transaction. Used for point-read access to receipts.  Stored as strings: see `receiptIds` remarks for rationale.  Read-only: set by the server; ignored on the AutoMapper write maps.
- `decisionNotes` (array<TransactionDecisionNote>): System-emitted decision explanations recorded against this transaction, surfaced  read-only on the transaction-detail view. Like `receiptIds`, this is server state:  it is populated on load for display but ignored on the create/update write maps, so a client  can never persist decision notes.
- `initiationType` (object): Identifies whether this transaction was initiated by the cardholder (CIT) or the merchant (MIT).
- `mitReason` (object): For merchant-initiated transactions, the reason code justifying the MIT. Null for CITs.
- `storedCredentialConsentId` (string(uuid)): Reference to the `StoredCredentialConsent` that authorizes this MIT. Null for CITs.  Optional, and best omitted: when it is absent the server resolves the consent from the stored  credential itself (resolved from the token plus `InvoiceData.CustomerId`) and selects the  most recently captured one that permits the declared MIT reason. Send a value only to pin a  specific consent when the credential carries several, for example after a re-enrollment, and  only when the value is a consent identifier this platform issued for that same credential  (from a capture response, a consent lookup, or a webhook). A supplied value is validated  strictly and is rejected if it belongs to a different credential, has been revoked, or does  not permit the declared reason. Note that a credential whose consent lineage predates this  platform's consent tracking has no consent record at all: an identifier minted by a prior  system is never valid here, so such a charge is rejected with  `stored_credential_consent_required` whether or not this field is sent. Remediate by  having the merchant attest the credential, which mints a new platform consent; the charge then  succeeds with the field omitted, and the newly issued identifier is accepted when sent.
- `schemeTransactionId` (string): The card network's trace ID for this transaction chain. Captured from the processor response  on the initial CIT and referenced on subsequent MITs.  Read-only: set by the server; ignored on the AutoMapper write maps.
- `cardholderPresence` (object): How present the cardholder is at the point of sale, separate from the physical entry mode.  Drives network-level presence indicators (e.g. TSYS `POSEnvironmentIndicator`) at auth  time. `null` means "let the classifier infer from EntryMode + Source". Conditional: When CardholderPresence is not null.
- `specialCondition` (object): Visa/MC special-condition tag (quasi-cash, quasi-MOTO). `null` defaults to  `None`. Drives TSYS  `SpecialConditionIndicator` + `CardholderId` when set to  `QuasiCash`. Conditional: When SpecialCondition is not null.
- `processorCertificationOverrides` (object): Per-processor certification override knobs. Production traffic must leave this  `null`; `ICertificationOverridesGate` rejects requests where  it is set unless the merchant is flagged as a test merchant AND the active processor  profile has `AcceptCertificationOverrides` enabled.
- `cumulativeRefundedAmount` (number(double)): Running total of refund amounts applied to this transaction.  Read-only: computed from refund operations.
- `cumulativeReversedAmount` (number(double)): Running total of reversal amounts applied to this transaction.  Read-only: computed from reversal operations.
- `authorizedAmount` (number(double)): The immutable amount the issuer authorised at the close of the Authorization stage.  Read-only: set once at `CloseAuthorization`. UI uses this rather than  `ResponseData.Amounts.Approved` for remaining-balance calculations because  reversal contributors overwrite `/ResponseData` with the processor's  reversal-response payload.
- `saveCardRequested` (boolean): Operator (VT) or cardholder (HPP) opt-in to save the card for future merchant-initiated  use. Honored only from the Virtual Terminal and the Hosted Payment Page, which capture the  required cardholder consent; a transaction create API request that sets it to true is  rejected with a validation error. Auth-time-only: it cannot be set on updates or on  subsequent operations.
- `isAccountVerification` (boolean): When `true`, this transaction is a zero-dollar account verification  rather than a charge: the gateway authorizes for $0 to confirm card validity (with  AVS/CVV) and immediately voids the authorization. Used by the Hosted Payment Page  "save card only: don't charge me" flow to vault a card without charging it. Mutually  exclusive with a non-zero amount. Auth-time-only: the AutoMapper Update and  recurring-billing maps both ignore it so it cannot be set on subsequent operations.  `null` (the default) is an ordinary chargeable transaction.
- `convenienceFeeDisclosureAcknowledgedAt` (string(date-time)): UTC timestamp of the moment the payer accepted the disclosed convenience fee (the  confirm-click, NOT the submit). This is the caller's attestation that the fee was disclosed  and agreed to, and it is <b>required</b> on any request charging a non-zero  `invoiceData.amounts.convenience` on a card tender, alongside  `convenienceFeeDisclosureChannel`. The Virtual Terminal stamps it from its  confirm modal (the CSR attesting as the cardholder's proxy) and the Hosted Payment Page from  the cardholder's own acceptance; a direct API integration owns its own disclosure UX and  supplies the same attestation. It may not sit more than a few minutes ahead of the gateway's  clock: a disclosure cannot have been accepted after the request that reports it.     Auth-time-only: the AutoMapper Update and recurring-billing maps both ignore it, so it cannot  be set on subsequent operations. `null` when no fee was charged. An ACH /  e-check debit is out of scope; a convenience fee on an EBT / eWIC tender is prohibited  outright and rejected before this field is examined.
- `convenienceFeeDisclosureChannel` (string): The surface on which the convenience-fee disclosure was shown and accepted. One of  `"VirtualTerminal"`, `"HostedPaymentPage"`, or `"Api"` (a direct integration's  own checkout); matched case-insensitively, and any other value is rejected. Paired with  `convenienceFeeDisclosureAcknowledgedAt` and required on the same requests.  Auth-time-only.
- `convenienceFeeEligibilitySnapshot` (string): Serialized convenience-fee eligibility decision (reason code + assessed amount) captured  at disclosure-acknowledgment time. Codes / amounts only: no request- or response-derived  free text (PCI). Gateway-produced and optional: the Virtual Terminal and Hosted Payment Page  serialize their own fee decision into it, and a direct API integration has no equivalent  internal decision to record, so it is never required. Auth-time-only.
- `convenienceFeeCancelledAmount` (number(double)): The convenience-fee amount, in the transaction currency, the Virtual Terminal operator declined  on the disclosure-confirm modal, removing it from this submission. Set by the VT cancel path (button, X, or Esc) so the  authorization pipeline can record a `CsrCancelledVtModal` convenience-fee decision note  carrying the amount that was waived: the fee is gone from the amounts by submit time, so the  evaluator has nothing left to explain without this marker.     Audit-only. It never adds to any total, never reaches the processor, and is honoured only when  the submitted transaction carries no convenience fee, originates from the Virtual Terminal, and  belongs to a merchant with an active convenience-fee configuration. Auth-time-only: the  AutoMapper Update and recurring-billing maps both ignore it. `null` (the  default) on every submission where no disclosed fee was cancelled.
- `surchargeDisclosureAcknowledgedAt` (string(date-time)): UTC timestamp captured at the surcharge disclosure confirm-click moment (NOT at submit). Set  by the Virtual Terminal confirm modal / HPP acceptance when a surcharge is disclosed and  agreed. Auth-time-only: the AutoMapper Update and recurring-billing maps both ignore it so  it cannot be set on subsequent operations. `null` when no surcharge  disclosure was acknowledged.
- `surchargeDisclosureChannel` (string): Channel on which the surcharge disclosure was acknowledged (`"VirtualTerminal"`,  `"HostedPaymentPage"`, or `"Api"`). Paired with  `surchargeDisclosureAcknowledgedAt`. Auth-time-only.
- `achWebAuthorizationText` (string): The NACHA WEB single-debit authorization language shown to the payer, captured verbatim at  ACH submit on the Hosted Payment Page. The consent evidence NACHA requires to substantiate an  internet-initiated (WEB) ACH debit. Auth-time-only: the AutoMapper Update and  recurring-billing maps both ignore it so it cannot be set on subsequent operations.  `null` for non-ACH tenders. PCI-safe: authorization language only.
- `achWebAuthorizationTextVersion` (string): Stable version hash (`sha256:{hex}`) of `achWebAuthorizationText`. Auth-time-only.
- `achWebAuthorizationConsumerIp` (string): Consumer IP recorded at ACH WEB authorization time (required NACHA evidence). On the anonymous  Hosted Payment Page create path the server derives this from the incoming request and ignores  a caller-supplied value. Auth-time-only. `null` for non-ACH tenders.
- `achWebAuthorizationAt` (string(date-time)): UTC timestamp of the ACH WEB authorization. Server-stamped on create; a client-supplied value  is never trusted. Auth-time-only. `null` for non-ACH tenders.
- `achWebAuthorizationSecCode` (string): SEC code the ACH WEB authorization was captured under (always `"WEB"` for HPP ACH).  Auth-time-only. `null` for non-ACH tenders.
- `achAuthorizationAttested` (boolean): Operator attestation signal for a Virtual Terminal CSR-keyed ACH debit: `true` when the  operator confirmed they obtained the account holder's authorization (TEL or PPD) for the debit.  This is a transient <b>input</b> only: the server consumes it to gate the submit (fail-closed  when a VT ACH debit is not attested) and to stamp the persisted `AchAuthorization*`  evidence fields; it is never persisted on its own. `null` / `false` for  non-VT-ACH tenders and for callers that do not attest.
- `achAuthorizationStatementText` (string): The CSR attestation statement captured for a Virtual Terminal CSR-keyed ACH debit (NACHA TEL /  PPD). Server-owned: rendered from the selected SEC code and stamped at create time, never  trusted from the client. Auth-time-only: the AutoMapper Update and recurring-billing maps both  ignore it so it cannot be set on subsequent operations. `null` for non-VT-ACH  tenders. PCI-safe: authorization language only.
- `achAuthorizationStatementVersion` (string): Stable version hash (`sha256:{hex}`) of `achAuthorizationStatementText`.  Server-recomputed from the statement text; a client-supplied value is never trusted.  Auth-time-only.
- `achAuthorizationSecCode` (string): SEC code the VT ACH authorization was captured under (`"TEL"` or `"PPD"`).  Server-owned from the operator's selection on `CheckData.SecCode`. Auth-time-only.  `null` for non-VT-ACH tenders.
- `achAuthorizationChannel` (string): Channel on which the VT ACH authorization was attested (`"VirtualTerminal"`). Server-owned.  Auth-time-only. `null` for non-VT-ACH tenders.
- `achAuthorizationAt` (string(date-time)): UTC timestamp of the VT ACH authorization. Server-stamped on create; a client-supplied value is  never trusted. Auth-time-only. `null` for non-VT-ACH tenders.
- `requestedSplitTenderTotal` (number(double)): The total of the whole order, when you know before submitting that the customer will pay  for it with more than one card. This transaction is charged for its own amount; once it is  approved, it stays open as the first payment of a split tender collecting toward this  total, and each further card is posted to  `POST /api/transactions/{id}/split-tender/continuations`. Conditional: When RequestedSplitTenderTotal is not null.
- `deferPartialApprovalAcknowledgment` (boolean): Set to `true` to decide a partial approval yourself instead of having it accepted for  you. When the issuer approves less than the requested amount, the transaction then waits in  the `SplitTenderPending` stage, and `partialApprovalData.dispositionDeadlineUtc`  says when it will be voided automatically. Before then, decide it through  `POST /api/transactions/{id}/partial-approval/accept`, `/void`, or  `/split-tender`.

_Example: Visa Authorization_

Card-not-present authorization (hold funds without capturing). Use this when you intend to capture the funds in a later step (typical for shipped goods).

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Authorization",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "duplicateCheck": true,
  "invoiceData": {
    "amounts": {
      "base": 1,
      "total": 1
    }
  }
}
```

_Example: MasterCard Authorization_

Authorization-only request using a MasterCard test PAN.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Authorization",
  "cardData": {
    "cardNumber": "5454545454545454",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "duplicateCheck": true,
  "invoiceData": {
    "amounts": {
      "base": 1,
      "total": 1
    }
  }
}
```

_Example: Discover Authorization_

Authorization-only request using a Discover test PAN.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Authorization",
  "cardData": {
    "cardNumber": "6011000990139424",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "duplicateCheck": true,
  "invoiceData": {
    "amounts": {
      "base": 1,
      "total": 1
    }
  }
}
```

_Example: Amex Authorization_

Authorization-only request using an American Express test PAN. Amex CVV is 4 digits.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Authorization",
  "cardData": {
    "cardNumber": "378282246310005",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "1234",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "duplicateCheck": true,
  "invoiceData": {
    "amounts": {
      "base": 1,
      "total": 1
    }
  }
}
```

_Example: Sale (single-message Auth+Capture)_

Single-message authorize-and-capture in one round trip. The most common production transaction type for retail and e-commerce checkouts where goods/services are delivered immediately.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Sale",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted",
    "billingAddress": {
      "address1": "123 Main St",
      "city": "Phoenix",
      "state": "AZ",
      "zip": "85027",
      "country": "USA"
    }
  },
  "duplicateCheck": true,
  "invoiceData": {
    "amounts": {
      "base": 49.99,
      "tax": 4.12,
      "total": 54.11
    },
    "isTaxExempt": false
  }
}
```

_Example: Planned split tender (first card)_

The first card of an order the customer is paying for with more than one card. requestedSplitTenderTotal declares the whole order; this card is charged for its own amount and, once approved, stays open as the first payment of a split tender. Post each further card to POST /api/transactions/{id}/split-tender/continuations with this transaction's id, until the payments reach the order total.

```json
{
  "requestedSplitTenderTotal": 100,
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Sale",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "invoiceData": {
    "amounts": {
      "base": 60,
      "total": 60
    }
  }
}
```

_Example: Sale that decides a partial approval itself_

A sale whose caller decides a partial approval itself. If the issuer approves less than the amount, the transaction waits in the SplitTenderPending stage until partialApprovalData.dispositionDeadlineUtc. Accept it, void it, or start a split tender through POST /api/transactions/{id}/partial-approval/accept, /void, or /split-tender. Without the flag, an API sale keeps a partial approval for the approved amount.

```json
{
  "deferPartialApprovalAcknowledgment": true,
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Sale",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "invoiceData": {
    "amounts": {
      "base": 75,
      "total": 75
    }
  }
}
```

_Example: Sale with Tip_

Single-message Sale carrying a tip. Total is computed by the server as Base + Tip + Tax + Shipping + Convenience.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Sale",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "Jane Smith",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "invoiceData": {
    "amounts": {
      "base": 25,
      "tip": 5,
      "tax": 2.06,
      "total": 32.06
    }
  }
}
```

_Example: Capture (follow-up to Authorization)_

Captures funds from a prior Authorization. Card data is inherited from the original transaction; only the OriginalTransaction.TransactionId is required. Send a partial-capture amount via InvoiceData.Amounts.Base when capturing less than the original auth.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Capture",
  "originalTransaction": {
    "transactionId": "00000000-0000-0000-0000-000000000abc"
  }
}
```

_Example: Return / Refund_

Refunds a previously settled transaction back to the cardholder. References the original transaction by id; amount may be partial or full.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Return",
  "invoiceData": {
    "amounts": {
      "base": 49.99,
      "total": 49.99
    }
  },
  "originalTransaction": {
    "transactionId": "00000000-0000-0000-0000-000000000abc"
  }
}
```

_Example: Reversal (full)_

Undo a prior auth/capture. Submit TransactionType.Void; the gateway issues an online reversal (0420-equivalent message, releases the issuer hold) when the processor supports it, and falls back to an offline batch-close exclusion only when the processor declares it cannot service the online reversal. Omit InvoiceData.Amounts to undo the full authorized amount.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Void",
  "originalTransaction": {
    "transactionId": "00000000-0000-0000-0000-000000000abc"
  }
}
```

_Example: Reversal (partial)_

Reverses only part of a prior authorization, leaving the un-reversed remainder available for capture/settlement. Send the partial amount via InvoiceData.Amounts.Base. Requires a processor that advertises SupportsPartialReversal; the same TransactionType.Void shape is used as the full-amount reversal.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Void",
  "invoiceData": {
    "amounts": {
      "base": 25,
      "total": 25
    }
  },
  "originalTransaction": {
    "transactionId": "00000000-0000-0000-0000-000000000abc"
  }
}
```

_Example: Force - Voice-Auth Capture_

Voice-authorization Force: the merchant obtained a verbal approval code from the issuer over the phone and is now submitting the transaction. Supplies fresh card data, fresh InvoiceData, and the issuer-provided AuthCode. There is NO prior gateway transaction.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Force",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "invoiceData": {
    "amounts": {
      "base": 100,
      "total": 100
    }
  },
  "originalTransaction": {
    "authCode": "AB1234"
  }
}
```

_Example: Force - Gateway-Capture (follow-up to Authorization)_

Gateway-Capture-as-Force: a follow-up to a prior gateway Authorization that maps to TransactionOperationType.Capture internally. Card data and amount are inherited from the resolved prior transaction - only OriginalTransaction.TransactionId (or MerchantTransactionId) is required.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Force",
  "originalTransaction": {
    "transactionId": "00000000-0000-0000-0000-000000000abc"
  }
}
```

_Example: Repeat Sale (recurring)_

Single-message authorize-and-capture for a recurring/repeating customer charge. Used by recurring-billing flows; carries an InitiationType + MITReason to mark this as a merchant-initiated transaction (MIT) for scheme compliance.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "RepeatSale",
  "invoiceData": {
    "amounts": {
      "base": 19.99,
      "total": 19.99
    }
  },
  "originalTransaction": {
    "transactionId": "00000000-0000-0000-0000-000000000abc"
  },
  "initiationType": "MerchantInitiated",
  "mitReason": "Recurring"
}
```

_Example: Authorization with Stored Payment Token_

Authorization using a previously stored payment method. Send only the payment token (TokenData.Token); the server resolves the card data from the stored payment method at the customer/payment-method level, so you do not send PAN/CVV.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Authorization",
  "tokenData": {
    "token": "00000000-0000-0000-0000-0000000000a1"
  },
  "invoiceData": {
    "customerId": "00000000-0000-0000-0000-000000000c01",
    "amounts": {
      "base": 75,
      "total": 75
    }
  },
  "initiationType": "CardholderInitiated"
}
```

_Example: Authorization with Level 3 Data_

Commercial-card authorization with Level 2 (tax) and Level 3 (line items) data. Submitting Level 3 typically qualifies the transaction for lower interchange rates on B2B card categories.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Authorization",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "Acme Corp",
    "entryMode": "Manual",
    "cvPresence": "Submitted",
    "billingAddress": {
      "address1": "1 Corporate Way",
      "city": "Phoenix",
      "state": "AZ",
      "zip": "85027",
      "country": "USA"
    }
  },
  "invoiceData": {
    "amounts": {
      "base": 250,
      "tax": 20.62,
      "shipping": 12.5,
      "total": 283.12
    },
    "shippingAddress": {
      "address1": "200 Shipping Ln",
      "city": "Reno",
      "state": "NV",
      "zip": "89501",
      "country": "USA"
    }
  },
  "level2Data": {
    "poNumber": "PO-2026-001",
    "transactionDate": "2026-01-15"
  },
  "level3Data": {
    "shipFromZip": "85027",
    "destinationZip": "89501",
    "destinationCountryCode": "USA",
    "invoiceNumber": "INV-2026-7788",
    "orderNumber": "ORD-2026-7788",
    "freightAmount": 12.5,
    "lineItems": [
      {
        "productCode": "SKU-001",
        "description": "Widget Standard",
        "quantity": 5,
        "unitOfMeasure": "EA",
        "unitPrice": 30,
        "totalAmount": 150,
        "taxAmount": 12.37,
        "taxRate": 0.0825
      },
      {
        "productCode": "SKU-002",
        "description": "Widget Premium",
        "quantity": 2,
        "unitOfMeasure": "EA",
        "unitPrice": 50,
        "totalAmount": 100,
        "taxAmount": 8.25,
        "taxRate": 0.0825
      }
    ]
  }
}
```

_Example: ACH / eCheck Sale_

Single-message ACH debit (eCheck) against a US checking or savings account. Supplies CheckData rather than CardData; routing and account numbers are required.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Sale",
  "checkData": {
    "nameOnCheck": "John Doe",
    "routingNumber": "021000021",
    "accountNumber": "123456789",
    "checkNumber": "1001",
    "checkType": "Personal",
    "accountType": "Checking",
    "emailAddress": "john.doe@example.com",
    "address": {
      "address1": "123 Main St",
      "city": "Phoenix",
      "state": "AZ",
      "zip": "85027",
      "country": "USA"
    },
    "secCode": "Web"
  },
  "invoiceData": {
    "amounts": {
      "base": 100,
      "total": 100
    }
  }
}
```

**Content type:** `text/json`

Schema: `TransactionCreateDto`

Properties:
- `currentStage` (object): Gets or sets the current stage of the transaction within the create or update workflow.
- `history` (array<TransactionHistoryItem>): Gets or sets the transaction history entries associated with the transaction.
- `appliedPatches` (array<TransactionPatchSnapshot>): Gets or sets the collection of patch snapshots that have been applied to the transaction.
- `merchantId` (string(uuid)): The unique identifier of the merchant associated with the transaction.
- `transactionType` (object): The type of transaction being performed. Conditional: When RequestedSplitTenderTotal is not null. Must equal Sale. Conditional: Conditional (see validator source).
- `description` (string): Optional free-text description of what this payment is for, at most 100 characters.
- `merchantReference` (string): Optional merchant-supplied reference for reconciliation, at most 25 characters, letters  and digits only.
- `tender` (object): Optionally declares that this transaction is taken in cash. The only accepted value is  `Cash`. Omit the field for every card, check, and token transaction.
- `cardData` (object): Card data associated with the transaction. Conditional: When CardData is not null. Required: Conditional (see validator source).
- `checkData` (object): Check data associated with the transaction. Conditional: When CheckData is not null. Conditional: Conditional (see validator source). Conditional: When TransactionType == VoucherClear. Required: When TransactionType == Payout.
- `cashData` (object): Cash sale details: the cash handed over, the change returned, and when the cash was taken.
- `tokenData` (object): Tokenized payment details, used to charge a stored credential instead of raw card data. Conditional: When TokenData is not null.
- `deviceData` (object): Device data for the transaction. Conditional: When DeviceData is not null.
- `fsa` (object): FSA (Flexible Spending Account) data for the transaction.
- `lodging` (object): Lodging detail for a stay-related transaction, for merchants transacting under a lodging  industry. Conditional: When Lodging is not null.
- `softDescriptor` (object): Soft descriptor information for the transaction.
- `duplicateCheck` (boolean): Indicates whether to perform a duplicate check for the transaction. Omit the field to  let the merchant's screening configuration decide, which is what happens today. Send  false to waive the check, which the merchant must have permitted. Sending true never  turns screening on for a merchant who has not configured it.
- `register` (object): Register information for the transaction.
- `invoiceData` (object): Invoice data associated with the transaction, carrying the customer and the amounts. Required: Conditional (see validator source).
- `originalTransaction` (object): Data about the original transaction, if applicable.
- `customFields` (array<TrxCustomField>): Custom fields for the transaction. Conditional: When CustomFields is not null.
- `signatureData` (object): Signature data for the transaction.
- `level2Data` (object): Level 2 data for the transaction (e.g., tax, purchase order).
- `level3Data` (object): Level 3 data for the transaction (e.g., line item details).
- `ebt` (object): EBT voucher data for the transaction (offline SNAP / Cash voucher-clear flow).
- `useInterchangeDefaults` (boolean): Indicates whether to use interchange defaults for the transaction.
- `skipOrderDataDefaults` (boolean): When true, the server does not apply the merchant's configured Level 2/3 defaults to  the transaction. Set by the Virtual Terminal when the operator chose "Enter Manually"  in the BIN-driven prompt. API submissions usually leave this null.
- `captureType` (object): The capture type for the transaction.
- `responseData` (object): Response data for the transaction.
- `settleData` (object): Settlement data for the transaction.
- `processorKey` (string): The processor type key (e.g. "tsys", "fiserv") that processed this transaction.  Display-only: set during authorization and not modifiable via create/update.
- `sourceData` (object): Gets or sets the source data associated with the transaction. Conditional: When SourceData is not null.
- `tags` (array<EntityTag>): Tags associated with the transaction.
- `notes` (array<EntityNote>): Notes associated with the transaction.
- `merchantTransactionId` (integer(int64)): The unique identifier of the merchant transaction.
- `idempotencyKey` (string): Your own identifier for this create request, used to make a retry safe. Send the same value  again and the gateway returns the transaction the first request produced instead of charging a  second time. This is the recommended pattern for reconciling a create whose response you never  received.
- `receiptIds` (array<string>): List of receipt IDs generated for this transaction. Used for point-read access to receipts.  Stored as strings: see `receiptIds` remarks for rationale.  Read-only: set by the server; ignored on the AutoMapper write maps.
- `decisionNotes` (array<TransactionDecisionNote>): System-emitted decision explanations recorded against this transaction, surfaced  read-only on the transaction-detail view. Like `receiptIds`, this is server state:  it is populated on load for display but ignored on the create/update write maps, so a client  can never persist decision notes.
- `initiationType` (object): Identifies whether this transaction was initiated by the cardholder (CIT) or the merchant (MIT).
- `mitReason` (object): For merchant-initiated transactions, the reason code justifying the MIT. Null for CITs.
- `storedCredentialConsentId` (string(uuid)): Reference to the `StoredCredentialConsent` that authorizes this MIT. Null for CITs.  Optional, and best omitted: when it is absent the server resolves the consent from the stored  credential itself (resolved from the token plus `InvoiceData.CustomerId`) and selects the  most recently captured one that permits the declared MIT reason. Send a value only to pin a  specific consent when the credential carries several, for example after a re-enrollment, and  only when the value is a consent identifier this platform issued for that same credential  (from a capture response, a consent lookup, or a webhook). A supplied value is validated  strictly and is rejected if it belongs to a different credential, has been revoked, or does  not permit the declared reason. Note that a credential whose consent lineage predates this  platform's consent tracking has no consent record at all: an identifier minted by a prior  system is never valid here, so such a charge is rejected with  `stored_credential_consent_required` whether or not this field is sent. Remediate by  having the merchant attest the credential, which mints a new platform consent; the charge then  succeeds with the field omitted, and the newly issued identifier is accepted when sent.
- `schemeTransactionId` (string): The card network's trace ID for this transaction chain. Captured from the processor response  on the initial CIT and referenced on subsequent MITs.  Read-only: set by the server; ignored on the AutoMapper write maps.
- `cardholderPresence` (object): How present the cardholder is at the point of sale, separate from the physical entry mode.  Drives network-level presence indicators (e.g. TSYS `POSEnvironmentIndicator`) at auth  time. `null` means "let the classifier infer from EntryMode + Source". Conditional: When CardholderPresence is not null.
- `specialCondition` (object): Visa/MC special-condition tag (quasi-cash, quasi-MOTO). `null` defaults to  `None`. Drives TSYS  `SpecialConditionIndicator` + `CardholderId` when set to  `QuasiCash`. Conditional: When SpecialCondition is not null.
- `processorCertificationOverrides` (object): Per-processor certification override knobs. Production traffic must leave this  `null`; `ICertificationOverridesGate` rejects requests where  it is set unless the merchant is flagged as a test merchant AND the active processor  profile has `AcceptCertificationOverrides` enabled.
- `cumulativeRefundedAmount` (number(double)): Running total of refund amounts applied to this transaction.  Read-only: computed from refund operations.
- `cumulativeReversedAmount` (number(double)): Running total of reversal amounts applied to this transaction.  Read-only: computed from reversal operations.
- `authorizedAmount` (number(double)): The immutable amount the issuer authorised at the close of the Authorization stage.  Read-only: set once at `CloseAuthorization`. UI uses this rather than  `ResponseData.Amounts.Approved` for remaining-balance calculations because  reversal contributors overwrite `/ResponseData` with the processor's  reversal-response payload.
- `saveCardRequested` (boolean): Operator (VT) or cardholder (HPP) opt-in to save the card for future merchant-initiated  use. Honored only from the Virtual Terminal and the Hosted Payment Page, which capture the  required cardholder consent; a transaction create API request that sets it to true is  rejected with a validation error. Auth-time-only: it cannot be set on updates or on  subsequent operations.
- `isAccountVerification` (boolean): When `true`, this transaction is a zero-dollar account verification  rather than a charge: the gateway authorizes for $0 to confirm card validity (with  AVS/CVV) and immediately voids the authorization. Used by the Hosted Payment Page  "save card only: don't charge me" flow to vault a card without charging it. Mutually  exclusive with a non-zero amount. Auth-time-only: the AutoMapper Update and  recurring-billing maps both ignore it so it cannot be set on subsequent operations.  `null` (the default) is an ordinary chargeable transaction.
- `convenienceFeeDisclosureAcknowledgedAt` (string(date-time)): UTC timestamp of the moment the payer accepted the disclosed convenience fee (the  confirm-click, NOT the submit). This is the caller's attestation that the fee was disclosed  and agreed to, and it is <b>required</b> on any request charging a non-zero  `invoiceData.amounts.convenience` on a card tender, alongside  `convenienceFeeDisclosureChannel`. The Virtual Terminal stamps it from its  confirm modal (the CSR attesting as the cardholder's proxy) and the Hosted Payment Page from  the cardholder's own acceptance; a direct API integration owns its own disclosure UX and  supplies the same attestation. It may not sit more than a few minutes ahead of the gateway's  clock: a disclosure cannot have been accepted after the request that reports it.     Auth-time-only: the AutoMapper Update and recurring-billing maps both ignore it, so it cannot  be set on subsequent operations. `null` when no fee was charged. An ACH /  e-check debit is out of scope; a convenience fee on an EBT / eWIC tender is prohibited  outright and rejected before this field is examined.
- `convenienceFeeDisclosureChannel` (string): The surface on which the convenience-fee disclosure was shown and accepted. One of  `"VirtualTerminal"`, `"HostedPaymentPage"`, or `"Api"` (a direct integration's  own checkout); matched case-insensitively, and any other value is rejected. Paired with  `convenienceFeeDisclosureAcknowledgedAt` and required on the same requests.  Auth-time-only.
- `convenienceFeeEligibilitySnapshot` (string): Serialized convenience-fee eligibility decision (reason code + assessed amount) captured  at disclosure-acknowledgment time. Codes / amounts only: no request- or response-derived  free text (PCI). Gateway-produced and optional: the Virtual Terminal and Hosted Payment Page  serialize their own fee decision into it, and a direct API integration has no equivalent  internal decision to record, so it is never required. Auth-time-only.
- `convenienceFeeCancelledAmount` (number(double)): The convenience-fee amount, in the transaction currency, the Virtual Terminal operator declined  on the disclosure-confirm modal, removing it from this submission. Set by the VT cancel path (button, X, or Esc) so the  authorization pipeline can record a `CsrCancelledVtModal` convenience-fee decision note  carrying the amount that was waived: the fee is gone from the amounts by submit time, so the  evaluator has nothing left to explain without this marker.     Audit-only. It never adds to any total, never reaches the processor, and is honoured only when  the submitted transaction carries no convenience fee, originates from the Virtual Terminal, and  belongs to a merchant with an active convenience-fee configuration. Auth-time-only: the  AutoMapper Update and recurring-billing maps both ignore it. `null` (the  default) on every submission where no disclosed fee was cancelled.
- `surchargeDisclosureAcknowledgedAt` (string(date-time)): UTC timestamp captured at the surcharge disclosure confirm-click moment (NOT at submit). Set  by the Virtual Terminal confirm modal / HPP acceptance when a surcharge is disclosed and  agreed. Auth-time-only: the AutoMapper Update and recurring-billing maps both ignore it so  it cannot be set on subsequent operations. `null` when no surcharge  disclosure was acknowledged.
- `surchargeDisclosureChannel` (string): Channel on which the surcharge disclosure was acknowledged (`"VirtualTerminal"`,  `"HostedPaymentPage"`, or `"Api"`). Paired with  `surchargeDisclosureAcknowledgedAt`. Auth-time-only.
- `achWebAuthorizationText` (string): The NACHA WEB single-debit authorization language shown to the payer, captured verbatim at  ACH submit on the Hosted Payment Page. The consent evidence NACHA requires to substantiate an  internet-initiated (WEB) ACH debit. Auth-time-only: the AutoMapper Update and  recurring-billing maps both ignore it so it cannot be set on subsequent operations.  `null` for non-ACH tenders. PCI-safe: authorization language only.
- `achWebAuthorizationTextVersion` (string): Stable version hash (`sha256:{hex}`) of `achWebAuthorizationText`. Auth-time-only.
- `achWebAuthorizationConsumerIp` (string): Consumer IP recorded at ACH WEB authorization time (required NACHA evidence). On the anonymous  Hosted Payment Page create path the server derives this from the incoming request and ignores  a caller-supplied value. Auth-time-only. `null` for non-ACH tenders.
- `achWebAuthorizationAt` (string(date-time)): UTC timestamp of the ACH WEB authorization. Server-stamped on create; a client-supplied value  is never trusted. Auth-time-only. `null` for non-ACH tenders.
- `achWebAuthorizationSecCode` (string): SEC code the ACH WEB authorization was captured under (always `"WEB"` for HPP ACH).  Auth-time-only. `null` for non-ACH tenders.
- `achAuthorizationAttested` (boolean): Operator attestation signal for a Virtual Terminal CSR-keyed ACH debit: `true` when the  operator confirmed they obtained the account holder's authorization (TEL or PPD) for the debit.  This is a transient <b>input</b> only: the server consumes it to gate the submit (fail-closed  when a VT ACH debit is not attested) and to stamp the persisted `AchAuthorization*`  evidence fields; it is never persisted on its own. `null` / `false` for  non-VT-ACH tenders and for callers that do not attest.
- `achAuthorizationStatementText` (string): The CSR attestation statement captured for a Virtual Terminal CSR-keyed ACH debit (NACHA TEL /  PPD). Server-owned: rendered from the selected SEC code and stamped at create time, never  trusted from the client. Auth-time-only: the AutoMapper Update and recurring-billing maps both  ignore it so it cannot be set on subsequent operations. `null` for non-VT-ACH  tenders. PCI-safe: authorization language only.
- `achAuthorizationStatementVersion` (string): Stable version hash (`sha256:{hex}`) of `achAuthorizationStatementText`.  Server-recomputed from the statement text; a client-supplied value is never trusted.  Auth-time-only.
- `achAuthorizationSecCode` (string): SEC code the VT ACH authorization was captured under (`"TEL"` or `"PPD"`).  Server-owned from the operator's selection on `CheckData.SecCode`. Auth-time-only.  `null` for non-VT-ACH tenders.
- `achAuthorizationChannel` (string): Channel on which the VT ACH authorization was attested (`"VirtualTerminal"`). Server-owned.  Auth-time-only. `null` for non-VT-ACH tenders.
- `achAuthorizationAt` (string(date-time)): UTC timestamp of the VT ACH authorization. Server-stamped on create; a client-supplied value is  never trusted. Auth-time-only. `null` for non-VT-ACH tenders.
- `requestedSplitTenderTotal` (number(double)): The total of the whole order, when you know before submitting that the customer will pay  for it with more than one card. This transaction is charged for its own amount; once it is  approved, it stays open as the first payment of a split tender collecting toward this  total, and each further card is posted to  `POST /api/transactions/{id}/split-tender/continuations`. Conditional: When RequestedSplitTenderTotal is not null.
- `deferPartialApprovalAcknowledgment` (boolean): Set to `true` to decide a partial approval yourself instead of having it accepted for  you. When the issuer approves less than the requested amount, the transaction then waits in  the `SplitTenderPending` stage, and `partialApprovalData.dispositionDeadlineUtc`  says when it will be voided automatically. Before then, decide it through  `POST /api/transactions/{id}/partial-approval/accept`, `/void`, or  `/split-tender`.

_Example: Visa Authorization_

Card-not-present authorization (hold funds without capturing). Use this when you intend to capture the funds in a later step (typical for shipped goods).

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Authorization",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "duplicateCheck": true,
  "invoiceData": {
    "amounts": {
      "base": 1,
      "total": 1
    }
  }
}
```

_Example: MasterCard Authorization_

Authorization-only request using a MasterCard test PAN.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Authorization",
  "cardData": {
    "cardNumber": "5454545454545454",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "duplicateCheck": true,
  "invoiceData": {
    "amounts": {
      "base": 1,
      "total": 1
    }
  }
}
```

_Example: Discover Authorization_

Authorization-only request using a Discover test PAN.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Authorization",
  "cardData": {
    "cardNumber": "6011000990139424",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "duplicateCheck": true,
  "invoiceData": {
    "amounts": {
      "base": 1,
      "total": 1
    }
  }
}
```

_Example: Amex Authorization_

Authorization-only request using an American Express test PAN. Amex CVV is 4 digits.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Authorization",
  "cardData": {
    "cardNumber": "378282246310005",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "1234",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "duplicateCheck": true,
  "invoiceData": {
    "amounts": {
      "base": 1,
      "total": 1
    }
  }
}
```

_Example: Sale (single-message Auth+Capture)_

Single-message authorize-and-capture in one round trip. The most common production transaction type for retail and e-commerce checkouts where goods/services are delivered immediately.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Sale",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted",
    "billingAddress": {
      "address1": "123 Main St",
      "city": "Phoenix",
      "state": "AZ",
      "zip": "85027",
      "country": "USA"
    }
  },
  "duplicateCheck": true,
  "invoiceData": {
    "amounts": {
      "base": 49.99,
      "tax": 4.12,
      "total": 54.11
    },
    "isTaxExempt": false
  }
}
```

_Example: Planned split tender (first card)_

The first card of an order the customer is paying for with more than one card. requestedSplitTenderTotal declares the whole order; this card is charged for its own amount and, once approved, stays open as the first payment of a split tender. Post each further card to POST /api/transactions/{id}/split-tender/continuations with this transaction's id, until the payments reach the order total.

```json
{
  "requestedSplitTenderTotal": 100,
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Sale",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "invoiceData": {
    "amounts": {
      "base": 60,
      "total": 60
    }
  }
}
```

_Example: Sale that decides a partial approval itself_

A sale whose caller decides a partial approval itself. If the issuer approves less than the amount, the transaction waits in the SplitTenderPending stage until partialApprovalData.dispositionDeadlineUtc. Accept it, void it, or start a split tender through POST /api/transactions/{id}/partial-approval/accept, /void, or /split-tender. Without the flag, an API sale keeps a partial approval for the approved amount.

```json
{
  "deferPartialApprovalAcknowledgment": true,
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Sale",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "invoiceData": {
    "amounts": {
      "base": 75,
      "total": 75
    }
  }
}
```

_Example: Sale with Tip_

Single-message Sale carrying a tip. Total is computed by the server as Base + Tip + Tax + Shipping + Convenience.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Sale",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "Jane Smith",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "invoiceData": {
    "amounts": {
      "base": 25,
      "tip": 5,
      "tax": 2.06,
      "total": 32.06
    }
  }
}
```

_Example: Capture (follow-up to Authorization)_

Captures funds from a prior Authorization. Card data is inherited from the original transaction; only the OriginalTransaction.TransactionId is required. Send a partial-capture amount via InvoiceData.Amounts.Base when capturing less than the original auth.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Capture",
  "originalTransaction": {
    "transactionId": "00000000-0000-0000-0000-000000000abc"
  }
}
```

_Example: Return / Refund_

Refunds a previously settled transaction back to the cardholder. References the original transaction by id; amount may be partial or full.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Return",
  "invoiceData": {
    "amounts": {
      "base": 49.99,
      "total": 49.99
    }
  },
  "originalTransaction": {
    "transactionId": "00000000-0000-0000-0000-000000000abc"
  }
}
```

_Example: Reversal (full)_

Undo a prior auth/capture. Submit TransactionType.Void; the gateway issues an online reversal (0420-equivalent message, releases the issuer hold) when the processor supports it, and falls back to an offline batch-close exclusion only when the processor declares it cannot service the online reversal. Omit InvoiceData.Amounts to undo the full authorized amount.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Void",
  "originalTransaction": {
    "transactionId": "00000000-0000-0000-0000-000000000abc"
  }
}
```

_Example: Reversal (partial)_

Reverses only part of a prior authorization, leaving the un-reversed remainder available for capture/settlement. Send the partial amount via InvoiceData.Amounts.Base. Requires a processor that advertises SupportsPartialReversal; the same TransactionType.Void shape is used as the full-amount reversal.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Void",
  "invoiceData": {
    "amounts": {
      "base": 25,
      "total": 25
    }
  },
  "originalTransaction": {
    "transactionId": "00000000-0000-0000-0000-000000000abc"
  }
}
```

_Example: Force - Voice-Auth Capture_

Voice-authorization Force: the merchant obtained a verbal approval code from the issuer over the phone and is now submitting the transaction. Supplies fresh card data, fresh InvoiceData, and the issuer-provided AuthCode. There is NO prior gateway transaction.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Force",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "invoiceData": {
    "amounts": {
      "base": 100,
      "total": 100
    }
  },
  "originalTransaction": {
    "authCode": "AB1234"
  }
}
```

_Example: Force - Gateway-Capture (follow-up to Authorization)_

Gateway-Capture-as-Force: a follow-up to a prior gateway Authorization that maps to TransactionOperationType.Capture internally. Card data and amount are inherited from the resolved prior transaction - only OriginalTransaction.TransactionId (or MerchantTransactionId) is required.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Force",
  "originalTransaction": {
    "transactionId": "00000000-0000-0000-0000-000000000abc"
  }
}
```

_Example: Repeat Sale (recurring)_

Single-message authorize-and-capture for a recurring/repeating customer charge. Used by recurring-billing flows; carries an InitiationType + MITReason to mark this as a merchant-initiated transaction (MIT) for scheme compliance.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "RepeatSale",
  "invoiceData": {
    "amounts": {
      "base": 19.99,
      "total": 19.99
    }
  },
  "originalTransaction": {
    "transactionId": "00000000-0000-0000-0000-000000000abc"
  },
  "initiationType": "MerchantInitiated",
  "mitReason": "Recurring"
}
```

_Example: Authorization with Stored Payment Token_

Authorization using a previously stored payment method. Send only the payment token (TokenData.Token); the server resolves the card data from the stored payment method at the customer/payment-method level, so you do not send PAN/CVV.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Authorization",
  "tokenData": {
    "token": "00000000-0000-0000-0000-0000000000a1"
  },
  "invoiceData": {
    "customerId": "00000000-0000-0000-0000-000000000c01",
    "amounts": {
      "base": 75,
      "total": 75
    }
  },
  "initiationType": "CardholderInitiated"
}
```

_Example: Authorization with Level 3 Data_

Commercial-card authorization with Level 2 (tax) and Level 3 (line items) data. Submitting Level 3 typically qualifies the transaction for lower interchange rates on B2B card categories.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Authorization",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "Acme Corp",
    "entryMode": "Manual",
    "cvPresence": "Submitted",
    "billingAddress": {
      "address1": "1 Corporate Way",
      "city": "Phoenix",
      "state": "AZ",
      "zip": "85027",
      "country": "USA"
    }
  },
  "invoiceData": {
    "amounts": {
      "base": 250,
      "tax": 20.62,
      "shipping": 12.5,
      "total": 283.12
    },
    "shippingAddress": {
      "address1": "200 Shipping Ln",
      "city": "Reno",
      "state": "NV",
      "zip": "89501",
      "country": "USA"
    }
  },
  "level2Data": {
    "poNumber": "PO-2026-001",
    "transactionDate": "2026-01-15"
  },
  "level3Data": {
    "shipFromZip": "85027",
    "destinationZip": "89501",
    "destinationCountryCode": "USA",
    "invoiceNumber": "INV-2026-7788",
    "orderNumber": "ORD-2026-7788",
    "freightAmount": 12.5,
    "lineItems": [
      {
        "productCode": "SKU-001",
        "description": "Widget Standard",
        "quantity": 5,
        "unitOfMeasure": "EA",
        "unitPrice": 30,
        "totalAmount": 150,
        "taxAmount": 12.37,
        "taxRate": 0.0825
      },
      {
        "productCode": "SKU-002",
        "description": "Widget Premium",
        "quantity": 2,
        "unitOfMeasure": "EA",
        "unitPrice": 50,
        "totalAmount": 100,
        "taxAmount": 8.25,
        "taxRate": 0.0825
      }
    ]
  }
}
```

_Example: ACH / eCheck Sale_

Single-message ACH debit (eCheck) against a US checking or savings account. Supplies CheckData rather than CardData; routing and account numbers are required.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Sale",
  "checkData": {
    "nameOnCheck": "John Doe",
    "routingNumber": "021000021",
    "accountNumber": "123456789",
    "checkNumber": "1001",
    "checkType": "Personal",
    "accountType": "Checking",
    "emailAddress": "john.doe@example.com",
    "address": {
      "address1": "123 Main St",
      "city": "Phoenix",
      "state": "AZ",
      "zip": "85027",
      "country": "USA"
    },
    "secCode": "Web"
  },
  "invoiceData": {
    "amounts": {
      "base": 100,
      "total": 100
    }
  }
}
```

**Content type:** `application/*+json`

Schema: `TransactionCreateDto`

Properties:
- `currentStage` (object): Gets or sets the current stage of the transaction within the create or update workflow.
- `history` (array<TransactionHistoryItem>): Gets or sets the transaction history entries associated with the transaction.
- `appliedPatches` (array<TransactionPatchSnapshot>): Gets or sets the collection of patch snapshots that have been applied to the transaction.
- `merchantId` (string(uuid)): The unique identifier of the merchant associated with the transaction.
- `transactionType` (object): The type of transaction being performed. Conditional: When RequestedSplitTenderTotal is not null. Must equal Sale. Conditional: Conditional (see validator source).
- `description` (string): Optional free-text description of what this payment is for, at most 100 characters.
- `merchantReference` (string): Optional merchant-supplied reference for reconciliation, at most 25 characters, letters  and digits only.
- `tender` (object): Optionally declares that this transaction is taken in cash. The only accepted value is  `Cash`. Omit the field for every card, check, and token transaction.
- `cardData` (object): Card data associated with the transaction. Conditional: When CardData is not null. Required: Conditional (see validator source).
- `checkData` (object): Check data associated with the transaction. Conditional: When CheckData is not null. Conditional: Conditional (see validator source). Conditional: When TransactionType == VoucherClear. Required: When TransactionType == Payout.
- `cashData` (object): Cash sale details: the cash handed over, the change returned, and when the cash was taken.
- `tokenData` (object): Tokenized payment details, used to charge a stored credential instead of raw card data. Conditional: When TokenData is not null.
- `deviceData` (object): Device data for the transaction. Conditional: When DeviceData is not null.
- `fsa` (object): FSA (Flexible Spending Account) data for the transaction.
- `lodging` (object): Lodging detail for a stay-related transaction, for merchants transacting under a lodging  industry. Conditional: When Lodging is not null.
- `softDescriptor` (object): Soft descriptor information for the transaction.
- `duplicateCheck` (boolean): Indicates whether to perform a duplicate check for the transaction. Omit the field to  let the merchant's screening configuration decide, which is what happens today. Send  false to waive the check, which the merchant must have permitted. Sending true never  turns screening on for a merchant who has not configured it.
- `register` (object): Register information for the transaction.
- `invoiceData` (object): Invoice data associated with the transaction, carrying the customer and the amounts. Required: Conditional (see validator source).
- `originalTransaction` (object): Data about the original transaction, if applicable.
- `customFields` (array<TrxCustomField>): Custom fields for the transaction. Conditional: When CustomFields is not null.
- `signatureData` (object): Signature data for the transaction.
- `level2Data` (object): Level 2 data for the transaction (e.g., tax, purchase order).
- `level3Data` (object): Level 3 data for the transaction (e.g., line item details).
- `ebt` (object): EBT voucher data for the transaction (offline SNAP / Cash voucher-clear flow).
- `useInterchangeDefaults` (boolean): Indicates whether to use interchange defaults for the transaction.
- `skipOrderDataDefaults` (boolean): When true, the server does not apply the merchant's configured Level 2/3 defaults to  the transaction. Set by the Virtual Terminal when the operator chose "Enter Manually"  in the BIN-driven prompt. API submissions usually leave this null.
- `captureType` (object): The capture type for the transaction.
- `responseData` (object): Response data for the transaction.
- `settleData` (object): Settlement data for the transaction.
- `processorKey` (string): The processor type key (e.g. "tsys", "fiserv") that processed this transaction.  Display-only: set during authorization and not modifiable via create/update.
- `sourceData` (object): Gets or sets the source data associated with the transaction. Conditional: When SourceData is not null.
- `tags` (array<EntityTag>): Tags associated with the transaction.
- `notes` (array<EntityNote>): Notes associated with the transaction.
- `merchantTransactionId` (integer(int64)): The unique identifier of the merchant transaction.
- `idempotencyKey` (string): Your own identifier for this create request, used to make a retry safe. Send the same value  again and the gateway returns the transaction the first request produced instead of charging a  second time. This is the recommended pattern for reconciling a create whose response you never  received.
- `receiptIds` (array<string>): List of receipt IDs generated for this transaction. Used for point-read access to receipts.  Stored as strings: see `receiptIds` remarks for rationale.  Read-only: set by the server; ignored on the AutoMapper write maps.
- `decisionNotes` (array<TransactionDecisionNote>): System-emitted decision explanations recorded against this transaction, surfaced  read-only on the transaction-detail view. Like `receiptIds`, this is server state:  it is populated on load for display but ignored on the create/update write maps, so a client  can never persist decision notes.
- `initiationType` (object): Identifies whether this transaction was initiated by the cardholder (CIT) or the merchant (MIT).
- `mitReason` (object): For merchant-initiated transactions, the reason code justifying the MIT. Null for CITs.
- `storedCredentialConsentId` (string(uuid)): Reference to the `StoredCredentialConsent` that authorizes this MIT. Null for CITs.  Optional, and best omitted: when it is absent the server resolves the consent from the stored  credential itself (resolved from the token plus `InvoiceData.CustomerId`) and selects the  most recently captured one that permits the declared MIT reason. Send a value only to pin a  specific consent when the credential carries several, for example after a re-enrollment, and  only when the value is a consent identifier this platform issued for that same credential  (from a capture response, a consent lookup, or a webhook). A supplied value is validated  strictly and is rejected if it belongs to a different credential, has been revoked, or does  not permit the declared reason. Note that a credential whose consent lineage predates this  platform's consent tracking has no consent record at all: an identifier minted by a prior  system is never valid here, so such a charge is rejected with  `stored_credential_consent_required` whether or not this field is sent. Remediate by  having the merchant attest the credential, which mints a new platform consent; the charge then  succeeds with the field omitted, and the newly issued identifier is accepted when sent.
- `schemeTransactionId` (string): The card network's trace ID for this transaction chain. Captured from the processor response  on the initial CIT and referenced on subsequent MITs.  Read-only: set by the server; ignored on the AutoMapper write maps.
- `cardholderPresence` (object): How present the cardholder is at the point of sale, separate from the physical entry mode.  Drives network-level presence indicators (e.g. TSYS `POSEnvironmentIndicator`) at auth  time. `null` means "let the classifier infer from EntryMode + Source". Conditional: When CardholderPresence is not null.
- `specialCondition` (object): Visa/MC special-condition tag (quasi-cash, quasi-MOTO). `null` defaults to  `None`. Drives TSYS  `SpecialConditionIndicator` + `CardholderId` when set to  `QuasiCash`. Conditional: When SpecialCondition is not null.
- `processorCertificationOverrides` (object): Per-processor certification override knobs. Production traffic must leave this  `null`; `ICertificationOverridesGate` rejects requests where  it is set unless the merchant is flagged as a test merchant AND the active processor  profile has `AcceptCertificationOverrides` enabled.
- `cumulativeRefundedAmount` (number(double)): Running total of refund amounts applied to this transaction.  Read-only: computed from refund operations.
- `cumulativeReversedAmount` (number(double)): Running total of reversal amounts applied to this transaction.  Read-only: computed from reversal operations.
- `authorizedAmount` (number(double)): The immutable amount the issuer authorised at the close of the Authorization stage.  Read-only: set once at `CloseAuthorization`. UI uses this rather than  `ResponseData.Amounts.Approved` for remaining-balance calculations because  reversal contributors overwrite `/ResponseData` with the processor's  reversal-response payload.
- `saveCardRequested` (boolean): Operator (VT) or cardholder (HPP) opt-in to save the card for future merchant-initiated  use. Honored only from the Virtual Terminal and the Hosted Payment Page, which capture the  required cardholder consent; a transaction create API request that sets it to true is  rejected with a validation error. Auth-time-only: it cannot be set on updates or on  subsequent operations.
- `isAccountVerification` (boolean): When `true`, this transaction is a zero-dollar account verification  rather than a charge: the gateway authorizes for $0 to confirm card validity (with  AVS/CVV) and immediately voids the authorization. Used by the Hosted Payment Page  "save card only: don't charge me" flow to vault a card without charging it. Mutually  exclusive with a non-zero amount. Auth-time-only: the AutoMapper Update and  recurring-billing maps both ignore it so it cannot be set on subsequent operations.  `null` (the default) is an ordinary chargeable transaction.
- `convenienceFeeDisclosureAcknowledgedAt` (string(date-time)): UTC timestamp of the moment the payer accepted the disclosed convenience fee (the  confirm-click, NOT the submit). This is the caller's attestation that the fee was disclosed  and agreed to, and it is <b>required</b> on any request charging a non-zero  `invoiceData.amounts.convenience` on a card tender, alongside  `convenienceFeeDisclosureChannel`. The Virtual Terminal stamps it from its  confirm modal (the CSR attesting as the cardholder's proxy) and the Hosted Payment Page from  the cardholder's own acceptance; a direct API integration owns its own disclosure UX and  supplies the same attestation. It may not sit more than a few minutes ahead of the gateway's  clock: a disclosure cannot have been accepted after the request that reports it.     Auth-time-only: the AutoMapper Update and recurring-billing maps both ignore it, so it cannot  be set on subsequent operations. `null` when no fee was charged. An ACH /  e-check debit is out of scope; a convenience fee on an EBT / eWIC tender is prohibited  outright and rejected before this field is examined.
- `convenienceFeeDisclosureChannel` (string): The surface on which the convenience-fee disclosure was shown and accepted. One of  `"VirtualTerminal"`, `"HostedPaymentPage"`, or `"Api"` (a direct integration's  own checkout); matched case-insensitively, and any other value is rejected. Paired with  `convenienceFeeDisclosureAcknowledgedAt` and required on the same requests.  Auth-time-only.
- `convenienceFeeEligibilitySnapshot` (string): Serialized convenience-fee eligibility decision (reason code + assessed amount) captured  at disclosure-acknowledgment time. Codes / amounts only: no request- or response-derived  free text (PCI). Gateway-produced and optional: the Virtual Terminal and Hosted Payment Page  serialize their own fee decision into it, and a direct API integration has no equivalent  internal decision to record, so it is never required. Auth-time-only.
- `convenienceFeeCancelledAmount` (number(double)): The convenience-fee amount, in the transaction currency, the Virtual Terminal operator declined  on the disclosure-confirm modal, removing it from this submission. Set by the VT cancel path (button, X, or Esc) so the  authorization pipeline can record a `CsrCancelledVtModal` convenience-fee decision note  carrying the amount that was waived: the fee is gone from the amounts by submit time, so the  evaluator has nothing left to explain without this marker.     Audit-only. It never adds to any total, never reaches the processor, and is honoured only when  the submitted transaction carries no convenience fee, originates from the Virtual Terminal, and  belongs to a merchant with an active convenience-fee configuration. Auth-time-only: the  AutoMapper Update and recurring-billing maps both ignore it. `null` (the  default) on every submission where no disclosed fee was cancelled.
- `surchargeDisclosureAcknowledgedAt` (string(date-time)): UTC timestamp captured at the surcharge disclosure confirm-click moment (NOT at submit). Set  by the Virtual Terminal confirm modal / HPP acceptance when a surcharge is disclosed and  agreed. Auth-time-only: the AutoMapper Update and recurring-billing maps both ignore it so  it cannot be set on subsequent operations. `null` when no surcharge  disclosure was acknowledged.
- `surchargeDisclosureChannel` (string): Channel on which the surcharge disclosure was acknowledged (`"VirtualTerminal"`,  `"HostedPaymentPage"`, or `"Api"`). Paired with  `surchargeDisclosureAcknowledgedAt`. Auth-time-only.
- `achWebAuthorizationText` (string): The NACHA WEB single-debit authorization language shown to the payer, captured verbatim at  ACH submit on the Hosted Payment Page. The consent evidence NACHA requires to substantiate an  internet-initiated (WEB) ACH debit. Auth-time-only: the AutoMapper Update and  recurring-billing maps both ignore it so it cannot be set on subsequent operations.  `null` for non-ACH tenders. PCI-safe: authorization language only.
- `achWebAuthorizationTextVersion` (string): Stable version hash (`sha256:{hex}`) of `achWebAuthorizationText`. Auth-time-only.
- `achWebAuthorizationConsumerIp` (string): Consumer IP recorded at ACH WEB authorization time (required NACHA evidence). On the anonymous  Hosted Payment Page create path the server derives this from the incoming request and ignores  a caller-supplied value. Auth-time-only. `null` for non-ACH tenders.
- `achWebAuthorizationAt` (string(date-time)): UTC timestamp of the ACH WEB authorization. Server-stamped on create; a client-supplied value  is never trusted. Auth-time-only. `null` for non-ACH tenders.
- `achWebAuthorizationSecCode` (string): SEC code the ACH WEB authorization was captured under (always `"WEB"` for HPP ACH).  Auth-time-only. `null` for non-ACH tenders.
- `achAuthorizationAttested` (boolean): Operator attestation signal for a Virtual Terminal CSR-keyed ACH debit: `true` when the  operator confirmed they obtained the account holder's authorization (TEL or PPD) for the debit.  This is a transient <b>input</b> only: the server consumes it to gate the submit (fail-closed  when a VT ACH debit is not attested) and to stamp the persisted `AchAuthorization*`  evidence fields; it is never persisted on its own. `null` / `false` for  non-VT-ACH tenders and for callers that do not attest.
- `achAuthorizationStatementText` (string): The CSR attestation statement captured for a Virtual Terminal CSR-keyed ACH debit (NACHA TEL /  PPD). Server-owned: rendered from the selected SEC code and stamped at create time, never  trusted from the client. Auth-time-only: the AutoMapper Update and recurring-billing maps both  ignore it so it cannot be set on subsequent operations. `null` for non-VT-ACH  tenders. PCI-safe: authorization language only.
- `achAuthorizationStatementVersion` (string): Stable version hash (`sha256:{hex}`) of `achAuthorizationStatementText`.  Server-recomputed from the statement text; a client-supplied value is never trusted.  Auth-time-only.
- `achAuthorizationSecCode` (string): SEC code the VT ACH authorization was captured under (`"TEL"` or `"PPD"`).  Server-owned from the operator's selection on `CheckData.SecCode`. Auth-time-only.  `null` for non-VT-ACH tenders.
- `achAuthorizationChannel` (string): Channel on which the VT ACH authorization was attested (`"VirtualTerminal"`). Server-owned.  Auth-time-only. `null` for non-VT-ACH tenders.
- `achAuthorizationAt` (string(date-time)): UTC timestamp of the VT ACH authorization. Server-stamped on create; a client-supplied value is  never trusted. Auth-time-only. `null` for non-VT-ACH tenders.
- `requestedSplitTenderTotal` (number(double)): The total of the whole order, when you know before submitting that the customer will pay  for it with more than one card. This transaction is charged for its own amount; once it is  approved, it stays open as the first payment of a split tender collecting toward this  total, and each further card is posted to  `POST /api/transactions/{id}/split-tender/continuations`. Conditional: When RequestedSplitTenderTotal is not null.
- `deferPartialApprovalAcknowledgment` (boolean): Set to `true` to decide a partial approval yourself instead of having it accepted for  you. When the issuer approves less than the requested amount, the transaction then waits in  the `SplitTenderPending` stage, and `partialApprovalData.dispositionDeadlineUtc`  says when it will be voided automatically. Before then, decide it through  `POST /api/transactions/{id}/partial-approval/accept`, `/void`, or  `/split-tender`.

_Example: Visa Authorization_

Card-not-present authorization (hold funds without capturing). Use this when you intend to capture the funds in a later step (typical for shipped goods).

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Authorization",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "duplicateCheck": true,
  "invoiceData": {
    "amounts": {
      "base": 1,
      "total": 1
    }
  }
}
```

_Example: MasterCard Authorization_

Authorization-only request using a MasterCard test PAN.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Authorization",
  "cardData": {
    "cardNumber": "5454545454545454",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "duplicateCheck": true,
  "invoiceData": {
    "amounts": {
      "base": 1,
      "total": 1
    }
  }
}
```

_Example: Discover Authorization_

Authorization-only request using a Discover test PAN.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Authorization",
  "cardData": {
    "cardNumber": "6011000990139424",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "duplicateCheck": true,
  "invoiceData": {
    "amounts": {
      "base": 1,
      "total": 1
    }
  }
}
```

_Example: Amex Authorization_

Authorization-only request using an American Express test PAN. Amex CVV is 4 digits.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Authorization",
  "cardData": {
    "cardNumber": "378282246310005",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "1234",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "duplicateCheck": true,
  "invoiceData": {
    "amounts": {
      "base": 1,
      "total": 1
    }
  }
}
```

_Example: Sale (single-message Auth+Capture)_

Single-message authorize-and-capture in one round trip. The most common production transaction type for retail and e-commerce checkouts where goods/services are delivered immediately.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Sale",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted",
    "billingAddress": {
      "address1": "123 Main St",
      "city": "Phoenix",
      "state": "AZ",
      "zip": "85027",
      "country": "USA"
    }
  },
  "duplicateCheck": true,
  "invoiceData": {
    "amounts": {
      "base": 49.99,
      "tax": 4.12,
      "total": 54.11
    },
    "isTaxExempt": false
  }
}
```

_Example: Planned split tender (first card)_

The first card of an order the customer is paying for with more than one card. requestedSplitTenderTotal declares the whole order; this card is charged for its own amount and, once approved, stays open as the first payment of a split tender. Post each further card to POST /api/transactions/{id}/split-tender/continuations with this transaction's id, until the payments reach the order total.

```json
{
  "requestedSplitTenderTotal": 100,
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Sale",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "invoiceData": {
    "amounts": {
      "base": 60,
      "total": 60
    }
  }
}
```

_Example: Sale that decides a partial approval itself_

A sale whose caller decides a partial approval itself. If the issuer approves less than the amount, the transaction waits in the SplitTenderPending stage until partialApprovalData.dispositionDeadlineUtc. Accept it, void it, or start a split tender through POST /api/transactions/{id}/partial-approval/accept, /void, or /split-tender. Without the flag, an API sale keeps a partial approval for the approved amount.

```json
{
  "deferPartialApprovalAcknowledgment": true,
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Sale",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "invoiceData": {
    "amounts": {
      "base": 75,
      "total": 75
    }
  }
}
```

_Example: Sale with Tip_

Single-message Sale carrying a tip. Total is computed by the server as Base + Tip + Tax + Shipping + Convenience.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Sale",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "Jane Smith",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "invoiceData": {
    "amounts": {
      "base": 25,
      "tip": 5,
      "tax": 2.06,
      "total": 32.06
    }
  }
}
```

_Example: Capture (follow-up to Authorization)_

Captures funds from a prior Authorization. Card data is inherited from the original transaction; only the OriginalTransaction.TransactionId is required. Send a partial-capture amount via InvoiceData.Amounts.Base when capturing less than the original auth.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Capture",
  "originalTransaction": {
    "transactionId": "00000000-0000-0000-0000-000000000abc"
  }
}
```

_Example: Return / Refund_

Refunds a previously settled transaction back to the cardholder. References the original transaction by id; amount may be partial or full.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Return",
  "invoiceData": {
    "amounts": {
      "base": 49.99,
      "total": 49.99
    }
  },
  "originalTransaction": {
    "transactionId": "00000000-0000-0000-0000-000000000abc"
  }
}
```

_Example: Reversal (full)_

Undo a prior auth/capture. Submit TransactionType.Void; the gateway issues an online reversal (0420-equivalent message, releases the issuer hold) when the processor supports it, and falls back to an offline batch-close exclusion only when the processor declares it cannot service the online reversal. Omit InvoiceData.Amounts to undo the full authorized amount.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Void",
  "originalTransaction": {
    "transactionId": "00000000-0000-0000-0000-000000000abc"
  }
}
```

_Example: Reversal (partial)_

Reverses only part of a prior authorization, leaving the un-reversed remainder available for capture/settlement. Send the partial amount via InvoiceData.Amounts.Base. Requires a processor that advertises SupportsPartialReversal; the same TransactionType.Void shape is used as the full-amount reversal.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Void",
  "invoiceData": {
    "amounts": {
      "base": 25,
      "total": 25
    }
  },
  "originalTransaction": {
    "transactionId": "00000000-0000-0000-0000-000000000abc"
  }
}
```

_Example: Force - Voice-Auth Capture_

Voice-authorization Force: the merchant obtained a verbal approval code from the issuer over the phone and is now submitting the transaction. Supplies fresh card data, fresh InvoiceData, and the issuer-provided AuthCode. There is NO prior gateway transaction.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Force",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "invoiceData": {
    "amounts": {
      "base": 100,
      "total": 100
    }
  },
  "originalTransaction": {
    "authCode": "AB1234"
  }
}
```

_Example: Force - Gateway-Capture (follow-up to Authorization)_

Gateway-Capture-as-Force: a follow-up to a prior gateway Authorization that maps to TransactionOperationType.Capture internally. Card data and amount are inherited from the resolved prior transaction - only OriginalTransaction.TransactionId (or MerchantTransactionId) is required.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Force",
  "originalTransaction": {
    "transactionId": "00000000-0000-0000-0000-000000000abc"
  }
}
```

_Example: Repeat Sale (recurring)_

Single-message authorize-and-capture for a recurring/repeating customer charge. Used by recurring-billing flows; carries an InitiationType + MITReason to mark this as a merchant-initiated transaction (MIT) for scheme compliance.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "RepeatSale",
  "invoiceData": {
    "amounts": {
      "base": 19.99,
      "total": 19.99
    }
  },
  "originalTransaction": {
    "transactionId": "00000000-0000-0000-0000-000000000abc"
  },
  "initiationType": "MerchantInitiated",
  "mitReason": "Recurring"
}
```

_Example: Authorization with Stored Payment Token_

Authorization using a previously stored payment method. Send only the payment token (TokenData.Token); the server resolves the card data from the stored payment method at the customer/payment-method level, so you do not send PAN/CVV.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Authorization",
  "tokenData": {
    "token": "00000000-0000-0000-0000-0000000000a1"
  },
  "invoiceData": {
    "customerId": "00000000-0000-0000-0000-000000000c01",
    "amounts": {
      "base": 75,
      "total": 75
    }
  },
  "initiationType": "CardholderInitiated"
}
```

_Example: Authorization with Level 3 Data_

Commercial-card authorization with Level 2 (tax) and Level 3 (line items) data. Submitting Level 3 typically qualifies the transaction for lower interchange rates on B2B card categories.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Authorization",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "Acme Corp",
    "entryMode": "Manual",
    "cvPresence": "Submitted",
    "billingAddress": {
      "address1": "1 Corporate Way",
      "city": "Phoenix",
      "state": "AZ",
      "zip": "85027",
      "country": "USA"
    }
  },
  "invoiceData": {
    "amounts": {
      "base": 250,
      "tax": 20.62,
      "shipping": 12.5,
      "total": 283.12
    },
    "shippingAddress": {
      "address1": "200 Shipping Ln",
      "city": "Reno",
      "state": "NV",
      "zip": "89501",
      "country": "USA"
    }
  },
  "level2Data": {
    "poNumber": "PO-2026-001",
    "transactionDate": "2026-01-15"
  },
  "level3Data": {
    "shipFromZip": "85027",
    "destinationZip": "89501",
    "destinationCountryCode": "USA",
    "invoiceNumber": "INV-2026-7788",
    "orderNumber": "ORD-2026-7788",
    "freightAmount": 12.5,
    "lineItems": [
      {
        "productCode": "SKU-001",
        "description": "Widget Standard",
        "quantity": 5,
        "unitOfMeasure": "EA",
        "unitPrice": 30,
        "totalAmount": 150,
        "taxAmount": 12.37,
        "taxRate": 0.0825
      },
      {
        "productCode": "SKU-002",
        "description": "Widget Premium",
        "quantity": 2,
        "unitOfMeasure": "EA",
        "unitPrice": 50,
        "totalAmount": 100,
        "taxAmount": 8.25,
        "taxRate": 0.0825
      }
    ]
  }
}
```

_Example: ACH / eCheck Sale_

Single-message ACH debit (eCheck) against a US checking or savings account. Supplies CheckData rather than CardData; routing and account numbers are required.

```json
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Sale",
  "checkData": {
    "nameOnCheck": "John Doe",
    "routingNumber": "021000021",
    "accountNumber": "123456789",
    "checkNumber": "1001",
    "checkType": "Personal",
    "accountType": "Checking",
    "emailAddress": "john.doe@example.com",
    "address": {
      "address1": "123 Main St",
      "city": "Phoenix",
      "state": "AZ",
      "zip": "85027",
      "country": "USA"
    },
    "secCode": "Web"
  },
  "invoiceData": {
    "amounts": {
      "base": 100,
      "total": 100
    }
  }
}
```

## Responses

### 200

OK

**Content type:** `application/json`

Schema: `TransactionDto`

Properties:
- `id` (string(uuid))
- `creationTime` (string(date-time)): The date and time when this entity was created.
- `creatorId` (string(uuid)): The ID of the user who created this entity.
- `lastModificationTime` (string(date-time)): The date and time when this entity was last modified.
- `lastModifierId` (string(uuid)): The ID of the user who last modified this entity.
- `isDeleted` (boolean): Indicates whether this entity has been deleted.
- `deleterId` (string(uuid)): The ID of the user who deleted this entity, if it is deleted.
- `deletionTime` (string(date-time)): The date and time when this entity was deleted, if it is deleted.
- `displayGuid` (string)
- `fraudScreenResult` (object): Deprecated. This object is never populated: no screening provider writes it, and it is always null  on the wire. It is retained for schema compatibility only. External screening outcomes are not  exposed through this property.
- `merchantName` (string)
- `resultCode` (object)
- `cardBrand` (string): The card brand (e.g., "VISA", "MASTERCARD") resolved from BIN data.
- `extraProperties` (object)
- `currentStage` (TransactionStage): Represents the stage of a transaction within the transaction management workflow.
- `history` (array<TransactionHistoryItem>)
- `appliedPatches` (array<TransactionPatchSnapshot>)
- `allowedActions` (array<TransactionOperationType>)
- `concurrencyStamp` (string)
- `entityVersion` (integer(int32))
- `tenantId` (string(uuid))
- `transactionType` (TransactionType): Represents the various types of transactions that can be performed in the system.
- `cardData` (CardData): Represents the data associated with a payment card.
- `checkData` (CheckData): Represents the data associated with a check transaction.
- `cashData` (object): The cash sale details: the cash handed over, the change returned, and when the cash was  taken. Null when the transaction's request carried none.
- `apmData` (object): The alternative-payment instrument block for a payment the payer approved inside a provider.  Null on every other tender.
- `tokenData` (TokenData): Represents tokenized payment information used to process a transaction.  This model supports internal stored tokens as well as digital wallet tokens  such as Internal, Apple Pay, Google Pay, and network tokens.
- `deviceData` (DeviceData): Represents data related to a device in a transaction.
- `fsa` (Fsa): Represents a Flexible Spending Account (FSA) with various amount categories and partial authorization support.
- `lodging` (object): Lodging detail for a stay-related transaction, echoed back as it was submitted. Null on every  transaction outside a lodging industry.
- `softDescriptor` (SoftDescriptor): Represents a soft descriptor for a transaction, containing alternative merchant information.
- `duplicateCheck` (boolean): The duplicate-check intent the submitting request carried, echoed back as it was  submitted. Null means the request expressed no opinion and the merchant's screening  configuration decided, which is the value a request that omitted the field carries.  False means the request asked to waive the check, and it was waived only if the merchant  permits per-transaction overrides. Transactions written before this field became nullable  read as false regardless of what the caller intended.
- `register` (TransactionRegister): Represents a transaction register in the system.
- `invoiceData` (Invoice): Represents an invoice in the system.
- `originalTransaction` (OriginalTransaction): Represents an original transaction with its identifying information.
- `customFields` (array<TrxCustomField>)
- `signatureData` (SignatureData): Represents signature data for a transaction.
- `level2Data` (Level2Data): Represents Level 2 data for a transaction, including purchase order information, transaction date, and merchant zip code.
- `level3Data` (Level3Data): Represents Level 3 data for a transaction, including shipping information and line items.
- `orderLines` (array<TransactionOrderLine>): The product lines of the order this transaction paid for, when it paid for one: a hosted page  selling catalog products records each product, quantity, unit price and line total here for  per-SKU reporting. `null` on every other transaction. Read-only: the platform writes it  from the order it priced itself.
- `ebt` (EbtData): Transaction-level EBT (Electronic Benefit Transfer) data for the offline SNAP / Cash  food-stamp voucher-clear flow. This is the first-class home for the voucher fields that  the legacy gateway stuffed into `ExtData`; it carries the scalar voucher identifiers  from the request through to the processor handlers.
- `useInterchangeDefaults` (boolean)
- `captureType` (CaptureTypes): Represents the types of payment capture methods available for transactions.
- `responseData` (TransactionResponseData): Represents the response data for a transaction, containing various details about the transaction outcome.
- `settleData` (TransactionSettleData): Represents settlement data for a transaction.
- `source` (object)
- `sourceData` (TransactionSourceData): Encapsulates the origin of a transaction and any source-specific identifiers.
- `tags` (array<EntityTag>)
- `notes` (array<EntityNote>)
- `merchantId` (string(uuid))
- `merchantTransactionId` (integer(int64))
- `receiptIds` (array<string>): List of receipt IDs generated for this transaction.
- `refundTransactionIds` (array<string>): IDs of the linked-refund child transactions issued against this transaction (as the parent  sale). Drives the detail-page reverse relationship ("Refunded by <guid>" and the  Related Transactions grid). Empty/null when this transaction has no linked refunds.
- `decisionNotes` (array<TransactionDecisionNote>): System-emitted decision explanations recorded against this transaction,  e.g. why the convenience-fee evaluator applied or suppressed a fee. Read-only on the wire:  written only by server-side contributors, never by an update. Rendered on the transaction  detail view via the decision-note copy resolver.
- `linkedFeeChargeTransactionId` (string): On a primary charge: the id of the separate convenience-fee charge linked to it (the  reverse link, primary → fee), when a card-brand program required the fee to settle as its own  authorization. Null when there is no linked fee charge. Server-state; read-only on the wire.  See `Transaction.LinkedFeeChargeTransactionId`.
- `primaryChargeTransactionId` (string): On a convenience-fee charge: the id of the primary charge this fee is linked to (the forward  link, fee → primary). Null for an ordinary transaction. Server-state; read-only on the wire.  See `Transaction.PrimaryChargeTransactionId`.
- `linkedChargeKind` (object): Why this transaction exists as a separate linked charge (currently only  `ConvenienceFee`), or null when  it is not a linked charge. Server-state; read-only on the wire.
- `processorProfileId` (string(uuid)): The unique identifier of the merchant processor profile that processed this transaction.
- `processorKey` (string): The processor type key (e.g., "tsys", "fiserv") used for this transaction.
- `routingResult` (object): The recorded processor routing decision: the selected processor and profile, the ordered  audit trail, and every evaluated candidate with its score and eliminated flag. Server-owned;  never accepted on a create or update. Back-office only: always null in responses to API-key  callers, and never included in outbound webhook payloads. `null` for  transactions that were not routed.
- `loopbackSimulation` (object): What the sandbox simulator did on this transaction: the published triggers your request fired,  and the response values it filled in from a default because nothing matched. Read it when a  sandbox answer is not the one you expected and you want to know which trigger the sandbox saw.  Each entry carries `isDefault`, which separates a trigger you sent from a value the  sandbox supplied. A card-verification entry reports the response code the sandbox returned and  never the security code you submitted.     Server-owned: it is never accepted on a create or update, and nothing in it changes what the  transaction did. `null` on every transaction the sandbox simulator did not  answer, which includes every transaction a live processor handled, and on every row written  before the trace existed.
- `surchargeResult` (object): The surcharge evaluation decision produced by the surcharge eligibility pipeline: the verdict,  applied rate, cap provenance, and the per-stage audit trail. Server-owned (mapped entity -> DTO  by convention; never accepted on a create/update). Back-office only: stripped for public  API-key callers and anonymous callers, mirroring `routingResult`.  `null` when the surcharge decision was never evaluated (no active surcharge  configuration, non-card tender, or a legacy row).
- `correlationId` (string): The correlation ID linking this transaction to its orchestration audit trail.
- `cumulativeRefundedAmount` (number(double)): Running total of refund amounts applied to this transaction.
- `cumulativeReversedAmount` (number(double)): Running total of reversal amounts applied to this transaction.
- `authorizedAmount` (number(double)): The immutable amount the issuer authorised at the close of the Authorization stage.  UI should read this (not `responseData`.`Amounts.Approved`) when  computing remaining-reversible / remaining-refundable balances, because the  processor's reversal-response payload overwrites `/ResponseData` in place.  Null on legacy rows that pre-date.
- `policyRejection` (object): Audit record of the post-authorization denylist match that policy-rejected this  transaction. Top-level (not nested under `responseData`) because the  auto-reversal flow Sets `/ResponseData` wholesale, so anything stored there  is clobbered. Null for any transaction that was not policy-rejected.
- `partialApprovalData` (object): Durable record of a partial approval (the issuer authorized less than was requested) and  the disposition decided for it. Its presence means the transaction was partially approved;  null when the issuer approved in full.
- `fraudReviewData` (object): Durable hold state when this transaction was parked for manual fraud review: when the hold  started, when it expires, what triggered it, and the disposition that was reached. Top-level  rather than nested under the screening results, which are rewritten wholesale on every  screening retry. Server-owned and read-only on the API surface. Null when the transaction was  never held for review.
- `threeDSAuthentication` (object): The 3-D Secure authentication record when this transaction was authenticated: the status the  issuer reported, the ECI, whether liability shifted, the directory-server and ACS transaction  identifiers, the message version, and the CAVV result code. Top-level rather than on  `cardData`, whose cryptogram and ECI describe a wallet authentication instead.  Server-owned and read-only on the API surface. The credential itself (CAVV / AAV) is never  returned: those members are always null here. Null when no 3-D Secure authentication ran.
- `payloadDecryption` (object): The provenance of the payload decryption the gateway performed through the merchant's  payment encryption provider before authorization: the provider, the scheme (`DUKPT` or  `ONGUARD`), the key serial identifier the request matched, the operator's key label,  the outcome, the provider's region and result code, the retry count and the latency.  Server-owned and read-only on the API surface. Carries no cardholder data and no key  material. Null when the gateway did not decrypt the payload through a provider.
- `enhancedDataQualification` (object): The gateway's own assessment of how well this transaction's enhanced data met the  commercial-card requirements, recorded when it settled. Server-owned and read-only on the API  surface. Null for a transaction that has not settled, that built no enhanced-data addendum, or  that settled before the gateway began recording this. Null is not the same as a clean result:  a present node with a finding count of zero is the clean one.
- `splitTenderGroupId` (string(uuid)): Groups this transaction with the other tenders that together collect one order total after  a partial approval left a shortfall. Server-owned; read-only on the API surface. Null when  the transaction is not part of a split tender.
- `splitTenderSequence` (integer(int32)): 1-based position within the `splitTenderGroupId` group, so the tenders can be  presented in the order they were taken. Null when the transaction is not part of a split  tender.
- `splitTenderRole` (object): Whether this transaction is the primary tender of its split-tender group or a continuation  collecting part of the remaining balance. Null when the transaction is not part of a split  tender.
- `splitTenderDeclaredTotal` (number(double)): The order total a planned split tender collects toward, as declared by  `requestedSplitTenderTotal` on this transaction's create request. Set on the first tender  of a planned split tender only; null on every other transaction, including the first tender of  a split tender started after a partial approval.
- `splitTenderDeadlineUtc` (string(date-time)): When an open planned split tender closes on its own, keeping what its payments collected, if no  further payment is being authorized. Restarted each time a payment leaves the order short.  Server-owned; read-only on the API surface. Null on every transaction that is not the first  tender of an open planned split tender; a split tender started after a partial approval reports  its deadline on `partialApprovalData` instead.
- `deferPartialApprovalAcknowledgment` (boolean): Whether this transaction's create request asked to decide a partial approval itself, as sent in  `deferPartialApprovalAcknowledgment`. Null when the request did not set it.
- `initiationType` (object): Identifies whether this transaction was initiated by the cardholder (CIT) or the merchant (MIT).  Null on legacy transactions.
- `mitReason` (object): For MIT transactions, the reason code justifying the merchant-initiated charge.
- `storedCredentialConsentId` (string(uuid)): Reference to the stored credential consent authorizing this MIT.
- `schemeTransactionId` (string): The card network's trace ID linking this transaction to its original CIT.
- `description` (string): The merchant-supplied free-text payment description recorded on this transaction, echoed  back exactly as it was submitted. `null` when the create request carried  none, in which case the processor received the gateway's own reference instead.
- `merchantReference` (string): The merchant-supplied reconciliation reference recorded on this transaction, echoed back  exactly as it was submitted. `null` when the create request carried none, in  which case the clearing record carried the gateway's fallback instead.
- `tender` (object): The tender the create request explicitly declared, echoed back as it was submitted.  `null` when the request declared nothing, which includes every card, check,  and token transaction and any cash transaction submitted without the declaration.
- `cardholderPresence` (object): How present the cardholder is at the point of sale, separate from the physical entry mode.  Drives network-level presence indicators at auth time.
- `specialCondition` (object): Visa/MC special-condition tag (quasi-cash, quasi-MOTO).
- `processorCertificationOverrides` (object): Per-processor certification override knobs. Non-null only for cert-tooling traffic.  Production traffic always sees this as `null`.
- `refundKind` (object): Classifies a refund transaction as linked (follow-up against a previously approved  original transaction) or unlinked (standalone). `null` for  non-refund transactions.
- `pendingRefundAmount` (number(double)): Reserved-but-not-yet-completed refund amount for this transaction (as a parent),  tracked separately from `cumulativeRefundedAmount` so UI can show  "refund pending settlement" vs "refund completed". `null` means zero.
- `saveCardRequested` (boolean): Operator (VT) or cardholder (HPP) opt-in to save the card for future merchant-initiated  use, captured at create time. Read-only on the API surface: the consumer cannot mutate  it through Update calls (server-side AutoMapper ignores the field on the Update map).
- `tokenizedPaymentMethodId` (string(uuid)): The id of the customer's stored payment method created when a customer-initiated  transaction was approved with `saveCardRequested` = `true`.  `null` on transactions that did not request save-card, were declined, or  where saving the card failed.
- `isAccountVerification` (boolean): When `true`, this transaction is a zero-dollar account verification (the HPP  "save card only" flow) rather than a charge: the card was authorized for $0 to confirm it,  vaulted with consent, and not charged. Read-only on the API surface; create-time-only (the  Update map ignores it). `null` on ordinary chargeable transactions.
- `convenienceFeeDisclosureAcknowledgedAt` (string(date-time)): UTC timestamp when the convenience-fee disclosure was accepted (CSR-as-proxy in the Virtual  Terminal, cardholder on the Hosted Payment Page, or the integrator's own checkout on a direct  API create), captured at confirm-click time. Echoed back as submitted: this is the caller's  attestation, set on create and never editable afterwards (the Update map ignores it).  `null` when no non-zero convenience fee was charged. See  `TransactionCreateOrUpdateDtoBase.ConvenienceFeeDisclosureAcknowledgedAt` for when it is  required.
- `convenienceFeeDisclosureChannel` (string): The surface on which the convenience-fee disclosure was shown and accepted:  `"VirtualTerminal"`, `"HostedPaymentPage"`, or `"Api"`. Set on create and never  editable afterwards.
- `convenienceFeeEligibilitySnapshot` (string): Serialized convenience-fee eligibility decision (reason code + assessed amount) captured  at disclosure-acknowledgment time. Codes / amounts only. Produced by the Virtual Terminal and  Hosted Payment Page; optional on a direct API create. Set on create and never editable  afterwards.
- `convenienceFeeCancelledAmount` (number(double)): The convenience-fee amount, in the transaction currency, the Virtual Terminal operator declined on  the disclosure-confirm modal, removing it from the submission. Audit-only: it was never charged, and the matching  `CsrCancelledVtModal` convenience-fee decision note carries the same amount. Read-only on  the API surface. `null` when no disclosed fee was cancelled.
- `surchargeRate` (number(double)): The surcharge rate actually applied to this transaction, as a decimal fraction (0.03 = 3%).  The same value as `surchargeResult`.AppliedRate, carried at the top level so it  can be filtered on. `null` when no surcharge was assessed.
- `surchargeDisclosureAcknowledgedAt` (string(date-time)): UTC timestamp when the surcharge disclosure was acknowledged, captured at confirm-click time.  Read-only on the API surface. `null` when no surcharge was disclosed.
- `surchargeDisclosureChannel` (string): Channel on which the surcharge disclosure was acknowledged  (`"VirtualTerminal"` / `"HostedPaymentPage"` / `"Api"`). Read-only on the API surface.
- `surchargeReversedAmount` (number(double)): The portion of the assessed surcharge amount reversed by a subsequent void or refund, in the  transaction currency.  Read-only on the API surface. `null` when nothing has been reversed.
- `achWebAuthorizationText` (string): NACHA WEB single-debit authorization language shown to the payer, captured verbatim at ACH  submit. Read-only on the API surface; delivered on the ACH completion webhook. PCI-safe.  `null` for non-ACH tenders.
- `achWebAuthorizationTextVersion` (string): Version hash (`sha256:{hex}`) of `achWebAuthorizationText`. Read-only.
- `achWebAuthorizationConsumerIp` (string): Consumer IP recorded at ACH WEB authorization time (required NACHA evidence). Read-only.  `null` for non-ACH tenders.
- `achWebAuthorizationAt` (string(date-time)): UTC timestamp of the ACH WEB authorization (server-stamped). Read-only.  `null` for non-ACH tenders.
- `achWebAuthorizationSecCode` (string): SEC code the ACH WEB authorization was captured under (always `"WEB"`). Read-only.  `null` for non-ACH tenders.
- `achAuthorizationStatementText` (string): CSR attestation statement captured for a Virtual Terminal CSR-keyed ACH debit (NACHA TEL / PPD).  Read-only on the API surface; delivered on the ACH completion webhook. PCI-safe.  `null` for non-VT-ACH tenders.
- `achAuthorizationStatementVersion` (string): Version hash (`sha256:{hex}`) of `achAuthorizationStatementText`. Read-only.
- `achAuthorizationSecCode` (string): SEC code the VT ACH authorization was captured under (`"TEL"` or `"PPD"`). Read-only.  `null` for non-VT-ACH tenders.
- `achAuthorizationChannel` (string): Channel on which the VT ACH authorization was attested (`"VirtualTerminal"`). Read-only.  `null` for non-VT-ACH tenders.
- `achAuthorizationAt` (string(date-time)): UTC timestamp of the VT ACH authorization (server-stamped). Read-only.  `null` for non-VT-ACH tenders.
- `idempotencyStatus` (object): What create idempotency did to the request that produced this response: whether a  `idempotencyKey` was sent, whether deduplication was in effect for the merchant, and  whether this response replays an earlier create.
- `idempotencyKey` (string): The idempotency key this transaction was created with, exactly as stored.  `null` when the create request carried none. Read-only: the key is fixed at  create time and an update never changes it.

### 403

Forbidden

**Content type:** `application/json`

Schema: `RemoteServiceErrorResponse`

Properties:
- `error` (RemoteServiceErrorInfo)

### 401

Unauthorized

**Content type:** `application/json`

Schema: `RemoteServiceErrorResponse`

Properties:
- `error` (RemoteServiceErrorInfo)

### 400

Bad Request

**Content type:** `application/json`

Schema: `RemoteServiceErrorResponse`

Properties:
- `error` (RemoteServiceErrorInfo)

### 404

Not Found

**Content type:** `application/json`

Schema: `RemoteServiceErrorResponse`

Properties:
- `error` (RemoteServiceErrorInfo)

### 501

Not Implemented

**Content type:** `application/json`

Schema: `RemoteServiceErrorResponse`

Properties:
- `error` (RemoteServiceErrorInfo)

### 500

Internal Server Error

**Content type:** `application/json`

Schema: `RemoteServiceErrorResponse`

Properties:
- `error` (RemoteServiceErrorInfo)

### default

The request failed. The body carries the standard error envelope: a machine-readable `error.code`, a human-readable `error.message`, and `error.validationErrors` when the failure was a validation rejection. See the error-code reference in this document's description for the values `error.code` can take.

**Content type:** `application/json`

Schema: `RemoteServiceErrorResponse`

Properties:
- `error` (RemoteServiceErrorInfo)

### 429

The request was refused because a rate limit was exceeded, or because something a later retry can clear stopped it. A rate limit refusal carries an `application/problem+json` body: wait at least the interval `Retry-After` names before retrying, then back off. Limits are tuned per deployment, so read the allowance from the response headers rather than assuming a fixed ceiling. Any other refusal carries the standard error envelope as `application/json`, and its `error.code` names the cause. A sandbox request whose merchant has spent the plan's transaction allowance is refused with a different `application/json` body: `code` is `USAGE_BUDGET_EXCEEDED`, and `limit` and `used` report the allowance. `Retry-After` is sent only when the allowance resets. An allowance that never resets sends none, and retrying won't help.

**Content type:** `application/problem+json`

Schema: `RateLimitProblemDetails`

Properties:
- `type` (string) required: The problem type identifier. Always the same value: the failure is the status code itself,  so there is no sub-type for a caller to branch on.
- `title` (string) required: A short, human-readable summary of the problem type.
- `status` (integer(int32)) required: The HTTP status code, repeated in the body as the problem-details format defines.
- `detail` (string) required: A human-readable explanation of this occurrence of the problem.
- `retryAfterSeconds` (integer(int32)) required: How long to wait before retrying, in whole seconds, carrying the same figure as the  `Retry-After` header. Always at least one: a value of zero would invite an immediate  retry that is certain to be rejected again.

**Content type:** `application/json`

Schema type: `object`

## Example request

Every block below sends the same request. Replace {{BASE_URL}} with the address of the API you are calling and {{API_KEY}} with your own key.

The request body is a TransactionCreateDto. See the Request body section below for its fields.

### cURL

```bash
curl -X POST "{{BASE_URL}}/api/transactions" \
  -H "api-key: {{API_KEY}}" \
  -H "Content-Type: application/json" \
  -d '{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Authorization",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "duplicateCheck": true,
  "invoiceData": {
    "amounts": {
      "base": 1,
      "total": 1
    }
  }
}'
```

### PowerShell

```powershell
$headers = @{
    'api-key' = '{{API_KEY}}'
}

$body = @'
{
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Authorization",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "duplicateCheck": true,
  "invoiceData": {
    "amounts": {
      "base": 1,
      "total": 1
    }
  }
}
'@

$response = Invoke-RestMethod -Method POST -Uri '{{BASE_URL}}/api/transactions' `
    -Headers $headers -ContentType 'application/json' -Body $body
```

### TypeScript (SDK)

```bash
npm install @winkpg/winkpg-api
```

```typescript
import { Configuration, TransactionsApi } from '@winkpg/winkpg-api';

const api = new TransactionsApi(new Configuration({
  basePath: '{{BASE_URL}}',
  apiKey: '{{API_KEY}}',
}));

const { data } = await api.transactionsCreate({
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Authorization",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "duplicateCheck": true,
  "invoiceData": {
    "amounts": {
      "base": 1,
      "total": 1
    }
  }
});
```

### TypeScript (raw HTTP)

```typescript
const response = await fetch('{{BASE_URL}}/api/transactions', {
  method: 'POST',
  headers: {
    "api-key": "{{API_KEY}}",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "merchantId": "00000000-0000-0000-0000-000000000001",
    "transactionType": "Authorization",
    "cardData": {
      "cardNumber": "4111111111111111",
      "expirationMonth": 12,
      "expirationYear": 2030,
      "cardVerificationValue": "123",
      "nameOnCard": "John Doe",
      "entryMode": "Manual",
      "cvPresence": "Submitted"
    },
    "duplicateCheck": true,
    "invoiceData": {
      "amounts": {
        "base": 1,
        "total": 1
      }
    }
  }),
});

const data = await response.json();
```

### C# (SDK)

```bash
dotnet add package WinkPg.Api.Client
```

```csharp
using WinkPg.Api.Client.Api;
using WinkPg.Api.Client.Client;
using System.Text.Json;

var config = new Configuration { BasePath = "{{BASE_URL}}" };
config.AddApiKey("api-key", "{{API_KEY}}");

var api = new TransactionsApi(config);
var body = JsonSerializer.Deserialize<TransactionCreateDto>("""
    {
      "merchantId": "00000000-0000-0000-0000-000000000001",
      "transactionType": "Authorization",
      "cardData": {
        "cardNumber": "4111111111111111",
        "expirationMonth": 12,
        "expirationYear": 2030,
        "cardVerificationValue": "123",
        "nameOnCard": "John Doe",
        "entryMode": "Manual",
        "cvPresence": "Submitted"
      },
      "duplicateCheck": true,
      "invoiceData": {
        "amounts": {
          "base": 1,
          "total": 1
        }
      }
    }
    """);

var result = await api.TransactionsCreateAsync(body);
```

### C# (raw HTTP)

```csharp
using System.Text;

using var http = new HttpClient { BaseAddress = new Uri("{{BASE_URL}}") };

var request = new HttpRequestMessage(new HttpMethod("POST"), "/api/transactions");
request.Headers.Add("api-key", "{{API_KEY}}");

request.Content = new StringContent("""
    {
      "merchantId": "00000000-0000-0000-0000-000000000001",
      "transactionType": "Authorization",
      "cardData": {
        "cardNumber": "4111111111111111",
        "expirationMonth": 12,
        "expirationYear": 2030,
        "cardVerificationValue": "123",
        "nameOnCard": "John Doe",
        "entryMode": "Manual",
        "cvPresence": "Submitted"
      },
      "duplicateCheck": true,
      "invoiceData": {
        "amounts": {
          "base": 1,
          "total": 1
        }
      }
    }
    """, Encoding.UTF8, "application/json");

var response = await http.SendAsync(request);
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync();
```

### Python (SDK)

```bash
pip install winkpg-api
```

```python
import winkpg_api

configuration = winkpg_api.Configuration(host="{{BASE_URL}}")
configuration.api_key["ApiKey"] = "{{API_KEY}}"

with winkpg_api.ApiClient(configuration) as client:
    api = winkpg_api.TransactionsApi(client)
    body = winkpg_api.TransactionCreateDto.from_dict({
      "merchantId": "00000000-0000-0000-0000-000000000001",
      "transactionType": "Authorization",
      "cardData": {
        "cardNumber": "4111111111111111",
        "expirationMonth": 12,
        "expirationYear": 2030,
        "cardVerificationValue": "123",
        "nameOnCard": "John Doe",
        "entryMode": "Manual",
        "cvPresence": "Submitted"
      },
      "duplicateCheck": True,
      "invoiceData": {
        "amounts": {
          "base": 1,
          "total": 1
        }
      }
    })
    result = api.transactions_create(body)
```

### Python (raw HTTP)

```bash
pip install requests
```

```python
import requests

headers = {
    "api-key": "{{API_KEY}}",
    "Content-Type": "application/json",
}

body = {
  "merchantId": "00000000-0000-0000-0000-000000000001",
  "transactionType": "Authorization",
  "cardData": {
    "cardNumber": "4111111111111111",
    "expirationMonth": 12,
    "expirationYear": 2030,
    "cardVerificationValue": "123",
    "nameOnCard": "John Doe",
    "entryMode": "Manual",
    "cvPresence": "Submitted"
  },
  "duplicateCheck": True,
  "invoiceData": {
    "amounts": {
      "base": 1,
      "total": 1
    }
  }
}

response = requests.request(
    "POST",
    "{{BASE_URL}}/api/transactions",
    headers=headers,
    json=body,
)
response.raise_for_status()
data = response.json()
```

## See also

- [All documentation](https://devportal-simpay-sbx.winkpg.io/llms.txt): the machine-readable index of every public page on this site.
