Skip to content
TilloTech Docs

Cadooz Processor and API

This page explains the Cadooz integration from an operations and customer-service perspective: how an order moves through the system, which settings control it, and what evidence is useful when investigating a failed or delayed gift-card order.

What Cadooz does

Cadooz is an asynchronous, SKU-per-denomination gift-card processor. It supplies digital vouchers through the Cadooz Business Order SOAP API. The application does not receive the voucher code in the initial order response; it first receives a Cadooz order number and retrieves the voucher in a later request.

The processor is configured as:

PropertyBehaviour
Processor typeSKU per denomination; a denomination-specific product mapping is required
ProcessingAsynchronous order creation followed by voucher retrieval
DeliveryDOWNLOAD digital voucher; provider e-card link is retained when returned
Balance lookupUnsupported
CancellationUnsupported
Order completion ruleRetrieval response has responseState=SUCCESS and a non-empty voucher code
Initial order statesCREATED or QUEUED

An approved CreateOrder response means that Cadooz accepted or queued the order. It does not mean that the voucher is available or that the card is successful yet.

Order lifecycle

  1. A partner orders a Cadooz-enabled brand and denomination through the normal gift-card API.
  2. The processor formats the requested face value to two decimal places and resolves the brand attribute cadooz-denomination-sku-%.2f. The attribute value is the Cadooz productNumber for that denomination.
  3. The processor builds a SOAP CreateOrder request with the customer profile, product number, face value, currency, one order position, and DOWNLOAD delivery type.
  4. Cadooz returns an orderNumber and an orderState of CREATED or QUEUED. The application stores the order number as the processor reference and keeps the card pending.
  5. The asynchronous processor flow sends getVouchersForOrder using the stored order number and the configured customer profile.
  6. If Cadooz returns responseState=SUCCESS with a non-empty voucher code, the application stores the code and any returned PIN, expiry date, serial number, and e-card link, then marks the card successful.
  7. The provider response and the request/response exchange are available in the processor interaction audit for reconciliation and support investigation.

WAITING, PROCESSING, and INTERNAL_ERROR are treated as retryable retrieval responses. Other unexpected states, missing XML segments, empty order numbers, or empty voucher codes are failures and should be investigated before another order is created.

Example API order flow

The following examples are representative SOAP payloads with illustrative values. Voucher codes, PINs, credentials, and live URLs must be redacted in support evidence.

Create order request

The request is sent as an XML SOAP envelope to the URI configured by CADOOZ_URI:

xml
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="webservices.cadooz.com">
  <soapenv:Header />
  <soapenv:Body>
    <web:CreateOrder>
      <order>
        <customerProfile>Tillo API</customerProfile>
        <deliveryAddress>
          <email>techteam@tillo.io</email>
        </deliveryAddress>
        <orderPositions>
          <amount>1</amount>
          <productNumber>ABC-25-EUR</productNumber>
          <value>
            <amount>25.00</amount>
            <currency>EUR</currency>
          </value>
          <deliveryType>DOWNLOAD</deliveryType>
        </orderPositions>
      </order>
    </web:CreateOrder>
  </soapenv:Body>
</soapenv:Envelope>

The face value is sent even though each denomination has its own product number. The delivery email is the technical integration address in the generated payload, not a partner's customer delivery address; downstream application delivery and presentation determine how the gift card is exposed.

Create order response

An accepted order has the following general shape:

xml
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <ns2:CreateOrderResponse xmlns:ns2="webservices.cadooz.com">
      <return>
        <orderNumber>CAD-123456</orderNumber>
        <orderState>CREATED</orderState>
        <deliveryState>PROCESSING</deliveryState>
        <message>Order was created and will be processed soon.</message>
      </return>
    </ns2:CreateOrderResponse>
  </soap:Body>
</soap:Envelope>

QUEUED is also a valid initial state. Neither state contains the final voucher code, so the orderNumber must be preserved for retrieval. A response with a missing or empty orderNumber or orderState, or an order state other than CREATED or QUEUED, is not accepted by the processor.

Retrieve voucher request

Retrieval uses the Cadooz order number stored as the processor reference:

xml
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="webservices.cadooz.com">
  <soapenv:Header />
  <soapenv:Body>
    <web:getVouchersForOrder>
      <customerProfile>Tillo API</customerProfile>
      <orderNumber>CAD-123456</orderNumber>
    </web:getVouchersForOrder>
  </soapenv:Body>
