Skip to content
TilloTech Docs

InComm Processor and API

This reference describes the active asynchronous InComm issuer and the deprecated synchronous issuer that can still appear in historical sales. It covers the provider calls, card mapping, retry states, configuration, audit evidence, and operational tools implemented in the repository.

Processor modes and scope

InCommAsyncProcessor is the active issuer. The issuer migration marks it as asynchronous, and a later migration moves brands from InCommSyncProcessor to it. InCommSyncProcessor is marked deprecated and is retained because its side effects are not known.

CapabilityAsync issuerLegacy sync issuer
Create callPOST /ordersPOST /orders/immediate
Card retrievalQueue-driven getByOrder(orderUri)In-process polling of /orders/{orderUri}/cards
Processor referenceorderUri from the Location headerorderUri from the create response
BalanceSupported; requires a PIN at the processor interfaceSupported
CancellationSupported through card lookup and voidSupported through card lookup and void
CashoutNo implementation in the async classcashoutGC() returns false

The HTTP client accepts CAD, USD, AUD, and NZD environments. The legacy constructor resolves program IDs for CAD, USD, and AUD; the active async constructor resolves all four.

Async lifecycle

  1. The sale is assigned to InCommAsyncProcessor and the processor resolves the SKU from the brand and face value.
  2. requestCode() sends an order with the sale UUID as both customerorderid and purchaseordernumber. The partner database ID is included in JSON metadata.
  3. InComm normally returns 202 Accepted with a Location header. The wrapper extracts the final path segment as orderUri, stores it as processor_ref, and returns a pending card.
  4. A returned card with a provider reference is handed to AsyncFetchCode; a pending card without a usable reference is requeued for another issue attempt. A duplicate response for the same customer order supplies the existing orderUri, after which the job schedules AsyncFetchCode.
  5. retrieveCode() calls GET /cards/order/{orderUri} and uses the first returned card. A successful response is mapped to the application card and completes the sale.
  6. Balance lookup first finds the original sale by gift-card code, retrieves its order card, then calls GET /cards/{cardUri}/balance. Cancellation retrieves the card URI and calls POST /Cards/{cardUri}/void.

The legacy sync path calls the provider create operation and then polls /orders/{orderUri}/cards up to 10 times, sleeping one second between attempts. It maps the first returned card in the same call rather than handing retrieval to AsyncFetchCode.

!WARNING Do not create a replacement order while the sale is pending. A request timeout can occur after InComm accepts the order, and a replacement can create a second provider purchase unless the existing orderUri is checked first.

Redacted request and response examples

The async request is JSON. Values below are synthetic or redacted; they are not suitable for a live order.

json
{
  "customerorderid": "sale-uuid-example",
  "purchaseordernumber": "sale-uuid-example",
  "metadata": "{\"partner_id\":12345}",
  "recipients": [
    {
      "firstname": "Application",
      "lastname": "Gift Card",
      "emailaddress": "redacted@example.invalid",
      "deliveremail": false,
      "products": [
        {
          "sku": "SKU-EXAMPLE",
          "quantity": 1,
          "value": 25
        }
      ]
    }
  ]
}

For 202 Accepted, the provider response used by the wrapper is represented by its relevant header:

http
HTTP/1.1 202 Accepted
Location: https://provider.example/orders/order-uri-example

The card lookup returns an array. The processor consumes the first item and maps the relevant fields as follows:

json
[
  {
    "CertificateLink": "https://provider.example/cert/redacted",
    "CardNumber": "[REDACTED]",
    "Pin": "[REDACTED]",
    "Auxiliary": "[REDACTED]",
    "ExpirationDate": "2030-12-31T23:59:59Z",
    "CardUri": "card-uri-example",
    "Sku": "SKU-EXAMPLE"
  }
]

CardNumber becomes the application code, Pin becomes the PIN, ExpirationDate is formatted as an ISO-8601 string, and CertificateLink becomes the third-party URL. CardUri is required for balance and void operations. Card numbers, PINs, auxiliary values, and certificate links must be redacted in tickets and examples.

