Developer dashboard

Transactions API#

Process credit card, ACH, cash, and tokenized payments with the AuxCORE Transactions API.


Overview#

The Transactions API allows you to:

  • Process sales — One-step payment authorization and capture
  • Authorize payments — Reserve funds for later capture
  • Capture authorized payments — Complete a previously authorized transaction
  • Void transactions — Cancel a transaction before settlement
  • Refund payments — Return funds to customers (full or partial)
  • Issue credits — Record a credit against a sale, or push an unlinked credit to a card
  • Record cash payments — Log cash transactions with immediate settled status
  • Record external SDK payments — Log IPOS/NearPay device payments with the full platform fee breakdown

API Surfaces#

AuxCORE has three paths for processing transactions. Choose based on your integration type:

Surface Base Path Auth Use Case
Public API /api/v1/public/ x-api-key (tenant + merchant come from the key; tenant/ERP keys also send X-Merchant-ID) ERP, server-to-server, plugins
Admin API /api/v1/transactions/ Authorization: Bearer JWT + X-Tenant-ID Dashboard integrations
AuxCORE SDK API (v2.0) /api/v1/auxvault/ Server-side x-api-key; tenant/ERP keys also need X-Merchant-ID; SDK public keys get 403 Official AuxCORE SDK namespace

For ERP and server integrations, use the Public API. The current auxVault.js also uses /api/v1/public/transaction with pciToken. The current /auxvault/transaction adapter drops PCI tokens and always calls sale, even with TransactionType: "0"; use Public API for auth-only. /api/v1/auxvault itself has no root handler. See AuxCORE SDK contracts.


Transaction Types#

Type Description Use Case
sale Auth + Capture in one step Immediate payment
auth Reserve funds only Hotels, rentals, pre-orders
capture Capture a previously authorized transaction After service delivered
void Cancel before settlement (the transaction's status becomes voided) Order cancelled
refund Return funds (full or partial) — recorded as a new refund row Returns, disputes
credit Credit not tied to a captured sale Store credit, compensation

Transaction Statuses#

The status field on a transaction record is one of: pending, approved, declined, settled, voided, refunded, error, reversed (ACH return), processing (ACH debit sent to the bank).

Payment Methods#

Method Description Transaction ID Prefix
Card (default) Credit/debit card via gateway TXN-
ACH Bank account transfer ACH-
Cash Physical cash — no gateway, settled immediately CASH-

Refund rows use the prefix REF- and credit rows CREDIT-. Every transaction also has a UUID id; endpoints that take a transaction ID accept either the UUID or the prefixed transactionId.


Process a Sale — Public API#

Endpoint#

POST/api/v1/public/transaction

Required Headers#

Required Headershttp
x-api-key: YOUR_API_KEY
Content-Type: application/json

Tenant and merchant are resolved from a merchant-scoped API key. With a tenant-scoped / ERP key (lv_erp_…), also send X-Merchant-ID: <merchantId> (or merchantId in the body).

PCI: On Sandbox and Production, raw card data (CardNumber / CVV) is rejected with 400 PCI_SCOPE_VIOLATION. Collect the card with the PCI SDK (https://vault.auxcore.net/sdk/) and send the returned pciToken instead. Every card example on this page uses a pciToken.

Card Payment (PCI token)#

Card Payment (PCI token)bash
curl -X POST https://uat.auxcore.net/api/v1/public/transaction \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "Amount": 150.75,
    "SuggestedMode": "Card",
    "pciToken": "pci_tok_8f2c1a9b7e4d",
    "BillingCustomerName": "John Doe",
    "BillingEmail": "john.doe@example.com",
    "BillingAddress": "123 Main Street",
    "BillingCity": "New York",
    "BillingState": "NY",
    "BillingPostalCode": "10001",
    "OrderId": "ORDER-2026-001",
    "Description": "Widget purchase"
  }'

Auth-Only Payment (Reserve Funds)#

Use transactionType: "auth" (legacy numeric value "2" is also accepted) to reserve funds without capturing. Follow up with a capture (Admin API or AuxCORE SDK capture route — see Captures) once the service or goods are delivered.

Auth-Only Payment (Reserve Funds)bash
curl -X POST https://uat.auxcore.net/api/v1/public/transaction \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "Amount": 150.75,
    "transactionType": "auth",
    "SuggestedMode": "Card",
    "pciToken": "pci_tok_8f2c1a9b7e4d",
    "BillingCustomerName": "John Doe",
    "BillingEmail": "john.doe@example.com",
    "BillingPostalCode": "10001",
    "OrderId": "ORDER-2026-001"
  }'