</soapenv:Envelope>

Retrieve voucher response

When the voucher is ready, Cadooz returns SUCCESS and the voucher fields:

xml
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <ns2:getVouchersForOrderResponse xmlns:ns2="webservices.cadooz.com">
      <return>
        <responseState>SUCCESS</responseState>
        <voucherList>
          <serialNumber>987654321</serialNumber>
          <code>[redacted]</code>
          <pin>[redacted]</pin>
          <value>
            <amount>25.00</amount>
            <currency>EUR</currency>
          </value>
          <productName>Example Gift Card</productName>
          <cadoozProductNumber>ABC-25-EUR</cadoozProductNumber>
          <ecardLink>https://[redacted]/ecard/[redacted]</ecardLink>
          <eVoucherLink xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
          <expirationDate>2027-08-21T00:00:00+00:00</expirationDate>
        </voucherList>
      </return>
    </ns2:getVouchersForOrderResponse>
  </soap:Body>
</soap:Envelope>

If Cadooz returns WAITING or PROCESSING, the voucher is not ready and the asynchronous flow may retry. INTERNAL_ERROR is also retryable in the current processor, even though its name sounds final.

Response mapping and validation

The processor parses the XML after converting the provider response from ISO-8859-1 to UTF-8 and removing the known SOAP/XML namespace prefixes. It validates the expected response structure before changing card state.

Provider field or conditionInternal resultOperational meaning
CreateOrderResponse.return.orderNumberprocessor_referenceCadooz identifier required for subsequent retrieval
orderState = CREATED or QUEUEDPending/requested cardCadooz accepted or queued the order; no voucher is available yet
getVouchersForOrderResponse.return.responseState = SUCCESSEligible for completionVoucher data should be present
voucherList.codeCard codeRequired and must be non-empty for success
voucherList.pinCard PINStored when present
voucherList.expirationDateCard expiration dateParsed and stored when present
voucherList.serialNumberCard serial numberStored when present
voucherList.ecardLinkThird-party URLStored as the provider e-card link when present
voucherList.eVoucherLinkNo direct card mappingRetained only in the raw provider response/audit if returned
voucherList.value, currency, and product metadataNo direct completion ruleUseful for reconciliation against the sale and SKU

The application also sets the internal card URL from the sale's existing saleUrl; this is distinct from the provider's ecardLink.

The following conditions are validation failures:

  • The response is not valid XML.
  • The SOAP Body, operation response, or return segment is missing.
  • A create response is missing orderNumber or orderState, or either value is empty.
  • A create response has an order state other than CREATED or QUEUED.
  • A retrieve response is missing responseState, or the value is empty or not recognised.
  • A successful retrieve response is missing voucherList or voucherList.code, or the code is empty.

Optional fields such as PIN, expiration date, serial number, and e-card link do not independently determine success.

Provider states and retry behaviour

The current processor distinguishes an accepted create request from a voucher-ready retrieval response:

OperationProvider stateProcessor behaviourOperational action
CreateCREATED, QUEUEDAccepted; card remains pendingPreserve orderNumber and retrieve it later
CreatePROCESSING, DELIVERED, INVOICED, DONENot a valid initial responseReconcile the order with Cadooz before retrying
CreateCANCELED, RETURNED, INTERNAL_ERROR, ACCESS_DENIED, PRODUCT_NOT_AVAILABLE, UNKNOWN, VERIFICATION_FAILED, ALREADY_PROCESSEDNon-retryable processor failureInspect the response message and configuration; do not create a duplicate blindly
RetrieveWAITING, PROCESSING, INTERNAL_ERRORRetryable processor failureAllow the asynchronous retry flow to continue
RetrieveSUCCESS with a non-empty codeSuccessful card completionStore the voucher data
RetrieveINCORRECT_USAGE, UNKNOWN_CUSTOMER_PROFILE, UNKNOWN_GENERAION_PROFILE, ORDER_NOT_FOUND, CANCELEDNon-retryable processor failureCheck request values, customer profile, and existing order

Any state not accepted by the current implementation is an error, including an empty or unknown state. Cadooz's published spelling UNKNOWN_GENERAION_PROFILE is retained here for matching provider responses.

