Skip to main content

TransIT Integration

1. Overview

This document specifies the monorepo's TSYS TransIT integration via the shared Kotlin library libs/transit-client.

  • libs/transit-client is the canonical API wrapper for TransIT request/response models, wrappers, retries, and exception handling.
  • services/processing integrates through TransitPaymentProcessor, which maps service DTOs to transit-client DTOs and delegates to TransitClient.
  • Other services can also use the same library for non-processing workflows (for example merchant activation and provisioning).

2. TransIT API Details

Environments

EnvironmentBase URLPurpose
Sandboxhttps://stagegw.transnox.com/servlets/TransNox_API_ServerDevelopment, staging, and certification testing
Productionhttps://gateway.transit-pass.com/servlets/TransNox_API_ServerLive transactions

Runtime services read the active endpoint from TRANSIT_BASE_URL. Keep environment values aligned with the TransIT Developer Portal and the merchant account profile before changing staging or production routing.

Authentication

Every request to TransIT requires:

Headers:
Content-Type: application/json
Accept: application/json

Body (in every request):
"deviceID": "<assigned by TransIT>",
"transactionKey": "<assigned by TransIT>",
"operatorID": "<our operator identifier>"
  • deviceID: Unique identifier for our integration endpoint (assigned during onboarding)
  • transactionKey: Secret key for authenticating requests (assigned during onboarding)
  • operatorID: Identifies the operator performing the transaction (configurable per-merchant)

Credential profile records and merchant-onboarding activation flows are the source of truth for merchant deviceID and transactionKey values. Do not put raw TransIT credentials in support docs, PR descriptions, or runbook examples.

API Version

  • TransIT publishes versioned API revisions through the Developer Portal.
  • Gateway request/response compatibility lives in libs/transit-client models and certification fixtures.
  • Format: JSON. XML may be supported by TransIT, but Gateway serializes TransIT traffic as JSON.

Integration Architecture (Current Code)