A successful authorization is stored with type: "auth" and status: "approved", so the Public API response carries Status: "1" — the same as an approved sale.

ACH Payment#

ACH Paymentbash
curl -X POST https://uat.auxcore.net/api/v1/public/transaction \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "Amount": 500.00,
    "SuggestedMode": "ACH",
    "account_number": "1234567890",
    "routing_number": "021000021",
    "account_type": "checking",
    "account_holder_name": "John Doe",
    "BillingCustomerName": "John Doe",
    "BillingEmail": "john.doe@example.com"
  }'

ACH is asynchronous: an accepted debit comes back with HTTP 200, status: "pending", Status: "2" and Settled: false. Watch the transaction.approved / transaction.declined webhooks (or poll the transaction) for the outcome; a later bank return arrives as transaction.returned.

Cash Payment#

Send "SuggestedMode": "Cash" with an Amount to record a cash sale. No gateway is called; the transaction is stored as settled with no convenience fee (see Cash Payment below for the rules).

Request Fields#

Core Fields#

Field Type Required Description
Amount number Yes Transaction amount in USD (e.g., 125.00). Must be > 0
transactionType string No "sale" (default) or "auth" (TransactionType and the numeric "2" for auth are also accepted)
SuggestedMode string No "Card" (default), "ACH" or "Cash"
BaseAmount number No Amount before tip, tax and fee
TipAmount number No Tip amount. Default 0
TaxAmount number No Tax amount. Default 0
ConvenienceFeeActive boolean No Who pays the technology fee. Omit for the merchant's default payer; true — the customer pays it; false — the merchant absorbs it. Honoured when the merchant's account allows changing who pays; otherwise it is ignored, the merchant's pricing decides, and the response carries the warning payer_change_not_allowed
Currency string No ISO 4217 code. Default "USD"
OrderId string No Your order reference number
InvoiceNumber string No Invoice reference
Description string No Transaction description
BranchId string (uuid) No Location (branch) the sale belongs to
saveCard boolean No With a pciToken, save the card to the customer vault after approval (needs BillingEmail or BillingPhoneNumber)
ReturnUrl / DeclineUrl / CancelUrl string No Where to send the payer after a redirect (3DS / hosted page). When supplied, the response includes ReturnLandingUrl
metadata object No Free-form key/value data

Default behavior: If transactionType is omitted, the transaction runs as a sale (authorize + capture in one step).

Card Fields (when SuggestedMode = "Card")#

Field Type Required Description
pciToken string Yes* PCI vault token (pci_tok_…) from the PCI SDK or a saved card
CardNumber string No Not accepted: raw card numbers are rejected on Sandbox and Production with 400 PCI_SCOPE_VIOLATION. Send pciToken
ExpiryMonth string Dev only 2-digit month ("01"–"12")
ExpiryYear string Dev only 4-digit year (e.g., "2027")
CVV string Dev only 3-4 digit security code
cardLast4 / cardBrand string No Display metadata returned by the PCI iframe

*token, paymentToken or cardToken holding a pci_tok_… value are accepted as aliases.

ACH Fields (when SuggestedMode = "ACH")#

Field Type Required Description
account_number string Yes Bank account number (AccountNumber also accepted)
routing_number string Yes Bank routing number (RoutingNumber also accepted)
account_type string No "checking" (default) or "savings"
account_holder_name string No Name on the account. Falls back to BillingCustomerName
SecCode string No ACH SEC code. Inferred (WEB) when absent
CustomerType string No Account holder type (e.g. business)
BusinessName string No Company name for a business bank account

Billing Fields#

Field Type Required Description
BillingCustomerName string Recommended Cardholder name (or FirstName + LastName)
BillingEmail string Recommended Customer email (for receipts)
BillingPhoneNumber string No Customer phone
BillingAddress string Conditional* Street address
BillingCity string Conditional* City
BillingState string Conditional* 2-letter state code
BillingPostalCode string Conditional* ZIP/postal code
BillingCountry string No Country