Transport errors, SOAP faults, malformed XML, and response validation errors are wrapped as processor exceptions and recorded in the interaction audit. Whether a transport failure is retried depends on the surrounding processor retry policy; a provider order must not be recreated until the existing create attempt has been reconciled.

Audit comparison fields

Compare the create and retrieval interaction audits as one sequence. The processor enables interaction auditing with the internal sale UUID as the transaction reference. On retrieval, it updates the gift-card audit request value with the latest retrieval payload so the audit reflects the request actually sent to Cadooz.

FieldCreate orderRetrieve voucherWhat to verify
OperationCreateOrdergetVouchersForOrderA new sale starts with create; retrieval reuses the existing Cadooz order
EndpointConfigured CADOOZ_URISame configured URIThe request was sent to the expected environment
Request/response timestampsAudit request and response timesAudit request and response timesThe response follows its matching request and the sequence is chronological
Internal transaction referenceSale UUID used for auditingSale UUID used for auditingBoth audits belong to the same sale/workflow
Customer profilecustomerProfilecustomerProfileThe same configured profile is used
Product mappingproductNumberNot sentThe product number matches the brand and face value
Amount/currencyvalue.amount and value.currencyNot sentThe requested amount and currency match the sale
Provider referenceorderNumber in responseorderNumber in requestRetrieval uses the original order, not a newly created order
Provider stateorderStateresponseStateCreation acceptance and voucher readiness are separate states
Voucher dataNot expectedvoucherListA non-empty code is present before completion

A redacted comparison record can be represented as follows:

json
{
  "create": {
    "operation": "CreateOrder",
    "requestTimestamp": "2026-08-21T16:03:04Z",
    "responseTimestamp": "2026-08-21T16:03:05Z",
    "saleId": "sale-123e4567-e89b-12d3-a456-426614174000",
    "transactionReference": "sale-123e4567-e89b-12d3-a456-426614174000",
    "customerProfile": "Tillo API",
    "productNumber": "ABC-25-EUR",
    "amount": "25.00",
    "currency": "EUR",
    "orderNumber": "CAD-123456",
    "orderState": "CREATED",
    "voucherDataPresent": false
  },
  "retrieve": {
    "operation": "getVouchersForOrder",
    "requestTimestamp": "2026-08-21T16:05:04Z",
    "responseTimestamp": "2026-08-21T16:05:05Z",
    "saleId": "sale-123e4567-e89b-12d3-a456-426614174000",
    "transactionReference": "sale-123e4567-e89b-12d3-a456-426614174000",
    "customerProfile": "Tillo API",
    "orderNumber": "CAD-123456",
    "responseState": "SUCCESS",
    "voucherDataPresent": true
  }
}

Settings

Processor settings

The processor-level settings are environment-backed values in config/cadooz.php:

SettingEnvironment variablePurpose
Customer profileCADOOZ_CUSTOMER_PROFILE_NAMECadooz profile included in create and retrieval requests
API URICADOOZ_URISOAP endpoint used for all Cadooz calls
Namespace hostCADOOZ_NAMESPACE_HOSTXML namespace used in generated SOAP payloads
TimeoutCADOOZ_TIMEOUTHTTP client timeout
UsernameCADOOZ_USERNAMEHTTP Basic Authentication username
PasswordCADOOZ_PASSWORDHTTP Basic Authentication password

The HTTP client sends the username and password as Basic Authentication. Verify the endpoint, namespace, customer profile, and credentials as a consistent environment-specific set. Do not enter processor credentials as brand settings or expose them in support responses.

Brand settings

Each Cadooz-enabled brand must have a product-number attribute for every denomination that can be ordered. The attribute name is generated using the Cadooz format:

text
cadooz-denomination-sku-%.2f

For example, a 25 face-value request resolves cadooz-denomination-sku-25.00; its stored value must be the matching Cadooz productNumber. The face value is also sent in the SOAP value.amount field and is rounded/formatted to two decimal places.

If the attribute is absent, the denomination format is wrong, or the value belongs to another product or market, the order can fail even when the processor credentials are valid. Confirm the brand, denomination, currency, and Cadooz product number together before enabling sales.

Catalog operations

The application exposes these Cadooz SOAP operations:

OperationUseRequest data
CreateOrderStart a voucher orderCustomer profile, product number, amount, currency, and download delivery
getVouchersForOrderRetrieve the voucher for an existing orderCustomer profile and Cadooz order number
getAvailableCatalogsRetrieve catalog dataNamespace host; the application requests extra content
getAvailableProductsRetrieve products for a customer profileNamespace host and customer profile