Response mapping and validation

The async create response is considered successful only when the provider wrapper receives 202; the body exposed to the processor contains the extracted orderUri. A 409 Conflict is not treated as a new order: the wrapper extracts the existing order URI from Location into response headers, and the processor records the sale as requested so retrieval can continue.

The retrieval response must be a successful card array with a first card. The processor sets application status to success, then maps cardNumber, pin, expirationDate, and certificateLink. If the brand has use_auxiliary_as_barcode_string and a barcode URL was generated, auxiliary replaces the barcode string and a new barcode URL is generated.

The provider resource also exposes orderStatus, programId, customerOrderId, totalFaceValue, and related order fields, but the async issue path stores the extracted order URI and the first card fields rather than interpreting a separate order-state field. A missing SKU fails before the provider request. An empty or malformed provider response can fail during card selection or mapping and must remain an error, not be presented as a successful card.

Provider outcomes, retries, and duplicate risk

Provider outcomeAsync handlingOperational meaning
202 AcceptedStore orderUri; leave the card requested/pendingThe order was accepted, but card details are obtained separately
409 ConflictRead the existing orderUri from Location; continue to retrievalThe customer order ID already exists; do not create another order
400499, except 409The processor raises an API error instead of returning a retry card; outer job handling leaves the sale retryableCheck SKU, authorization, program access, URI, inventory, and reseller balance
500599Retry the issue job with a five-minute step and a five-hour maximum delay, up to MAX_RETRIESTreat as a provider or gateway failure, while checking whether the original order was accepted
Other issue failureRetry with the processor backoff and a five-minute maximum delay while attempts remainInspect the recorded status and response
Retrieval failureKeep the card pending and retry with retrieval backoff while attempts remainCard details are not yet available or the lookup failed

The async processor sets MAX_RETRIES to 10. Issue attempts and retrieval attempts use separate card metadata counters. The queue job also avoids processing a sale already marked successful. These controls reduce duplicate work, but they cannot prove that a network failure happened before or after provider acceptance; sale UUID, purchaseordernumber, and orderUri are the idempotency investigation keys.

Audit and reconciliation fields

Compare the following fields without copying sensitive card data into a ticket:

Local or audit fieldInComm value to compare
Sale UUIDcustomerorderid; also async purchaseordernumber
Legacy client request IDSync purchaseordernumber
Partner IDJSON metadata.partner_id
Face value and currencyProduct value and the selected currency environment
Brand mappingProduct sku and the matching incomm-sku attribute
Entity/program contextProgramId request header and the resolved currency/entity program ID
Processor referenceorderUri from Location, stored as processor_ref
Card identitycardUri; compare only a masked card number or last four digits if policy permits
Completion dataExpiry, presence of PIN, certificate-link presence, and barcode source

For provider calls that return or throw an InComm response, the async client records each request/response sequence in its API history and labels authentication traffic separately for /auth/token. The sync implementation records only the last request and response for each call. Processor interaction logs and the sale audit record therefore need to be read together, especially after a retry or duplicate response.

Settings and brand mappings

config/incomm.php reads these environment-backed settings:

SettingEnvironment variablePurpose
Application base URLINCOMM_APP_URLBase URI for program and catalogue calls
API base URLINCOMM_API_URLBase URI for order and card calls
Shared client credentialsINCOMM_CLIENT_ID, INCOMM_CLIENT_SECRETClient identity and secret
Reward Cloud program IDsINCOMM_CAD_PROGRAM_ID, INCOMM_USD_PROGRAM_ID, INCOMM_AUD_PROGRAM_ID, INCOMM_NZD_PROGRAM_IDDefault program per currency
Tillo entity overridesINCOMM_*_TILLOINC_PROGRAM_IDtilloinc program per currency
Asset-update notificationSLACK_INCOMM_CARD_IMAGE_UPDATE_WEBHOOKSlack destination for changed card images