*Required if AVS filtering is enabled for this merchant

Response#

HTTP 200 for an approved or accepted (pending ACH) transaction, 402 for a decline.

Responsejson
{
  "success": true,
  "status": "success",
  "status_code": 200,
  "message": "Approved",
  "data": {
    "TransactionId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "Status": "1",
    "Amount": 155.27,
    "BaseAmount": 150.75,
    "ConvenienceFee": 4.52,
    "TipAmount": 0,
    "TaxAmount": 0,
    "ConvenienceFeeActive": true,
    "CardNumber": "****1111",
    "BillingEmail": "john.doe@example.com",
    "BillingCustomerName": "John Doe",
    "ResponseCode": "100",
    "ResponseMessage": "Approved",
    "AuthCode": "123456",
    "AvsResult": "Y",
    "CvvResult": "M",
    "GatewayTransactionId": "3456789012",
    "ProcessedAt": "2026-02-23T14:00:00.000Z",
    "otpSent": false,
    "watchdog": {}
  }
}
  • TransactionId is the transaction's UUID id.
  • status is "success", "pending" (accepted, not settled — ACH) or "declined". Read status, not just success.
  • Amount is the fee-inclusive total; ConvenienceFee, TipAmount and TaxAmount are always present (0 when not applied).
  • warnings (top level) appears only when the fee was not applied as requested: a convenience fee was requested but none was applied, or ConvenienceFeeActive was ignored because the merchant's account does not allow changing who pays (payer_change_not_allowed).
  • customerId / paymentMethodId are added when saveCard saved the card.
  • VelocityReviewStatus: "in_review" is added when one of the merchant's Transaction Rules held an approved payment for review. Status stays "1", but the payment is not complete: do not fulfil until transaction.approved arrives. transaction.voided means the merchant denied it (see Webhook Events).

Status Codes#

Status Meaning
"1" Approved (sale or auth)
"2" Pending (accepted ACH, or awaiting a customer redirect)
"3" Processing
"9" Declined / error

Redirect Required (3DS / hosted payment page)#

Some gateways need the payer to complete an action first. The response is HTTP 200 with success: false, status: "pending" and requires_action: true:

Redirect Required (3DS / hosted payment page)json
{
  "success": false,
  "status": "pending",
  "status_code": 200,
  "requires_action": true,
  "message": "Cardholder authentication required (3DS)",
  "data": {
    "TransactionId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "Status": "2",
    "RequiresAction": true,
    "RedirectUrl": "https://acs.example-bank.com/challenge/abc123",
    "RedirectType": "three_ds",
    "PaymentMode": "card",
    "Url3Ds": "https://acs.example-bank.com/challenge/abc123",
    "Amount": 150.75
  }
}

Send the payer to RedirectUrl. RedirectType is three_ds, hosted_checkout or hosted_payment_page. Url3Ds is deprecated (same value). ReturnLandingUrl is included when you sent ReturnUrl / DeclineUrl / CancelUrl.


Void a Transaction — Public API#

Cancel an approved transaction before it settles.

Endpoint#

POST/api/v1/public/void
Void a Transactionbash
curl -X POST https://uat.auxcore.net/api/v1/public/void \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "transactionId": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
  }'
Field Required Description
transactionId Yes Transaction UUID or TXN-… ID (TransactionId / transaction_id also accepted)

The response is the voided transaction: { "success": true, "data": { ...transaction, "status": "voided" }, "gatewayVoided": true }. A failed void returns 400 with error.code: "VALIDATION_ERROR" and the reason in error.message.

Note: Only approved transactions (and pending ACH debits) can be voided. Once a transaction is settled, use /refund instead. Cash transactions cannot be voided.


Refund a Transaction — Public API#

Issue a full or partial refund for an approved or settled transaction.

Endpoint#

POST/api/v1/public/refund
Refund a Transactionbash
# Full refund
curl -X POST https://uat.auxcore.net/api/v1/public/refund \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "transactionId": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
  }'

# Partial refund
curl -X POST https://uat.auxcore.net/api/v1/public/refund \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "transactionId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "amount": 50.00
  }'