For local catalog inspection, run:

shell
php artisan catalog:generate-cadooz-catalog-csv

The command is intentionally restricted to local environments. It calls getAvailableCatalogs with includeExtraContent=true and writes a timestamped CSV to local storage. The export includes product references, denomination-to-variation mappings, categories, English and German descriptions/instructions, redemption methods, expiry, quantity limits, and logo/voucher/redemption URLs. It is a catalog inspection tool, not a per-sale retry mechanism.

Customer-service investigation

Collect the following before re-ordering or escalating:

  1. Internal sale UUID and transaction reference.
  2. Brand slug, requested face value, currency, delivery method, and sale status.
  3. The resolved cadooz-denomination-sku-%.2f attribute name and redacted product number.
  4. The processor reference, which should be the Cadooz orderNumber after creation.
  5. Create and retrieval audit records, including request/response timestamps, SOAP operation, endpoint, redacted payloads, HTTP result or mapped exception, and provider state/message.
  6. The configured customer profile and environment/credential status, without exposing credentials.
  7. Returned voucher-field presence, especially whether responseState=SUCCESS included a non-empty code.

Use the first provider operation to classify the issue:

  • If CreateOrder returned an orderNumber with CREATED or QUEUED, treat the order as accepted/pending and retrieve that order; do not create another order.
  • If retrieval returned WAITING, PROCESSING, or INTERNAL_ERROR, the order may still complete through the asynchronous retry flow.
  • If retrieval returned SUCCESS but no non-empty code, treat it as a response-validation or provider-completion issue and reconcile with Cadooz before repeating.
  • If creation returned ALREADY_PROCESSED, first locate the existing order associated with the request; this state is not permission to submit a second purchase.
  • If creation returned PRODUCT_NOT_AVAILABLE, compare the product number, denomination, currency, customer profile, and catalog record.
  • If creation returned ACCESS_DENIED or retrieval returned UNKNOWN_GENERAION_PROFILE, verify the environment credentials and customer profile with Cadooz.
  • If only a retrieval audit exists, verify that a preceding create audit exists and that the order number came from that create response.
  • If no provider audit exists, investigate processor selection, brand SKU resolution, configuration loading, and request dispatch before contacting Cadooz.

Do not manually retry by creating a new Cadooz order until the existing create attempt has been reconciled. A second CreateOrder call can create a duplicate purchase; retrieval should continue using the existing processor reference.

Limitations and escalation evidence

Cadooz balance and cancellation transactions are not implemented by this processor. A request for either operation must follow the applicable refund, cancellation, or balance-verification procedure rather than being sent through a Cadooz processor transaction.

Escalations should include the internal sale identifier, Cadooz order number if available, customer profile, timestamps, SOAP operation, endpoint, provider state/message, and redacted audit evidence. Never include Basic Authentication credentials, unredacted voucher codes, or PINs in a ticket.

  • app/Processors/Cadooz/CadoozProcessor.php — order and voucher lifecycle, state validation, response parsing, and card mapping.
  • app/Http/Clients/Cadooz/CadoozApi.php — authenticated SOAP transport and Cadooz operations.
  • app/Http/Clients/Cadooz/RawCadoozResponseData.php — encoding conversion and XML parsing.
  • app/Http/Clients/Cadooz/Requests/CreateOrderRequestData.php — create-order SOAP payload and amount formatting.
  • app/Http/Clients/Cadooz/Requests/GetVouchersForOrderRequestData.php — voucher-retrieval SOAP payload.
  • app/Http/Clients/Cadooz/Requests/GetAvailableCatalogsRequestData.php — catalog SOAP payload.
  • app/Http/Clients/Cadooz/Requests/GetAvailableProductsRequestData.php — product SOAP payload.
  • config/cadooz.php — processor environment settings.
  • app/Console/Commands/GenerateCadoozCatalogCsv.php — local catalog export.
  • openapi/cadooz-business-order-v1.6.yaml — provider API contract included in the repository.
  • tests/Feature/Processors/Cadooz/CadoozProcessorTest.php — lifecycle, state, validation, and audit scenarios.
  • tests/Unit/App/Http/Clients/Cadooz/Requests/ — SOAP request payload tests.