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:
| Property | Behaviour |
|---|---|
| Processor type | SKU per denomination; a denomination-specific product mapping is required |
| Processing | Asynchronous order creation followed by voucher retrieval |
| Delivery | DOWNLOAD digital voucher; provider e-card link is retained when returned |
| Balance lookup | Unsupported |
| Cancellation | Unsupported |
| Order completion rule | Retrieval response has responseState=SUCCESS and a non-empty voucher code |
| Initial order states | CREATED 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
- A partner orders a Cadooz-enabled brand and denomination through the normal gift-card API.
- 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 CadoozproductNumberfor that denomination. - The processor builds a SOAP
CreateOrderrequest with the customer profile, product number, face value, currency, one order position, andDOWNLOADdelivery type. - Cadooz returns an
orderNumberand anorderStateofCREATEDorQUEUED. The application stores the order number as the processor reference and keeps the card pending. - The asynchronous processor flow sends
getVouchersForOrderusing the stored order number and the configured customer profile. - If Cadooz returns
responseState=SUCCESSwith a non-empty vouchercode, the application stores the code and any returned PIN, expiry date, serial number, and e-card link, then marks the card successful. - 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:
<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:
<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:
<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:
<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 condition | Internal result | Operational meaning |
|---|---|---|
CreateOrderResponse.return.orderNumber | processor_reference | Cadooz identifier required for subsequent retrieval |
orderState = CREATED or QUEUED | Pending/requested card | Cadooz accepted or queued the order; no voucher is available yet |
getVouchersForOrderResponse.return.responseState = SUCCESS | Eligible for completion | Voucher data should be present |
voucherList.code | Card code | Required and must be non-empty for success |
voucherList.pin | Card PIN | Stored when present |
voucherList.expirationDate | Card expiration date | Parsed and stored when present |
voucherList.serialNumber | Card serial number | Stored when present |
voucherList.ecardLink | Third-party URL | Stored as the provider e-card link when present |
voucherList.eVoucherLink | No direct card mapping | Retained only in the raw provider response/audit if returned |
voucherList.value, currency, and product metadata | No direct completion rule | Useful 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, orreturnsegment is missing. - A create response is missing
orderNumberororderState, or either value is empty. - A create response has an order state other than
CREATEDorQUEUED. - A retrieve response is missing
responseState, or the value is empty or not recognised. - A successful retrieve response is missing
voucherListorvoucherList.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:
| Operation | Provider state | Processor behaviour | Operational action |
|---|---|---|---|
| Create | CREATED, QUEUED | Accepted; card remains pending | Preserve orderNumber and retrieve it later |
| Create | PROCESSING, DELIVERED, INVOICED, DONE | Not a valid initial response | Reconcile the order with Cadooz before retrying |
| Create | CANCELED, RETURNED, INTERNAL_ERROR, ACCESS_DENIED, PRODUCT_NOT_AVAILABLE, UNKNOWN, VERIFICATION_FAILED, ALREADY_PROCESSED | Non-retryable processor failure | Inspect the response message and configuration; do not create a duplicate blindly |
| Retrieve | WAITING, PROCESSING, INTERNAL_ERROR | Retryable processor failure | Allow the asynchronous retry flow to continue |
| Retrieve | SUCCESS with a non-empty code | Successful card completion | Store the voucher data |
| Retrieve | INCORRECT_USAGE, UNKNOWN_CUSTOMER_PROFILE, UNKNOWN_GENERAION_PROFILE, ORDER_NOT_FOUND, CANCELED | Non-retryable processor failure | Check 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.
| Field | Create order | Retrieve voucher | What to verify |
|---|---|---|---|
| Operation | CreateOrder | getVouchersForOrder | A new sale starts with create; retrieval reuses the existing Cadooz order |
| Endpoint | Configured CADOOZ_URI | Same configured URI | The request was sent to the expected environment |
| Request/response timestamps | Audit request and response times | Audit request and response times | The response follows its matching request and the sequence is chronological |
| Internal transaction reference | Sale UUID used for auditing | Sale UUID used for auditing | Both audits belong to the same sale/workflow |
| Customer profile | customerProfile | customerProfile | The same configured profile is used |
| Product mapping | productNumber | Not sent | The product number matches the brand and face value |
| Amount/currency | value.amount and value.currency | Not sent | The requested amount and currency match the sale |
| Provider reference | orderNumber in response | orderNumber in request | Retrieval uses the original order, not a newly created order |
| Provider state | orderState | responseState | Creation acceptance and voucher readiness are separate states |
| Voucher data | Not expected | voucherList | A non-empty code is present before completion |
A redacted comparison record can be represented as follows:
{
"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:
| Setting | Environment variable | Purpose |
|---|---|---|
| Customer profile | CADOOZ_CUSTOMER_PROFILE_NAME | Cadooz profile included in create and retrieval requests |
| API URI | CADOOZ_URI | SOAP endpoint used for all Cadooz calls |
| Namespace host | CADOOZ_NAMESPACE_HOST | XML namespace used in generated SOAP payloads |
| Timeout | CADOOZ_TIMEOUT | HTTP client timeout |
| Username | CADOOZ_USERNAME | HTTP Basic Authentication username |
| Password | CADOOZ_PASSWORD | HTTP 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:
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:
| Operation | Use | Request data |
|---|---|---|
CreateOrder | Start a voucher order | Customer profile, product number, amount, currency, and download delivery |
getVouchersForOrder | Retrieve the voucher for an existing order | Customer profile and Cadooz order number |
getAvailableCatalogs | Retrieve catalog data | Namespace host; the application requests extra content |
getAvailableProducts | Retrieve products for a customer profile | Namespace host and customer profile |
For local catalog inspection, run:
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:
- Internal sale UUID and transaction reference.
- Brand slug, requested face value, currency, delivery method, and sale status.
- The resolved
cadooz-denomination-sku-%.2fattribute name and redacted product number. - The processor reference, which should be the Cadooz
orderNumberafter creation. - Create and retrieval audit records, including request/response timestamps, SOAP operation, endpoint, redacted payloads, HTTP result or mapped exception, and provider state/message.
- The configured customer profile and environment/credential status, without exposing credentials.
- Returned voucher-field presence, especially whether
responseState=SUCCESSincluded a non-emptycode.
Use the first provider operation to classify the issue:
- If
CreateOrderreturned anorderNumberwithCREATEDorQUEUED, treat the order as accepted/pending and retrieve that order; do not create another order. - If retrieval returned
WAITING,PROCESSING, orINTERNAL_ERROR, the order may still complete through the asynchronous retry flow. - If retrieval returned
SUCCESSbut 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_DENIEDor retrieval returnedUNKNOWN_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.
Related code
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.