Field Required Description
transactionId Yes Transaction UUID or TXN-… ID
amount No Partial refund amount (> 0). Omit for full refund.

Returns HTTP 201 with the new refund transaction (REF-…) in data. Check data.status: refunded means the gateway accepted it, declined means it was refused (a gateway decline is added to the Refund Decline Queue) — success is true in both cases. Only a lowercase amount makes it partial; a PascalCase Amount is ignored and the full amount is refunded.


Get Transaction — Public API#

Retrieve the full details of a specific transaction.

Endpoint#

GET/api/v1/public/transaction/:id
Get Transactionbash
curl https://uat.auxcore.net/api/v1/public/transaction/7c9e6679-7425-40de-944b-e07fc1f90ae7 \
  -H "x-api-key: YOUR_API_KEY"

:id is the UUID or the TXN-… / ACH-… / CASH-… ID. The response is { "success": true, "data": { ...transaction } } with the stored transaction fields (camelCase: transactionId, status, type, amount, baseAmount, convenienceFee, cardLast4, …) plus refundedAmount and, when available, merchantName. Returns 404 NOT_FOUND for a transaction outside the key's merchant.


List Transactions — Public API#

Search and filter transactions for the API key's merchant.

Endpoint#

GET/api/v1/public/transaction-list

GET /api/v1/public/merchant-transactions is an alias with identical behaviour.

List Transactionsbash
# All recent transactions
curl "https://uat.auxcore.net/api/v1/public/transaction-list" \
  -H "x-api-key: YOUR_API_KEY"

# Filter by date range
curl "https://uat.auxcore.net/api/v1/public/transaction-list?dateFrom=2026-02-01&dateTo=2026-02-28" \
  -H "x-api-key: YOUR_API_KEY"

# Filter by status
curl "https://uat.auxcore.net/api/v1/public/transaction-list?status=approved" \
  -H "x-api-key: YOUR_API_KEY"

Query Parameters#

Parameter Type Description
page integer Page number (default: 1)
limit integer Items per page (default: 50)
dateFrom date Filter start date (ISO 8601). A plain YYYY-MM-DD dateTo covers the whole day
dateTo date Filter end date (ISO 8601)
dateField string settledAt to filter on settlement date instead of creation date
status string pending, approved, declined, settled, voided, refunded, error, reversed, processing (comma-separated for several)
excludeStatus string Statuses to leave out (comma-separated)
type string sale, auth, capture, refund, credit (void matches voided transactions)
paymentMethod string card, ach, cash, crypto, gift
q string Free-text search across name, transaction ID, order ID, amount, email, card last 4, auth code
transactionId / orderId / email / cardLast4 / name / amount string Field filters (ignored when q is sent)
customerId string (uuid) Transactions for one customer
sort string asc or desc (default)
sortColumn string createdAt (default), amount, status, type, transactionId, orderId

Response#

Responsejson
{
  "success": true,
  "data": [ { "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7", "transactionId": "TXN-1771855200000-A1B2C3D4", "status": "approved", "type": "sale", "amount": "150.75" } ],
  "meta": {
    "page": 1,
    "limit": 50,
    "total": 1,
    "totalPages": 1,
    "summary": { "count": 1, "amountTotal": 150.75, "approvedCount": 1, "refundTotal": 0 },
    "statusCounts": { "approved": 1 }
  }
}

Token-Based Transaction — Public API#

Charge a saved card by its PCI vault token. The body is passed to the transaction service as-is (camelCase fields), and the merchant comes from the API key.

Endpoint#

POST/api/v1/public/token-transaction
Token-Based Transactionbash
curl -X POST https://uat.auxcore.net/api/v1/public/token-transaction \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "pciToken": "pci_tok_8f2c1a9b7e4d",
    "amount": 125.00,
    "description": "Monthly renewal",
    "billingEmail": "john.doe@example.com"
  }'
Field Required Description
pciToken Yes Saved PCI vault token (pci_tok_…); cardToken / paymentToken holding a pci_tok_… value also work
amount Yes Amount (> 0)
transactionType No sale (default)
description, orderId, billingEmail, billingCustomerName No Same meaning as on the Admin API sale

Returns HTTP 201 with { "success": true, "data": { ...transaction } } — the raw transaction record, not the PascalCase shape of /transaction. Check data.status (approved / declined).


