Vouchers Depot processor reference
This guide describes the implemented Vouchers Depot integration, its request and response contract, and the evidence needed to investigate an issuance or catalogue problem. Examples show the structure used by the application and contain placeholders instead of credentials, voucher links, or live card data.
Processing model
Vouchers Depot is a synchronous digital-voucher processor. Issuance has two provider calls: the application creates an order, then requests the voucher details. The sale is not mapped to a completed card until the details response passes validation.
| Property | Implemented behaviour |
|---|---|
| Issuer | Vouchers Depot |
| Processor type | SKU per product for open-value brands, or SKU per denomination for fixed-value brands |
| Issuance | Synchronous create-order followed by create-order-details-vouchers |
| Delivery data | A voucher URL and expiry date |
| Balance and cancellation | No implementation in the processor interaction |
| Provider reference | order_id from the details response |
Issuance lifecycle
- The issue request supplies a transaction reference, face value, and currency.
- The interaction selects the brand SKU. Open-value brands use
vouchers-depot-sku; fixed-value brands usevouchers-depot-sku-{amount}such asvouchers-depot-sku-100.00. - The client obtains or reuses an access token for the request currency.
- The client posts the transaction reference to
api/v2/create-order. - The client posts the same reference, the selected product ID, and quantity
1toapi/v2/create-order-details-vouchers. - The details response is decoded and validated. The resulting card contains the response
order_id, voucherlink, and ISO-8601expiration_date. - A failure in either call is returned as an external processor error; a successful order-creation response alone does not complete issuance.
Authentication and HTTP operations
The base URI comes from VOUCHERS_DEPOT_BASE_URI. Requests use JSON headers and a bearer token. The token request uses the credentials configured for the request currency and posts to api/v2/generate-access-token:
{
"grant_type": "password",
"username": "<redacted>",
"client_id": "<redacted>",
"client_secret": "<redacted>",
"client_password": "<redacted>"
}
The client accepts an access_token from a successful token response and caches it under a currency-specific key for 3000 seconds. The provider token lifetime is documented in the client as 3600 seconds. A token-generation response with status: "error", or without a token, is rejected.
Create order
POST api/v2/create-order sends the transaction reference. The remaining fields are sent as the literal value NA because the request model has no corresponding customer address data:
{
"order_number": "<transaction-reference>",
"contact_person": "NA",
"address": "NA",
"client_email": "NA",
"city": "NA",
"country": "NA",
"county": "NA",
"phone": "NA",
"company": "NA",
"vat_tax_no": "NA"
}
The create-order body is not used to produce the card. The interaction only proceeds when the HTTP request succeeds; the details call supplies the fields that are mapped to the card.
Create order details voucher
POST api/v2/create-order-details-vouchers sends:
{
"order_number": "<transaction-reference>",
"product_id": "<redacted-sku>",
"quantity": "1"
}
A successful response has this relevant shape. The URL, order ID, and date below are placeholders:
{
"vouchers": [
{
"link": "<redacted-voucher-url>",
"expiration_date": {
"date": "<provider-date>",
"timezone": "<provider-timezone>"
}
}
],
"order_id": "<provider-order-id>"
}
Generate feed and catalogue tools
POST api/v2/generate-feed uses query parameters rather than a JSON body:
| Parameter | Meaning |
|---|---|
limit | Number of products requested |
skip | Product offset; page n uses (n - 1) * limit |
lang | Catalogue language; the request model defaults to en |
VouchersDepotCatalogueCollector first requests one product per configured currency to read total_products. It then queues page collectors with a limit of 100. Each page retries up to three attempts with a one-second delay, rejects invalid JSON or a response without products, stores valid pages in cache, and combines them into vouchers-depot-catalogue. Missing pages are logged when the batch is combined.
Configuration and brand mappings
config/vouchers-depot.php defines the following environment-backed values:
| Configuration area | Values |
|---|---|
| Global | base_uri, timeout, and legacy/global username and client fields |
| Currency accounts | BGN, CZK, EUR, HUF, MDL, PLN, RON, and USD; each has username, client ID, client secret, and client password |
| Brand attribute | vouchers-depot-sku for an open-value product, or vouchers-depot-sku-{amount} for a fixed denomination |
The access-token code reads credentials from vouchers-depot.currencies.{currency}. Missing currency credentials therefore fail before the order call. The brand SKU is passed as product_id; a missing mapping is an application configuration problem, not a provider response state.
Response mapping and validation
The raw client response is retained as a string. The interaction then requires all of the following:
| Path | Rule | Card mapping |
|---|---|---|
vouchers | Required array with exactly one item | The only voucher is selected |
vouchers.0.link | Required | url |
vouchers.0.expiration_date | Required array | The date input |
vouchers.0.expiration_date.date | Required | Parsed with the provider timezone |
vouchers.0.expiration_date.timezone | Required | Used by CarbonImmutable |
order_id | Required | processor_reference |
Invalid JSON, missing fields, a voucher count other than one, or an unparseable date raises ResponseValidationException. The provider status field is not used by the interaction's success validation. The client does reject JSON error responses before mapping when they contain status: "error" or a recognised status_code error.
Provider error states and retry risks
The client documents inconsistent provider error bodies, including status: "error", status_code, message, and errors. The implemented mapping is:
| Provider signal | Application result |
|---|---|
Token body has status: "error" | AuthFailureException |
Call body has status: "error" | AuthFailureException |
status_code 0100 or 0152 with errors | MalformedRequestException; the client comments identify order or order-item duplication |
status_code 0150 or 0151 with errors | ResourceNotFoundException; the client comments identify product or order not found |
| Other error-code body | UnexpectedServerSideException |
| Invalid JSON | UnexpectedServerSideException |
| HTTP transport error | Mapped through the shared Guzzle exception handler |
The issuance interaction has no retry loop. A timeout after create-order may leave a provider order whose outcome is unknown; repeating the complete flow can produce a duplicate order or a duplicate order item. The duplicate message is provider evidence, but the repository does not define a reconciliation operation. Do not blindly retry an uncertain issuance: retain the original transaction reference, inspect both audit calls, and ask the internal processor owner or Vouchers Depot account team to reconcile the provider order.
Catalogue collection is different: its page jobs intentionally retry up to three times. That retry policy must not be applied to the two issuance calls without first establishing the outcome of the original order.
Audit comparison fields
Issuance enables request and response middleware on the client using the transaction reference. For each provider request that receives a response, compare the processor interaction audit with the internal sale record using:
| Evidence | Fields to compare |
|---|---|
| Internal sale | Sale UUID, transaction reference, requested currency, face value, brand, and delivery method |
| Token request | Currency selected and the configured account; never copy credentials into a ticket |
| Create-order request | Endpoint, order_number, and the request timestamp |
| Details request | Endpoint, order_number, product_id, and quantity |
| Details response | order_id, one voucher entry, link, and expiration date/timezone |
| Error response | HTTP status if present, status, status_code, message, and errors |
Audit content may contain sensitive provider data. Share only redacted excerpts; do not paste bearer tokens, voucher URLs, voucher tokens, or live card data into support channels.
Investigation checklist
- Confirm the internal sale UUID and transaction reference.
- Confirm the requested currency is one of the configured currency accounts.
- Confirm the brand is using the expected open-value or fixed-denomination SKU attribute.
- Check the audit for token generation, create-order, and order-details calls in timestamp order.
- If create-order succeeded but details did not, treat the provider order as potentially created and do not submit a new transaction without reconciliation.
- Compare
order_numberacross both requests and compare the returnedorder_idand voucher fields with the internal sale. - Classify the response: authentication, duplicate/malformed request, missing resource, invalid JSON, validation failure, or transport failure.
- For a catalogue issue, check the currency, page offset,
total_products, page cache key, missing-page warning, and the finalvouchers-depot-cataloguecache entry. - Escalate with the sale UUID, transaction reference, currency, provider reference if known, UTC timestamps, error code, and redacted audit excerpts.
Limitations and support contacts
The implemented interaction supports issuance only. Balance lookup and cancellation are not implemented, and the repository contains no named Vouchers Depot support contact or provider escalation address. Use the internal processor owner or the Vouchers Depot account team recorded by the organisation; include the redacted evidence listed in the investigation checklist.
Related code
app/Processors/VouchersDepot/VouchersDepotProcessor.php— synchronous processor wrapper and endpoint configuration.app/Processors/Interaction/Integrations/VouchersDepot/VouchersDepotProcessorInteraction.php— two-call issuance flow and response mapping.app/Http/Clients/VouchersDepot/VouchersDepotApi.php— authentication, caching, endpoints, and provider error mapping.app/Http/Clients/VouchersDepot/Requests/— token, order, details, and feed request models.app/CatalogueService/Jobs/VouchersDepot/— queued catalogue pagination and cache assembly.config/vouchers-depot.php— environment-backed global and currency settings.app/ProcessorInteractionAuditLog.php— processor request and response audit record.tests/Unit/Processors/Interaction/Integrations/VouchersDepot/VouchersDepotProcessorInteractionTest.php— SKU selection, mapping, and validation cases.tests/Unit/App/Http/Clients/VouchersDepot/VouchersDepotApiTest.php— authentication, token expiry, error, and transport cases.