services/* -> libs/transit-client: TransitClient -> TransIT endpoint
  • TransitClient centralizes wrapper selection (Sale, Auth, etc.), request body assembly, credentials injection, retries, and response/decline parsing.
  • Transport concerns stay inside libs/transit-client (OkHttpClient, timeout/backoff, sensitive field redaction).
  • Service modules own business mapping:
    • services/processing: transaction workflows through TransitPaymentProcessor
    • services/management: merchant/activation related integration points
    • services/merchant-onboarding: activation and provisioning retry orchestration
  • Exception boundary is split by layer:
    • TransitClient throws TransitException.*
    • callers map those to service-level outcomes/exceptions

3. TransIT Client API Surface (Current)

The table below reflects the current operations in libs/transit-client/src/main/kotlin/com/myriad/gateway/transit/TransitClient.kt.

3.1 Core Transaction and Utility Operations (Existing)

OperationRequest WrapperKey FieldsKotlin Method
SaleSaletransactionAmount, cardNumber/tokenID, cardDataSource, transactionIndustryType, externalReferenceIDsale(credentials, SaleRequest)
AuthAuthtransactionAmount, cardNumber/tokenID, cardDataSource, transactionIndustryType, externalReferenceIDauthorize(credentials, AuthRequest)
CaptureCapturetransactionID, transactionAmount, externalReferenceIDcapture(credentials, CaptureRequest)
VoidVoidtransactionID, externalReferenceIDvoid(credentials, VoidRequest)
Return / RefundReturntransactionID or card fields, transactionAmount, externalReferenceIDrefund(credentials, ReturnRequest)
TipAdjustTipAdjustmenttip, transactionID, externalReferenceIDtipAdjust(credentials, TipAdjustRequest)
L2L3AdjustTransactionAdjustmenttransactionID, level2Data, level3Data, externalReferenceIDl2l3Adjust(credentials, L2L3AdjustRequest)
CardVerificationCardVerificationcardNumber, expirationDate, CVV2, externalReferenceIDcardVerification(credentials, CardVerificationRequest)
BalanceInquiryBalanceInquirycard/account lookup fields + externalReferenceIDbalanceInquiry(credentials, BalanceInquiryRequest)
BatchCloseBatchCloseoptional batch context + externalReferenceIDbatchClose(credentials, BatchCloseRequest)
MerchantActivationActivateMerchantmerchant onboarding fieldsmerchantActivation(credentials, MerchantActivationRequest)
ForcedAuthForcedAuthauth fields + force-auth detailsforcedAuth(credentials, ForcedAuthRequest)
CardAuthenticationCardAuthentication3DS/card-auth fieldscardAuthentication(credentials, CardAuthenticationRequest)
DebitSaleDebitSaledebit card/PIN transaction fieldsdebitSale(credentials, DebitSaleRequest)
DebitReturnDebitReturndebit refund fieldsdebitReturn(credentials, DebitReturnRequest)
CashSaleCashSalecash sale amount/order fieldscashSale(credentials, CashSaleRequest)
NotificationNotificationcallback/event payload fieldsnotification(credentials, NotificationRequest)
GenerateReceiptGenerateReceipttransactionID, receipt delivery fieldsgenerateReceipt(credentials, GenerateReceiptRequest)
SearchTransactionSearchTransactionsearch criteria (transactionID, refs, date ranges)searchTransaction(credentials, SearchTransactionRequest)
GenerateKeyGenerateKeykey generation payload (no merchant credentials wrapper)generateKey(GenerateKeyRequest)

3.2 Newer Operations

Network Tokenization (4)

OperationRequest WrapperKey FieldsKotlin Method
GenerateTokenGenerateTokenPAN/tokenization input + customer contextgenerateToken(credentials, GenerateTokenRequest)
GenerateTokenCryptogramGenerateTokenCryptogramtoken + cryptogram context (amount, auth context)generateTokenCryptogram(credentials, GenerateTokenCryptogramRequest)
GetTokenStatusGetTokenStatustoken identifier/status lookup fieldsgetTokenStatus(credentials, GetTokenStatusRequest)
GetTokenCardMetaDataGetTokenCardMetaDatatoken identifier for metadata retrievalgetTokenCardMetadata(credentials, GetTokenCardMetaDataRequest)

EBT (5)

OperationRequest WrapperKey FieldsKotlin Method
EbtCashBenefitPurchaseEbtCashBenefitPurchaseEBT account + purchase amount fieldsebtCashBenefitPurchase(credentials, EbtCashBenefitPurchaseRequest)
EbtCashWithdrawalEbtCashWithdrawalEBT account + withdrawal amount fieldsebtCashWithdrawal(credentials, EbtCashWithdrawalRequest)
EbtElectronicVoucherEbtElectronicVouchervoucher ID + voucher redemption fieldsebtElectronicVoucher(credentials, EbtElectronicVoucherRequest)
EbtFoodStampPurchaseEbtFoodStampPurchasefood-stamp purchase amount/account fieldsebtFoodStampPurchase(credentials, EbtFoodStampPurchaseRequest)
EbtReturnEbtReturnoriginal EBT transaction reference + return amountebtReturn(credentials, EbtReturnRequest)

eInvoice (7)

OperationRequest WrapperKey FieldsKotlin Method
CreateInvoiceCreateInvoiceinvoice amount, recipient, due and metadata fieldscreateInvoice(credentials, CreateInvoiceRequest)
CancelInvoiceCancelInvoiceinvoice identifier + cancel reason/contextcancelInvoice(credentials, CancelInvoiceRequest)
GenerateInvoiceEmailGenerateInvoiceEmailinvoice identifier + recipient email contextgenerateInvoiceEmail(credentials, GenerateInvoiceEmailRequest)
InvoiceAchInvoiceAchinvoice identifier + ACH payment detailsinvoiceAch(credentials, InvoiceAchRequest)
InvoiceSaleInvoiceSaleinvoice identifier + card payment detailsinvoiceSale(credentials, InvoiceSaleRequest)
SearchInvoiceSearchInvoiceinvoice search criteria (ID, merchant/customer/date status)searchInvoice(credentials, SearchInvoiceRequest)
UpdateInvoiceUpdateInvoiceinvoice identifier + mutable invoice fieldsupdateInvoice(credentials, UpdateInvoiceRequest)

Digital Wallet (4)

OperationRequest WrapperKey FieldsKotlin Method
DigitalWalletSaleDigitalWalletSalewallet payload + sale amount/contextdigitalWalletSale(credentials, DigitalWalletSaleRequest)
DigitalWalletAuthDigitalWalletAuthwallet payload + auth amount/contextdigitalWalletAuth(credentials, DigitalWalletAuthRequest)
SecureAuthSecureAuthsecure wallet auth payload (network token + cryptogram)secureAuth(credentials, SecureAuthRequest)
SecureSaleSecureSalesecure wallet sale payload (network token + cryptogram)secureSale(credentials, SecureSaleRequest)

ACH (4)

OperationRequest WrapperKey FieldsKotlin Method
AchSaleAchrouting/account details, amount, SEC contextachSale(credentials, AchSaleRequest)
AchReturnAchReturnoriginal ACH transaction reference + return reasonachReturn(credentials, AchReturnRequest)
AchResubmitAchResubmitoriginal ACH reference + resubmission detailsachResubmit(credentials, AchResubmitRequest)
AchVerificationAchVerificationaccount verification (routing/account/customer fields)achVerification(credentials, AchVerificationRequest)

Signature and EMV Enrichment

OperationRequest WrapperKey FieldsKotlin Method
UpdateSignatureUpdateTransactionSignaturetransactionID, signature payload (signatureData/image fields)updateSignature(credentials, UpdateSignatureRequest)
EMV EnrichmentTransactionAdjustment plus EMV fields on sale/auth requestsL2/L3 line items (level2Data, level3Data) and EMV request fields (emvTags, terminal/card-present capability fields)l2l3Adjust(credentials, L2L3AdjustRequest) and EMV-capable sale/authorize models

3.3 Processing Service Delegation

services/processing/src/main/kotlin/com/myriad/gateway/processing/service/TransitPaymentProcessor.kt is the adapter from service DTOs to transit-client models:

  • injects TransitClient as a constructor dependency (@Component)
  • maps SaleRequest, AuthRequest, capture/void/refund/tip/enrichment inputs into transit-client request DTOs
  • delegates to sale, authorize, capture, void, refund, tipAdjust, l2l3Adjust, and batchClose
  • maps transit responses back to TransactionResult
  • maps TransitException types to service-layer behavior (declines -> declined result, auth/network/server errors -> service exceptions)

4. Transaction Industry Types

CodeTypeUse Case
RERetailPeakPOS in-store transactions
ECE-CommerceOnline payment website
RSRestaurantDerived for restaurant MCCs such as 5812-5814
HCHealthcareDerived for healthcare MCCs such as 8011
DMDirect MarketingMail/phone orders, actively used now
LDLodgingDerived for lodging MCCs such as 7011 and 3500-3999

5. Card Data Sources

CodeDescriptionOur Usage
MANUALManually keyed card numberManagement portal manual entry, online payments
SWIPEMagnetic stripePre-certified terminal
EMVChip insertionPre-certified terminal
CONTACTLESSNFC tapPre-certified terminal
TOKENPreviously tokenized cardRecurring payments, stored cards
INTERNETE-commerce transactionOnline payment website

5.1 SoftPOS / Tap on Phone Mapping Gap

The downloaded Visa, Mastercard, Amex, Apple, and PCI MPoC materials define network-level requirements that are only partially mapped to the local TransIT server-to-server materials. Do not implement production SoftPOS authorization mapping until TSYS confirms the exact host fields for software-based contactless acceptance.

Public TSYS operating-guide pages confirm the merchant-processing rules surface, but they are not enough to derive the TransIT Multipass JSON request shape for SoftPOS. Authenticated TransIT developer portal / partner docs are available and are the primary next source for implementation details before escalating to the TSYS account team.

Known inputs from current docs:

  • TransIT already supports card-present EMV/contactless flows for pre-certified terminals and returns EMV metadata such as emvTags[], emvAppLabel, cardDataEntry, and host transaction identifiers.
  • The local emv_samples.json file labels sale/auth/debit examples as NFC / EMV / EMVContactless, but submits those requests with cardDataSource = EMV, emvTags.tag[], terminal capability fields, card-present/cardholder-present fields, and host response fields for issuer scripts and issuer authentication data.
  • The same EMV sample set shows online PIN transport fields (pin, pinKsn) on a debit EMVContactless example. This is useful evidence for the field names, but it does not prove SoftPOS PIN block format, DUKPT domain, or host key requirements.
  • The local digital_wallet_samples.json file covers card-not-present SecureAuth/SecureSale wallet-token flows using INTERNET or PHONE sources plus wallet payloads. Those examples are not evidence for card-present Tap to Phone or Apple Tap to Pay on iPhone submission.
  • The local TransIT v6.2 certification workbook covers ecommerce, direct marketing / MOTO, recurring/installment, non-SDK in-app, and merchant activation scenarios. It does not appear to include a dedicated SoftPOS, Tap to Phone, or card-present EMV host-cert script.
  • Visa Tap to Phone documentation says the authorization and clearing path must identify Tap to Phone / mobile acceptance. For Base I/SMS authorization, the source material calls out terminal type 9, terminal entry capability 8, and Field 55 supplemental Form Factor Indicator tag 9F6E byte 4 bit 8 set. For clearing/settlement it calls out corresponding mobile/proximity indicators.
  • Mastercard Tap on Phone documentation requires the acquirer/processor path to identify the acceptance channel as Tap on Phone; the implementation guide specifically calls out PDS 0023 = CT9.
  • Amex contactless documentation requires contactless identification in Point of Service Data Code position 6 using X.
  • The Amex SoftPOS kernel returns outcome, message, Field 55, transaction tag data, and online PIN indicators that must be preserved through gateway processing and certification evidence.
  • Apple Tap to Pay on iPhone produces an encrypted card-read result in the app, then the PSP backend calls Apple's Proximity Payment Service, validates Apple's signed response, unwraps data through the PSP HSM, and receives cardholder / EMV tag data plus reader and transaction identifiers that must be logged for troubleshooting.
  • The local TransIT sample set includes EMV terminal fields and online PIN fields (pin, pinKsn) for device-originated debit flows, but does not prove the SoftPOS request shape for direct gateway submission.

Open TSYS / online-doc confirmation items:

  • Whether SoftPOS contactless sale/auth requests should use cardDataSource = EMV, CONTACTLESS, or another value. Current local sample evidence points to EMV for EMVContactless samples, while the support-doc source table still lists CONTACTLESS for NFC taps.
  • Which terminal/card-present capability fields must be populated for iOS and Android SoftPOS.
  • Where Visa terminal type 9, Visa terminal entry capability 8, Visa Form Factor Indicator tag 9F6E, Mastercard CT9, Amex contactless indicator X, CDCVM state, kernel outcome, and contactless reader capability flags are carried in TransIT / TSYS messages.
  • Exact Field 55/tag format, allowed tag list, and whether raw kernel tag maps must be transformed or filtered before submission.
  • Online PIN support path for SoftPOS, including PIN block format, KSN handling, debit routing indicators, and whether host-side keys differ from pre-certified terminal keys.
  • Whether Apple Tap to Pay on iPhone decrypted output and Android SoftPOS device-token / kernel-output flows use SecureAuth/SecureSale models, card-present EMV models, or a distinct TransIT operation.
  • Whether Apple readerIdentifier and PaymentCardReadResult.id / transaction identifier should be carried to TransIT, stored only in gateway evidence, or both.
  • Whether the online TransIT certification packet has a newer SoftPOS / Tap to Phone host-cert script than the local v6.2 workbook.

Until these items are answered, the processing service should persist full kernel outputs for diagnostics and certification evidence, but keep SoftPOS host-submission mapping behind a disabled capability flag.

5.2 TSYS SoftPOS Question Packet

Use this first against the authenticated TransIT online docs / developer portal. Anything not answered there becomes the outbound checklist for the TSYS account / certification team. The answer should be specific enough to implement TransitPaymentProcessor mapping, write test fixtures, and prepare Visa / Mastercard / Amex certification evidence.

AreaQuestionsWhy it blocks implementation
Operation / wrapperShould Android SoftPOS and Apple Tap to Pay on iPhone use Sale / Auth / DebitSale, SecureAuth / SecureSale, or a separate TransIT operation?Determines transit-client DTOs, processing service routing, and certification fixtures.
Card data sourceFor contactless SoftPOS, should cardDataSource be EMV, CONTACTLESS, or another value? Does the answer differ for iOS Apple Tap to Pay output?Local EMVContactless samples use EMV, but network Tap to Phone indicators still need explicit host support.
EMV tag transportWhat tag container should carry Field 55 / kernel output? Which tags are required, optional, filtered, or transformed by TSYS?SDK-05 metadata and NET-07 evidence need to preserve exactly what the host expects.
Visa indicatorsWhere do Visa terminal type 9, terminal entry capability 8, and Form Factor Indicator tag 9F6E byte 4 bit 8 land in TransIT requests and clearing?Required for Visa Tap to Phone transaction coding and L3 evidence.
Mastercard indicatorsWhere is Mastercard Tap on Phone PDS 0023 = CT9 represented in the TransIT request / host message?Required for Mastercard M-TIP and Tap on Phone acceptance identification.
Amex indicatorsWhere is Amex contactless Point of Service Data Code position 6 value X represented?Required for Amex contactless / SoftPOS L3 evidence.
Terminal capability fieldsWhich TransIT terminal/card-present fields are mandatory for software acceptance on Android and iOS?Prevents cert failures caused by defaulting traditional terminal values.
Online PINAre pin and pinKsn the correct fields for SoftPOS Online PIN? Which PIN block format, KSN format, key domain, and debit-routing fields are required?Determines whether Online PIN is supported for SoftPOS and how MPoC evidence expands.
Apple identifiersShould Apple readerIdentifier, PaymentCardReadResult.id, PSP transaction ID, or Proximity Payment Service response IDs be submitted to TransIT, retained only by gateway, or both?Needed for dispute support, Apple troubleshooting, and certification trace correlation.
Certification scriptIs there a TransIT SoftPOS / Tap to Phone host-cert script separate from the current v6.2 ecommerce / MOTO / in-app workbook?The local workbook does not include SoftPOS card-present scenarios.
Environment setupWhich test credentials, device IDs, terminal profiles, BIN routing, and merchant category settings are needed for Visa, Mastercard, and Amex SoftPOS certification?Blocks end-to-end test runs and evidence collection.
Receipts / response fieldsWhich response fields should the gateway persist for issuer scripts, issuer authentication data, receipt text, card entry mode, and network transaction identifiers?Required for issuer-script completion, audit, and support traceability.

6. Response Codes

Approval Codes (Prefix: A)

CodeMeaning
A0000Approved
A0001Approved (partial)

Decline Codes (Prefix: D)

CodeMeaning
D0092Declined, general
D1218Declined, invalid card
D1219Declined, expired card
D1220Declined, insufficient funds
D1221Declined, CVV mismatch
D1222Declined, AVS mismatch
D1223Declined, card restricted
D1224Declined, do not honor
D1225Declined, pickup card
D1226Declined, invalid transaction

Error Codes (Prefix: E)

CodeMeaning
E0913Error, invalid device credentials
E0XXXError, communication failure

NOTE: Full response code table available in TransIT API documentation (requires developer access).


7. Semi-Integrated Device Flow, NexGO SmartConnect API

For card-present transactions, PeakPOS communicates with NexGO's pre-certified Integrator app via the SmartConnect API. SmartConnect uses Android Intents (on-device, preferred) or TCP (port 8765, cross-device) to pass JSON messages. Card data never touches our PeakPOS app or servers.

7.1 SmartConnect Flow

┌──────────────┐ ┌───────────────────────┐ ┌─────────────┐
│ PeakPOS App │ │ NexGO Integrator App │ │ TransIT │
│ (Android) │ │ (SmartConnect API, │ │ Multipass │
│ │ │ Pre-Certified EMV) │ │ API │
└──────┬───────┘ └──────────┬────────────┘ └──────┬──────┘
│ │ │
│ 1. Android Intent │ │
│ w/ JSON request │ │
│───────────────────────>│ │
│ │ │
│ │ 2. Integrator takes │
│ │ screen, prompts │
│ │ insert/tap/swipe │
│ │ │
│ │ 3. Encrypts card data, │
│ │ sends to TransIT │
│ │────────────────────────>│
│ │ │
│ │ 4. TransIT processes, │
│ │ returns auth result │
│ │<────────────────────────│
│ │ │
│ 5. Intent result │ │
│ w/ JSON response │ │
│ (transdata extra) │ │
│<───────────────────────│ │
│ │ │
│ 6. PeakPOS logs result │ │
│ via Processing │ │
│ Microservice │ │

7.2 SmartConnect Request Format

PeakPOS sends an Android Intent with a JSON payload:

val intent = Intent("android.intent.action.Integrator")
intent.putExtra("Input", requestJson.toString())
startActivityForResult(intent, REQUEST_CODE)

Sale Request

{
"action": {
"accountType": 0,
"processor": "<TSYS_TI>",
"receipt": true,
"signature": true,
"manual": true
},
"payment": {
"type": "Sale",
"amount": "10.00",
"tip_amount": "0.00",
"cash_back": "0.00"
}
}

Auth (Pre-Authorization) Request

{
"action": { "processor": "<TSYS_TI>", "receipt": true },
"payment": {
"type": "Auth",
"amount": "10.00",
"tip_amount": "0.00"
}
}

Capture (Post-Auth) Request

{
"action": { "processor": "<TSYS_TI>", "receipt": true },
"payment": {
"type": "Capture",
"amount": "10.00",
"tip_amount": "0.00",
"transaction_id": "<transactionID from Auth>",
"trace_no": "<traceNo from Auth>"
}
}

Either transaction_id or trace_no must be included. If both are present, transaction_id takes precedence.

Void Request

{
"action": { "processor": "<TSYS_TI>", "receipt": true },
"payment": {
"type": "Void",
"transaction_id": "<transactionID>",
"trace_no": "<traceNo>"
}
}

Return (Refund) Request

{
"action": { "processor": "<TSYS_TI>", "receipt": true },
"payment": {
"type": "Return",
"amount": "5.00"
}
}

Tip Adjustment Request

{
"action": { "processor": "<TSYS_TI>", "receipt": true },
"payment": {
"type": "Tip Adjustment",
"amount": "10.00",
"tip_amount": "3.00",
"transaction_id": "<transactionID>",
"trace_no": "<traceNo>"
}
}

Note (EVO-specific): Tip Adjustment on EVO can only modify the tip, not the base amount. Confirm TransIT behavior matches.

Action Field Reference

FieldTypeRequiredDescription
processorStringMProcessor identifier. Can be left blank if only one Integrator is installed.
receiptbooleanMPrint receipt on terminal's integrated printer
signaturebooleanOPrompt for on-screen signature after approval
manualbooleanOAllow manual/keyed card entry (vs. swipe/EMV/tap only)
accountTypeStringO0 = Automatic, 1 = Credit, 2 = Debit

Payment Field Reference

FieldTypeRequiredDescription
typeStringMTransaction type: Sale, Auth, Capture, Void, Return, Tip Adjustment, BatchClose, BatchDetail, BatchSummary, Reprint, getLastStatus, TerminalInfo, EBTFSPurchase, EBTCBPurchase, EBTBalance, EBTFSReturn
amountStringMBase transaction amount (e.g., "10.00")
tip_amountStringOTip amount. If omitted, Integrator prompts user for tip on screen.
cash_backStringOCash back amount
transaction_idStringO/MHost transaction ID (for Void, Capture, Tip Adjust). Either this or trace_no required.
trace_noStringO/MLocal terminal transaction ID (for Void, Capture, Tip Adjust)
panDataTokenStringOPayment token for card-on-file transactions (see section 7.5)
taxRateStringOTax rate percentage (TSYS Sierra only)
customTaxOneRateStringOCustom tax rate (TSYS Sierra only)
customTaxTwoRateStringOCustom tax rate (TSYS Sierra only)

7.3 SmartConnect Response Format

Response is returned via the Intent result in onActivityResult():

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
val response = data?.getStringExtra("transdata") // JSON response
val signature = data?.getByteArrayExtra("signature") // Signature bitmap (if requested)
}

Sale/Auth Response Fields

FieldTypeDescription
batchIDStringBatch number (e.g., "000004")
transactionIDStringHost transaction ID, use for Void, Capture, Tip Adjust
traceNoStringLocal terminal transaction ID
transactionTypeStringe.g., "Credit Sale", "Pre-Auth", "Void", "Credit Refund", "Add Tip"
baseAmountStringBase amount processed (excluding tip)
tipAmountStringTip amount ("0.00" if none)
cashbackAmountStringCash back amount ("0.00" if none)
processedAmountStringTotal processed (base + tip + fees)
resultCodeString"00" = approved. Non-zero = declined/error. -501 = cancelled.
cardNumberStringLast 4 digits only (e.g., "0010")
cardIssuerStringCard brand (e.g., "VISA", "MASTERCARD")
cardDataEntryStringEntry method: "SWIPED", "CHIP READ (I)", "CONTACTLESS", "KEYED", "TOKEN"
panDataTokenStringPayment token for subsequent card-on-file charges
referenceNumberStringHost reference number for troubleshooting with processor
authorizationCodeStringProcessor authorization code
merchantIdStringMerchant account ID used for processing
applicationVersionStringIntegrator app version (e.g., "N08.011.066_49")
fwVersionStringTerminal firmware version
emvTags[]JSON ArrayEMV tag key-value pairs (e.g., "9F06=A0000000031010")
cardHolderStringCardholder name from card (if present)
accountTypeString"Credit" or "Debit" (TSYS Sierra only)
cardBINStringCard BIN (TSYS Sierra only)
emvAppLabelStringEMV application label (e.g., "MasterCard")
Full JSON responseJSON ObjectStore for debugging

Sample Sale Response (TSYS TransIT)

{
"packetID": "XCRT",
"packetData": {
"batchID": "000004",
"transactionID": "53ABB10B5BFF49C7A20B456AD7040BBD",
"traceNo": "6",
"transactionType": "Credit Sale",
"baseAmount": "1.00",
"tipAmount": "0.00",
"cashbackAmount": "0.00",
"resultCode": "00",
"cardNumber": "0010",
"cardIssuer": "VISA",
"cardDataEntry": "CHIP READ (I)",
"referenceNumber": "000001560420",
"authorizationCode": "556475",
"merchantId": "000000001168579",
"applicationVersion": "N08.011.066_49",
"fwVersion": "v4.5.5",
"emvTags": [
"9F06=A0000000031010",
"5F2A=0840",
"9F36=0042",
"9F26=6206484E62C59D54",
"9F02=000000000100",
"82=5C00",
"95=42C0008000"
],
"cardHolder": "TEST CARD 01"
}
}

SmartConnect Result Codes

resultCodeDescription
00Success / Approved
Non-zeroDeclined, check processor response for meaning
-50XGeneral application error
-501Transaction cancelled by user

7.4 SmartConnect Transaction Type Support (TSYS TransIT)

Transaction TypeTSYS TransITNotes
SaleCredit + Debit
Credit/Debit SelectionNot supported on TransIT
Auth (Pre-Auth)
Capture (Post-Auth)Reference by transaction_id or trace_no
Void
Return (Refund)
Tip Adjustment
ReprintReprint last receipt / retrieve last response JSON
getLastStatusGet raw JSON from last transaction
BatchCloseSettle the open batch (see section 9)
BatchDetailPer-transaction batch listing
BatchSummaryAggregate batch totals
EBTFSPurchaseEBT Food Stamp
EBTCBPurchaseEBT Cash Benefit
EBTBalanceNot supported on TransIT
EBTFSReturn
EBTFSVoucher
EBTFSVoucherReturnNot supported on TransIT
Gift (all types)Not supported on TransIT
DEVICE_INFONot supported on TransIT

7.5 SmartConnect Token Payments (panDataToken)

SmartConnect supports sending a panDataToken in the request to charge a previously tokenized card without requiring the physical card:

{
"action": { "processor": "<TSYS_TI>", "receipt": true },
"payment": {
"type": "Sale",
"panDataToken": "03a0106a-d62a-4a47-9301-6060c1774e26...",
"amount": "10.00",
"tip_amount": "0.00"
}
}

On approved transactions, the response includes a panDataToken field that can be stored for subsequent card-on-file use.

⚠️ SmartConnect Replay Boundary: As of SmartConnect API rev. 1.18 (Oct 2024), panDataToken replay is documented for the EVO Integrator application but not for the TSYS TransIT Integrator. Treat SmartConnect token replay as unsupported for TransIT unless NexGO certification evidence says otherwise. Card-present token capture can still store returned tokens, but recurring or card-on-file replay must use the gateway's server-to-server TransIT token path rather than sending panDataToken back through SmartConnect.

7.6 SmartConnect Communication Modes

ModeWhen to UseDetails
Android Intent (preferred)PeakPOS runs on same device as Integratorintent.setAction("android.intent.action.Integrator"), auto-starts Integrator if not running
TCPExternal device initiating paymentConnect to terminal IP on port 8765. Same JSON format. Must handle socket lifecycle.

PeakPOS uses Android Intent when it runs on the same NexGO device as the Integrator.

7.7 PeakPOS to SmartConnect Response Mapping

The PeakPOS app must map SmartConnect response fields to the monorepo's card_authorizations schema:

SmartConnect FieldMonorepo Schema FieldNotes
transactionIDprocessor_transaction_idHost transaction ID
traceNoterminal_trace_no (new)Local terminal ID, needed for Void/Capture/Tip Adjust
batchIDbatch_id
baseAmountamountParse string to cents
tipAmounttip_amount
cashbackAmountcashback_amount
processedAmountprocessed_amount
resultCoderesponse_code"00" = approved
authorizationCodeapproval_code
cardNumbercard_last_fourLast 4 only
cardIssuercard_brand
cardDataEntrycard_data_entrySWIPED/CHIP/CONTACTLESS/KEYED/TOKEN
panDataTokentokenStore for card-on-file
referenceNumberreference_number
merchantIdprocessor_merchant_id
emvTags[]emv_data (JSONB)Parse array to structured object
cardHoldercardholder_name
emvAppLabelemv_app_label
Full JSON responseraw_response (JSONB)Store complete response for debugging

8. Tokenization Strategy, Guardian Tokenization

TransIT provides tokenization through Guardian Tokenization, a TSYS-native token vault that replaces card PANs with non-reversible token values. Guardian tokens are the foundation for recurring billing, card-on-file, and refund-on-original-card flows.

8.1 How Guardian Tokenization Works

  1. Token generation: On any transaction where tokenRequired: "Y", TransIT returns a tokenID alongside the authorization response
  2. Token usage: Subsequent transactions send tokenID in the cardNumber field with cardDataSource: "TOKEN", no raw card data needed
  3. Token scope: Tokens are scoped to our deviceID. A token generated under one deviceID cannot be used under another
  4. Token persistence: Tokens remain valid as long as the underlying card is valid, no separate expiration on the token itself

8.2 Token Lifecycle

┌──────────────────────┐
│ Transaction with │
│ tokenRequired: "Y" │
└──────────┬───────────┘

v
┌──────────────────────┐
│ ACTIVE │ <- Token returned in response
│ (usable for charges) │
└──────────┬───────────┘

┌───────┼────────┐
│ │ │
v v v
┌──────┐ ┌──────┐ ┌─────────┐
│ Used │ │ Card │ │ Explicit│
│ for │ │ exp │ │ delete │
│ TOKEN│ │ or │ │ request │
│ txns │ │ lost │ │ │
└──────┘ └──┬───┘ └────┬────┘
│ │
v v
┌──────────┐ ┌──────────┐
│ INACTIVE │ │ DELETED │
│ (decline │ └──────────┘
│ on use) │
└────┬─────┘

v
┌──────────┐
│ DELETED │ (after cleanup period)
└──────────┘

8.3 Token Generation, Card Present vs. Card Not Present

ChannelHow Token is GeneratedCard Data Source
Card Present (NexGO)SmartConnect semi-integration: NexGO Integrator handles card capture, sends to TransIT, panDataToken returned in SmartConnect response, PeakPOS stores tokenEMV, CONTACTLESS, SWIPE
Card Not Present (Server-to-Server)Merchant sends card data via API, Processing Service sends to TransIT with tokenRequired: "Y", token storedMANUAL, INTERNET
Card Not Present (Hosted Payment)Customer enters card in hosted page/iFrame, TransIT handles PCI-scoped tokenization, token returned to our backendINTERNET
Existing TokenSubsequent charges (recurring, card-on-file) use stored tokenIDTOKEN

⚠️ Card-Present Token Replay Boundary: SmartConnect returns panDataToken in responses, but replaying that token in a SmartConnect request is only documented for EVO. For TSYS TransIT, route card-present token replay through the gateway's server-to-server TransIT token path unless NexGO certification evidence explicitly approves SmartConnect replay.

8.4 Token-to-Customer Mapping

Our gateway maintains the relationship between Guardian tokens and customers in the stored_tokens table (Online Txn Service):

Customer "cust_001" (Jane Doe)
├── tok_visa_1234 → Visa ****1234, exp 12/27 (ACTIVE, primary)
├── tok_mc_5678 → MC ****5678, exp 03/28 (ACTIVE)
└── tok_visa_9012 → Visa ****9012, exp 01/26 (INACTIVE, expired)

Customer "cust_002" (John Smith)
└── tok_amex_3456 → Amex ****3456, exp 09/27 (ACTIVE, primary)

Rules:

  • One customer can have multiple stored tokens (multiple cards)
  • Each token links to exactly one customer_id and one merchant_id
  • Tokens are merchant-scoped: a token stored by merchant A cannot be used by merchant B (Guardian's deviceID scoping enforces this at the TSYS level)
  • Customers can designate a "primary" token for default recurring charges
  • On card update (new expiry, replacement card), merchant must create new token. Guardian tokens are immutable

8.5 Token Usage for Recurring Billing

The subscription billing engine (Processing Microservice) uses Guardian tokens to execute recurring charges:

1. Billing job queries due subscriptions
2. For each subscription, retrieves stored tokenId
3. Sends TOKEN sale to TransIT:
{
"SaleTransaction": {
"deviceID": "...",
"transactionKey": "...",
"cardNumber": "<tokenID>", <- Guardian token, NOT a PAN
"cardDataSource": "TOKEN",
"transactionAmount": "49.99",
"transactionIndustryType": "EC",
"tokenRequired": "N" <- Already have token, don't need new one
}
}
4. TransIT resolves token, charges underlying card
5. Response handled same as any sale (approved/declined)

Decline handling for recurring: If a recurring TOKEN charge is declined, the token status is not automatically changed. The subscription enters retry/dunning flow. Only persistent declines (card cancelled, account closed) should trigger token deactivation.

8.6 NMI Token Migration Strategy

The existing PeakPOS monorepo uses NMI as its payment processor. Customers already have NMI tokens stored in the card_authorizations table (field: token). When migrating merchants from NMI to Peak Gateway (TSYS TransIT):

NMI tokens are not compatible with Guardian tokens. Migration requires re-tokenization.

Migration ApproachDescriptionProsCons
Gradual re-tokenizationOn next customer transaction (any channel), capture card data, generate Guardian token, store alongside the NMI token, subsequent charges use GuardianNo bulk migration, zero downtimeStale customers may never re-tokenize
Card-on-file migrationFor active recurring customers, use NMI's card-on-file data to generate a Guardian token via a one-time batch processComplete migration for active subscribersRequires NMI to allow one final charge/verification per token; PCI implications of handling card data in transit
Customer re-entryNotify customers to re-enter card data via hosted payment pageCleanest from PCI perspectiveWorst customer experience; guaranteed churn

Recommended: Gradual re-tokenization as default, with card-on-file migration for merchants with active recurring/subscription billing that must continue uninterrupted. Track migration status per-merchant:

merchant.tokenMigrationStatus:
NOT_STARTED -> IN_PROGRESS -> COMPLETED

Per stored token:
nmi_token: "nmi_abc123" (original)
guardian_token: "tok_xyz789" (new, null until re-tokenized)
migration_status: PENDING | MIGRATED

8.7 Token Security & PCI Considerations

  • Guardian tokens are non-reversible, cannot derive card PAN from token
  • Tokens are scoped to our deviceID, compromised token is useless without our TransIT credentials
  • Our systems never store raw card data (PANs, CVVs), only Guardian token IDs
  • Card-present tokens: card data never touches our servers (NexGO semi-integration handles encryption)
  • Card-not-present tokens: raw card data is transmitted to TransIT in the initial tokenization call, but our gateway acts as a pass-through, we log the token, not the PAN
  • Hosted payment tokens: card data enters TransIT's hosted page directly, never touches our infrastructure

NOTE: Verify Guardian token-management changes against the authenticated TransIT documentation and certification fixtures before changing request serialization. Token deletion and deactivation APIs may have additional processor-specific parameters.


9. Settlement & Batch Management (via SmartConnect)

TransIT is a host-capture platform, batch management happens on the TSYS cloud. We manage batches ourselves through SmartConnect's batch operations on the terminal, not through the TSYS Merchant Center portal.

Settlement Modes

ModeDescription
ScheduledAuto-settle at a configured time daily. Default dev batch closing: 10:30 PM
On-DemandManual batch close via SmartConnect BatchClose request from PeakPOS or gateway

SmartConnect Batch Operations

BatchDetail, View All Transactions in Current Batch

// Request
{
"action": { "processor": "<TSYS_TI>", "receipt": true },
"payment": { "type": "BatchDetail" }
}

// Response
{
"packetID": "XCRT",
"packetData": {
"batchID": "000004",
"transactionType": "BatchDetail",
"timestamp": "2026-03-08 13:51",
"transactions": [
{
"traceNo": "1",
"transactionID": "8420679",
"transactionType": "Sale",
"referenceNumber": "123456789",
"authorizationCode": "556475",
"cardDataEntry": "SWIPE",
"cardHolder": "JOHN DOE",
"baseAmount": "10.00",
"tipAmount": "2.00",
"cashbackAmount": "0.00",
"feeAmount": "0.50",
"taxAmount": "0.10",
"processedAmount": "12.60",
"timestamp": "2026-03-08 11:30"
}
]
}
}

Use case: Display batch contents in PeakPOS, identify problematic transactions before settlement, reconcile terminal batch against gateway records.

BatchSummary, Aggregate Batch Totals

// Request
{
"action": { "processor": "<TSYS_TI>", "receipt": true },
"payment": { "type": "BatchSummary" }
}

// Response
{
"packetID": "XCRT",
"packetData": {
"batchID": "000004",
"transactionType": "BatchSummary",
"timestamp": "2026-03-08 13:51",
"summary": [{
"cashSaleCount": "1",
"cashSaleAmount": "5.00",
"cashReturnCount": "0",
"cashReturnAmount": "0.00",
"totalCash": "5.00",
"creditDebitCount": "4",
"creditDebitAmount": "48.00",
"creditDebitReturnCount": "1",
"creditDebitReturnAmount": "5.00",
"totalCreditDebit": "43.00",
"ebtCount": "1",
"ebtAmount": "12.00",
"ebtReturnCount": "0",
"ebtReturnAmount": "0.00",
"totalEbt": "12.00",
"giftRedeemCount": "0",
"giftRedeemAmount": "0.00",
"giftActivateCount": "0",
"giftActivateAmount": "0.00",
"giftReloadCount": "0",
"giftReloadAmount": "0.00",
"totalAmount": "60.00"
}]
}
}

Use case: End-of-day summary display, quick reconciliation check before settling.

BatchClose, Settle the Batch

// Request
{
"action": { "processor": "<TSYS_TI>", "receipt": true },
"payment": { "type": "BatchClose" }
}

// Response (TSYS TransIT-specific)
{
"packetID": "XCRT",
"packetData": {
"batchID": "000004",
"transactionType": "BatchClose",
"resultCode": "00",
"merchantId": "000000001168579",
"applicationVersion": "N08.011.066_49",
"fwVersion": "v4.5.5",
"settlementTime": "2026/03/08 22:30:01",
"creditSaleCount": "6",
"creditSaleAmount": "120.00",
"creditReturnCount": "1",
"creditReturnAmount": "5.00",
"debitSaleCount": "2",
"debitSaleAmount": "30.00",
"debitReturnCount": "0",
"debitReturnAmount": "0.00",
"transITHostResponseObject": {
"BatchCloseResponse": {
"batchInfo": {
"returnAmount": "500",
"returnCount": "1",
"sICCODE": "5999",
"saleAmount": "15000",
"saleCount": "8"
},
"responseCode": "A0000",
"responseMessage": "Success",
"status": "PASS"
}
},
"hostReturnAmount": "5.00",
"hostReturnCount": "1",
"hostSaleAmount": "150.00",
"hostSaleCount": "8"
}
}

TransIT-specific fields in BatchClose response:

FieldDescription
transITHostResponseObjectFull parsed host response from TransIT (JSON object)
hostSaleCount / hostSaleAmountHost-reported sale totals, use for reconciliation against terminal counts
hostReturnCount / hostReturnAmountHost-reported return totals

Reconciliation: Compare terminal-reported counts (creditSaleCount, etc.) against host-reported counts (hostSaleCount, etc.). Discrepancies indicate transactions that were processed locally but not received by the host, or vice versa.

Batch Management Workflow

1. During business day: PeakPOS processes Sales, Auths, Voids, Returns
2. Before settlement: PeakPOS calls BatchDetail to review transactions
- Identify bad/problematic transactions
- Void incorrect transactions (before batch closes)
- Apply tip adjustments
3. At configured time (10:30 PM default): PeakPOS sends BatchClose
- Or: Gateway triggers BatchClose via TCP to terminal
4. After settlement: Gateway compares terminal response vs. host response
- Flag discrepancies for manual review
- Store reconciliation results in CDE Spanner
5. New batch opens automatically after settlement

Void Rules

Void TypeAvailability
Full voidBefore batch settlement only
Partial voidBefore batch settlement only
After settlementMust use refund (Return) instead

10. Recurring & Scheduled Payments via TransIT

How Recurring Works at the TransIT Level

TransIT does not have a native subscription/recurring billing engine. Recurring billing is implemented by our gateway, the Processing Microservice's subscription engine schedules and executes TOKEN-based sale transactions at configured intervals.

TransIT's Role in Recurring

ResponsibilityOwner
Subscription creation, lifecycle, schedulingPeak Gateway (Processing Microservice)
Dunning logic (retries on decline)Peak Gateway (Processing Microservice)
Executing the actual chargeTransIT (via TOKEN sale)
Token storage & resolutionTransIT (Guardian Tokenization)
Token-to-customer mappingPeak Gateway (Online Txn Service)

Transaction Flow for a Recurring Charge

Peak Gateway (scheduler)

│ 1. Query subscriptions due today
│ 2. For each: look up Guardian tokenId

v
Processing Microservice

│ 3. POST SaleTransaction with cardDataSource: "TOKEN"

v
TransIT Multipass API

│ 4. Resolve Guardian token, card PAN
│ 5. Process sale against issuer
│ 6. Return approval/decline

v
Processing Microservice

│ 7a. Approved, update subscription cycle, publish event
│ 7b. Declined, increment failed_attempts, schedule retry

Industry Type for Recurring

  • Recurring charges for online merchants: transactionIndustryType: "EC" (E-Commerce)
  • Recurring charges for mail/phone order merchants: transactionIndustryType: "DM" (Direct Marketing)
  • The industry type is set per-merchant in their configuration, not per-subscription

Certification Note

Recurring billing uses the same TOKEN-based sale flow as card-on-file payments. No separate certification is needed for recurring billing specifically, it falls under the Card Not Present (server-to-server) certification scope. Once CNP is certified, recurring billing works automatically.


11. Certification Scope

Pre-Certified (No Additional Certification Needed)

CapabilityStatus
Level 3 EMV (Card Present)Pre-certified, works out of the box with NexGO semi-integration

Requires Separate Certification

CapabilityCertificationNotes
Back OfficeSeparate certNexGO integration, Sales/Refund/Void/Batch Management, Tokenization (if needed)
Card Not PresentSeparate certServer-to-server, not pre-certified
Hosted Payment 2.0Separate certSale-only, "really simple certification process"
Apple PaySeparate certAfter base CNP certification
Google PaySeparate certAfter base CNP certification

Key Certification Rule

Adding new capabilities does NOT extend existing certification, only new items need testing.

Each new feature or payment method requires its own certification testing with TSYS. Plan certification batches strategically to minimize re-testing.


12. Error Handling & Retry Strategy

ScenarioAction
Network timeout to TransITRetry with exponential backoff (max 3 attempts, 1s -> 2s -> 4s)
TransIT returns 5xxRetry with exponential backoff (max 3 attempts)
TransIT returns 4xxDo NOT retry. Log error, return failure to caller.
Duplicate transaction suspectedUse idempotency key (Spanner) to prevent double-charge
TransIT unreachableQueue transaction in Pub/Sub for retry. Alert ops.

Idempotency

Every transaction request includes a client-generated externalReferenceID (UUID). If a timeout occurs and we retry, TransIT will recognize the duplicate and return the original response.


13. References