Charge a Tokenized Bank Account — Public API#

The ACH counterpart of /token-transaction: charge a pci_ach_… token from /tokenize-ach. Requires a server-side API key — SDK public keys (lpk_live_…) get 403 FORBIDDEN.

Endpoint#

POST/api/v1/public/token-transaction-ach
Charge a Tokenized Bank Accountbash
curl -X POST https://uat.auxcore.net/api/v1/public/token-transaction-ach \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "token": "pci_ach_4b7d2e91c0aa",
    "amount": 250.00,
    "description": "Invoice 1042",
    "billingEmail": "john.doe@example.com"
  }'
Field Required Description
token Yes pci_ach_… token (pciAchToken / tokenId also accepted)
amount Yes Amount (> 0)
accountType, accountHolderName No Override what the vault stored
secCode, customerType, businessName No ACH entry details
customerId, description, orderId, billingEmail, billingPhoneNumber, billingFirstName, billingLastName No Reference and billing data
convenienceFeeActive No Who pays the technology fee. Omit for the merchant's default payer; true — the customer pays it; false — the merchant absorbs it. Honoured when the merchant's account allows changing who pays; otherwise it is ignored, the merchant's pricing decides, and the response carries the warning payer_change_not_allowed

Returns HTTP 201 with the ACH transaction (status: "pending" while the debit settles). A tenant-scoped key without a resolvable merchant gets 400 VALIDATION_ERROR.


Rerun a Declined Transaction — Public API#

Note: POST /api/v1/public/rerun is not available. The route exists in the gateway but the transaction service has no rerun operation, so it returns 404. To retry a declined payment, submit a new POST /api/v1/public/transaction.


Admin API Routes (Dashboard / JWT Auth)#

These routes are used by the AuxCORE dashboard and require a JWT Bearer token. They accept camelCase request bodies and respond with { success, data }, where data is the transaction record.

Process Sale#

POST/api/v1/transactions/sale
Process Salebash
curl -X POST https://uat.auxcore.net/api/v1/transactions/sale \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "X-Tenant-ID: YOUR_TENANT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "merchantId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "amount": 150.75,
    "currency": "USD",
    "paymentMethod": "card",
    "pciToken": "pci_tok_8f2c1a9b7e4d",
    "billingCustomerName": "John Doe",
    "billingEmail": "john@example.com"
  }'

Returns HTTP 201. merchantId and amount (> 0) are required. Use POST /api/v1/transactions/auth with the same body for an authorization only. An optional Idempotency-Key header de-duplicates retries for 24 hours.

Itemised sale (lineItems)#

sale, auth, token-sale, ach-sale and external-payment accept an optional lineItems
array — the cart sold with the payment (catalog products and free-text misc lines):

Itemised sale (lineItems)json
"lineItems": [
  { "productId": "3f2b8c1e-4d5a-4e6f-8a7b-9c0d1e2f3a4b", "name": "Diesel", "quantity": 2.5, "unit": "gallon", "unitPrice": 4.19 },
  { "type": "misc", "name": "Car wash", "quantity": 1, "unitPrice": 8.00 }
]

Each line: type (product | misc), productId (required for product, forbidden for misc),
name, quantity (> 0, up to 3 decimals), optional unit, unitPrice (2 decimals), optional
lineTotal (= quantity × unitPrice). The lines must add up to baseAmount (amount before tip, tax
and convenience fee) within $0.01, otherwise 400 INVALID_LINE_ITEMS before anything is charged.
A cart holding more of a product than its maxQuantity (summed across lines) is refused with
400 QUANTITY_LIMIT_EXCEEDED — also before anything is charged, and not on external-payment; see
Products, section "Per-order quantity limit".
The normalised cart is stored on the transaction and returned by GET /transactions/:id (not by the
list). Product lines count toward the product's soldQuantity once the sale is approved, and come
back out on a void, a full refund or an ACH return. Full contract:
Device Integration, section "Itemised sales (POS cart)".

Optional immutable purchase snapshot#

Mobile card sales authenticated with X-Device-Token may include enhancedData without
sending requestOrigin. The server derives ipos or nearpay from the trusted device
context; portal Take Payment calls continue to use their existing take_payment context.
The field is optional and never reaches a processor.