The processor first resolves a program for the sale owner’s Tillo entity and currency, then falls back to the Reward Cloud program for that currency when the override is empty. Each brand uses incomm-sku for an open-value product or incomm-sku-<denomination> for a fixed-denomination product. The fixed-denomination key uses the denomination formatted as a float. use_auxiliary_as_barcode_string is optional and affects barcode generation only.

API operations and operational tools

OperationEndpoint or commandUse
AuthenticatePOST /auth/tokenClient-credentials token; form fields include client_id, client_secret, and grant_type
Async orderPOST /ordersCreate the provider order; 202 uses Location
Legacy sync orderPOST /orders/immediateCreate and return an order with card links in the synchronous flow
Async order cardsGET /cards/order/{orderUri}Retrieve cards for async completion and balance lookup
Legacy order cardsGET /orders/{orderUri}/cardsPoll cards in the sync flow and find a card for cancellation
Card balanceGET /cards/{cardUri}/balanceRetrieve current balance
Card voidPOST /Cards/{cardUri}/voidDeactivate a card
ProgramsGET /programs/programsList programs for a currency environment
CataloguesGET /programs/programs/{programId}/catalogsList program catalogues
Catalogue assetsGET /programs/programs/{programId}/catalogs/{catalogId}/assetsRefresh retailer assets
Retailer refreshphp artisan rewardcloud:check-incomm-retailersUpdate redemption instructions, terms, descriptions, and recent card-image attributes for matching SKUs

Investigation checklist

  1. Confirm the issuer: incomm-async for current issuance or incomm-sync for a historical sale.
  2. Record the sale UUID, client request ID, sale status, currency, amount, delivery method, brand slug, and processor_ref.
  3. Confirm the selected SKU and program ID, including the owner’s Tillo entity and the Reward Cloud fallback.
  4. Compare the audited create request with the provider status and Location header. For 409, use the existing order URI rather than a new order.
  5. Follow the order URI through the card lookup and check the first card’s card URI, expiry, PIN presence, certificate-link presence, and barcode source without exposing the raw values.
  6. For balance, verify that the original sale was found by code and that the order lookup returned a card URI before checking /balance.
  7. For cancellation, verify the original processor reference, the cancellation sale’s partner audit context, and the /void response.
  8. Check async authentication, request, response, and exception audit records; for sync calls, check the last request/response pair.
  9. Check retry metadata and whether a timeout could have occurred after provider acceptance.

Limitations and support

The active async issuer does not expose a cashout operation. Balance lookup is provider-card based and requires a code and PIN at the processor interface. The repository’s InComm issuer onboarding migration does not define a support-contact attribute, so no InComm email address is documented here. Use the approved internal processor escalation route and include identifiers, timestamps, status codes, safe field comparisons, and audit evidence; never include credentials, full card numbers, PINs, auxiliary values, or live certificate links.

  • app/Processors/InCommAsyncProcessor.php — active async issue, retrieval, balance, cancellation, mapping, and retry handling.
  • app/Processors/InCommSyncProcessor.php — deprecated synchronous issue, polling, balance, and cancellation behavior.
  • app/Processors/Api/InComm/InComm.php — selects program, order, card, and fulfilment API resources.
  • app/Processors/Api/InComm/Http/Order.php — async and sync order endpoints and Location/Link extraction.
  • app/Processors/Api/InComm/Http/Card.php — card retrieval, balance, and void endpoints.
  • app/Processors/Api/InComm/Http/HttpClient.php — currency environments, token caching, program headers, and API history.
  • config/incomm.php — API URLs, credentials, program IDs, and Slack notification configuration.
  • app/Console/Commands/UpdateInCommRetailersCommand.php — retailer asset and metadata refresh.
  • app/Jobs/AsyncProcessRequest.php and app/Jobs/AsyncFetchCode.php — pending, duplicate, and retrieval queue transitions.
  • tests/Feature/Processors/IncommAsyncProcessorTest.php — async accepted, conflict, authentication, retrieval, barcode, balance, and audit scenarios.
  • database/migrations/2021_11_01_122948_r_c_c-9119-move-incomm-sync-brands-to-async.php — migration of existing brands to the async issuer.