Optional immutable purchase snapshotjson
{
  "enhancedData": {
    "source": "manual",
    "lines": [{
      "stableLineId": "mobile-line-1",
      "description": "Widget",
      "quantity": "1",
      "unitPrice": "100.00",
      "tax": "8.00"
    }]
  }
}

Use { "source": "invoice", "invoiceId": "…" } for an invoice candidate. The invoice
is reloaded under the device's tenant and merchant scope. It is stored only when its full
server-authoritative total equals the charge excluding tip and customer/convenience fees;
otherwise the sale remains a normal Standard payment with no snapshot.

For manual snapshot lines, quantity may have up to three decimal places and unitPrice may
have up to two. The exact quantity × unit-price calculation must resolve to whole currency
minor units; the API rejects a non-representable line total rather than rounding it.

Capture an Authorization#

POST/api/v1/transactions/:transactionId/capture
Capture an Authorizationbash
curl -X POST https://uat.auxcore.net/api/v1/transactions/7c9e6679-7425-40de-944b-e07fc1f90ae7/capture \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "X-Tenant-ID: YOUR_TENANT_ID"

Captures the full authorized amount — the endpoint takes no body (partial capture is not supported). Requires the transactions.capture permission.

Cancel Capture#

POST/api/v1/transactions/:transactionId/cancel-capture
Cancel Capturebash
curl -X POST https://uat.auxcore.net/api/v1/transactions/7c9e6679-7425-40de-944b-e07fc1f90ae7/cancel-capture \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "X-Tenant-ID: YOUR_TENANT_ID"

Cash Payment (Record a Cash Sale)#

Record a cash transaction. No gateway is called — the transaction is immediately created with status: "settled" and convenienceFee: 0.

Note: Cash is not gated by merchant or device configuration — any merchant can record a cash sale.

POST/api/v1/transactions/sale
Cash Payment (Record a Cash Sale)bash
curl -X POST https://uat.auxcore.net/api/v1/transactions/sale \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "X-Tenant-ID: YOUR_TENANT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "merchantId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "amount": 55.00,
    "tipAmount": 5.00,
    "paymentMethod": "Cash",
    "currency": "USD",
    "billingCustomerName": "Jane Smith",
    "billingEmail": "jane.smith@example.com",
    "requestOrigin": "virtual-terminal"
  }'

Request Fields#

Field Type Required Description
merchantId string (uuid) Yes Merchant ID
amount number Yes Total amount including tip and tax. Must be > 0
paymentMethod string Yes "Cash" (case-insensitive; "Check" is treated the same way)
tipAmount number No Tip amount. Default: 0
taxAmount number No Tax amount. Default: 0
baseAmount number No Amount before tip and tax. Default: amount - tipAmount - taxAmount
currency string No ISO 4217 currency code. Default: "USD"
deviceId string (uuid) No Device ID when transaction originates from a device
branchId string (uuid) No Location the sale belongs to
orderId string No Internal order reference
requestOrigin string No Source of the transaction. Default "virtual-terminal"
description string No Transaction description
signature string No Customer signature, printed on the receipt
billingCustomerName string No Customer name (or billingFirstName + billingLastName)
billingEmail string No Customer email — used to send receipt if provided
billingAddress string No Street address
billingCity string No City
billingState string No State
billingPostalCode string No ZIP/postal code
billingCountry string No Country
billingPhoneNumber string No Phone number

Do not send card or ACH fields (cardNumber, cardExpiry, accountNumber, etc.) — they are ignored for Cash payments.

Response — 201 Created#

Response — 201 Createdjson
{
  "success": true,
  "data": {
    "id": "0b6f3c3e-9a51-4d1e-8f43-2f7b1c9d6e10",
    "transactionId": "CASH-1750300000000-A1B2C3D4",
    "merchantId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "amount": "55.00",
    "baseAmount": "50.00",
    "tipAmount": "5.00",
    "taxAmount": "0.00",
    "convenienceFee": "0.00",
    "currency": "USD",
    "type": "sale",
    "status": "settled",
    "paymentMethod": "Cash",
    "provider": "Cash",
    "gatewayName": "Cash",
    "billingCustomerName": "Jane Smith",
    "billingEmail": "jane.smith@example.com",
    "requestOrigin": "virtual-terminal",
    "createdAt": "2026-06-19T10:00:00.000Z",
    "updatedAt": "2026-06-19T10:00:00.000Z"
  }
}

Cash Payment Rules#

Rule Behavior
status Always "settled" — no gateway processing
convenienceFee Always 0 — fees do not apply to cash
type Only sale is supported. A Cash auth (/transactions/auth) returns 400 VALIDATION_ERROR
Void Not supported for Cash (400). Use Refund instead
Refund Full refund only — a partial amount returns 400
Settlement batch Cash transactions are excluded from settlement batches
Ledger Cash transactions are posted to the ledger
Receipt email Sent automatically if billingEmail is provided

Record a Credit Against a Transaction#

POST/api/v1/transactions/:transactionId/credit
Record a Credit Against a Transactionbash
curl -X POST https://uat.auxcore.net/api/v1/transactions/7c9e6679-7425-40de-944b-e07fc1f90ae7/credit \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "X-Tenant-ID: YOUR_TENANT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 50.00
  }'

Creates a credit transaction (CREDIT-…, status: "approved") for the original transaction's merchant, gateway and location. No gateway call is made — this records the credit only. amount must be a positive number. Returns HTTP 201. A reason field is accepted but not stored.

Issue an Unlinked Credit#

POST/api/v1/transactions/credit

Pushes funds to a card through the gateway without referencing a prior sale (the Virtual Terminal "Credit" action). Takes the same body as Process Sale (merchantId, amount, card / pciToken, billing fields) and returns HTTP 201 with the credit transaction.


Record an External SDK Payment (IPOS / NearPay)#

Record a payment the device already completed through an external provider SDK (IPOS or NearPay). The provider SDK only carries total + tip, so the platform-computed fee breakdown (convenienceFee, taxAmount, and the derived baseAmount) never reaches the provider webhook. The device calls this endpoint right after the SDK returns success to push the full breakdown, keyed by the provider's gatewayTransactionId.

The endpoint is idempotent and async-safe with the provider webhook — either side may arrive first, both matched on gatewayTransactionId:

  • Webhook not seen yet → a pending transaction is created; the webhook later finalizes the status (approved / declined).
  • Webhook already created the record → only the platform fee breakdown is filled in; the webhook-owned status, card, and auth data are left untouched. A later webhook re-delivery will not overwrite the device-supplied fees.

enhancedData is optional immutable purchase context (the same manual-lines or invoice-ID
candidate accepted by mobile card sales). It is resolved after the fee components are
normalized and stored with the local transaction only; it is never submitted to IPOS,
NearPay, or another processor. A webhook-first row receives the snapshot only if it has none.
Repeating the same candidate is idempotent; a different valid candidate returns
409 ENHANCED_DATA_SNAPSHOT_CONFLICT and never overwrites the first snapshot.

POST/api/v1/transactions/external-payment

Auth: JWT Bearer plus a device token. This is a device-only endpoint — X-Device-Token is required; tenantId, merchantId, deviceId, and terminalId are resolved from the device context, never from the body.

Record an External SDK Payment (IPOS / NearPay)http
Authorization: Bearer YOUR_JWT_TOKEN
X-Device-Token: DEVICE_TOKEN
X-Tenant-ID: YOUR_TENANT_ID
Content-Type: application/json
Record an External SDK Payment (IPOS / NearPay)bash
curl -X POST https://uat.auxcore.net/api/v1/transactions/external-payment \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "X-Device-Token: DEVICE_TOKEN" \
  -H "X-Tenant-ID: YOUR_TENANT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "gatewayTransactionId": "85635456265410555120260724032413",
    "paymentMode": "IPOS",
    "type": "sale",
    "amount": 108.00,
    "baseAmount": 100.00,
    "tipAmount": 5.00,
    "convenienceFee": 3.00,
    "taxAmount": 0.00,
    "currency": "USD",
    "cardLast4": "4242",
    "cardBrand": "Visa"
  }'

Request Fields#

Field Type Required Description
gatewayTransactionId string Yes Transaction ID returned by the IPOS/NearPay SDK — the key the webhook is matched on
paymentMode string Yes "IPOS" or "NEARPAY"
type string No "sale" (default) or "auth"
amount number Yes Total charged (baseAmount + tipAmount + taxAmount + convenienceFee). Must be > 0
baseAmount number No Amount before tip/tax/fee. Default: amount - tipAmount - taxAmount - convenienceFee
tipAmount number No Tip amount. Default: 0
convenienceFee number No Platform-computed convenience fee. Default: 0
taxAmount number No Platform-computed tax. Default: 0
currency string No ISO 4217 currency code. Default: "USD"
cardLast4 string No Last 4 digits of the card (display only), from the SDK response
cardBrand string No Card brand (e.g. "Visa"), from the SDK response
invoiceNumber string No Linked invoice number
enhancedData object No Immutable purchase candidate: { source: "manual", lines: [...] } or { source: "invoice", invoiceId }
orderId string No Internal order reference
metadata object No Provider-specific extra data

Do not send tenantId, merchantId, deviceId, or status — the server sets them (status is always pending on create). The stored transactionId is IPOS-<gatewayTransactionId> for IPOS and NPAY-<gatewayTransactionId> for NearPay.

Response — 201 Created (no webhook yet)#

Response — 201 Created (no webhook yet)json
{
  "success": true,
  "data": {
    "id": "5d1f0c7a-2b8e-4c3a-9e61-7a4f2d8b9c01",
    "transactionId": "IPOS-85635456265410555120260724032413",
    "status": "pending",
    "amount": "108.00",
    "baseAmount": "100.00",
    "tipAmount": "5.00",
    "convenienceFee": "3.00",
    "taxAmount": "0.00"
  }
}

Response — 200 OK (webhook already created it, fees filled in)#

Response — 200 OK (webhook already created it, fees filled in)json
{
  "success": true,
  "data": {
    "id": "5d1f0c7a-2b8e-4c3a-9e61-7a4f2d8b9c01",
    "transactionId": "IPOS-85635456265410555120260724032413",
    "status": "approved",
    "baseAmount": "100.00",
    "convenienceFee": "3.00",
    "taxAmount": "0.00"
  }
}

Error Responses#

HTTP Code Cause
400 VALIDATION_ERROR Missing gatewayTransactionId; paymentMode not in IPOS/NEARPAY; amount ≤ 0; type not in sale/auth
400 DEVICE_CONTEXT_REQUIRED Called without a valid X-Device-Token
401 / 403 INVALID_DEVICE_TOKEN / DEVICE_SUSPENDED Device token invalid, revoked, or device suspended
409 ENHANCED_DATA_SNAPSHOT_CONFLICT Retry supplied different purchase details after a snapshot was stored
500 INTERNAL_ERROR Unexpected backend error

AVS Response Codes#

Code Meaning
Y Address and 5-digit ZIP match
A Address matches, ZIP does not
Z ZIP matches, address does not
N Neither address nor ZIP match
U Address information unavailable
R Retry — system unavailable
S Service not supported

CVV Response Codes#

Code Meaning
M CVV matches
N CVV does not match
P CVV not processed
S CVV should be on card but not provided
U Issuer unable to process CVV

Error Handling#

Declined Transaction#

Public API returns HTTP 402 for card-level declines. Response codes are normalized to the NMI convention (100 = approved, 2xx = issuer decline, 3xx = gateway reject, 4xx = processor error):

json
{
  "success": false,
  "status": "declined",
  "status_code": 402,
  "message": "Insufficient funds",
  "data": {
    "TransactionId": "9a3e7c21-6f4b-4d8e-a2c5-1b0f9e8d7c6a",
    "Status": "9",
    "ResponseCode": "202",
    "ResponseMessage": "Insufficient funds"
  }
}

PCI Scope Violation#

json
{
  "success": false,
  "error": {
    "code": "PCI_SCOPE_VIOLATION",
    "message": "PublicAPI.transaction: raw card data is not permitted in this environment. Collect card data via the PCI iframe/SDK and submit a pciToken only."
  }
}

Validation Error#

Gateway-level checks on /void and /refund return a string error:

json
{
  "success": false,
  "error": "Transaction ID required",
  "message": "Please provide a transactionId in the request body"
}

Errors raised by the transaction service (amount, status rules, not found) use the structured shape:

json
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Only approved transactions can be voided"
  }
}

Next Steps#


Questions? Contact support@auxcore.net