Choice Digital Processor and API
This page explains the Choice Digital integration from an operations and customer-service perspective: how an order moves through the system, which settings control the request shape, and what evidence is useful when investigating a failed or delayed gift-card order.
What Choice Digital does
Choice Digital is a digital card processor with catalogue support. The current application behaviour is synchronous: the processor calls the realtime order endpoint and expects the order to be processed and an activation URL to be returned in the same response.
The processor is configured as:
| Property | Behaviour |
|---|---|
| Processor type | SKU per product |
| Processing | Synchronous |
| Delivery | Digital voucher/code |
| Balance lookup | Unsupported |
| Cancellation | Unsupported |
| Issue completion rule | response_data.order_status=processed, a ready-for-activation card, and a valid activation URL |
Order lifecycle
- A partner orders a Choice Digital brand through the normal gift-card API.
- The application reads the Choice Digital product reference and the partner’s funding-source identifier configured for the brand/partner relationship.
- Request middleware validates the customer fields required by the selected Choice Digital mode. The processor then builds a realtime order request with the product identifier, amount, and internal transaction reference.
- The client obtains and caches an OAuth bearer token, then sends
POST /orders-realtimewith thex-idempotency-keyandx-tenant-idheaders. - The response is validated. The provider
order_idbecomes the processor reference and the provider activation URL becomes the card URL.
If the realtime response is missing a required field, has an unexpected status, fails authentication, or cannot be sent, the issue fails with an external or response-validation error and should be investigated using the processor interaction audit records.
!IMPORTANT Choice Digital uses an idempotency key based on the internal external-card identifier. This helps prevent accidental duplicate orders when the same request is retried.
Settings
Processor settings
The processor-level settings are environment-backed values in config/choice-digital.php:
| Setting | Environment variable | Purpose |
|---|---|---|
| API base URI | CHOICE_DIGITAL_BASE_URI | Base URL for Choice Digital API requests |
| Authentication URI | CHOICE_DIGITAL_AUTH_URI | OAuth token endpoint |
| Client ID | CHOICE_DIGITAL_CLIENT_ID | OAuth client identifier |
| Client secret | CHOICE_DIGITAL_CLIENT_SECRET | OAuth client secret |
| Audience | CHOICE_DIGITAL_AUDIENCE | OAuth audience value |
| Tenant ID | CHOICE_DIGITAL_TENANT_ID | Default tenant header |
| Timeout | CHOICE_DIGITAL_TIMEOUT | HTTP client timeout |
| Personalisation default | CHOICE_DIGITAL_IS_PERSONALISATION_REQUIRED | Optional default controlling whether recipient name and email are sent |
| Fulfillment parameters default | CHOICE_DIGITAL_IS_FULFILMENT_PARAMETERS_REQUIRED | Optional default controlling whether name, email, address, phone number, and state details are sent |
The API client caches the access token and attaches both the bearer token and tenant ID to provider requests. These values should stay in processor configuration rather than support notes.
Brand settings
Each Choice Digital-enabled brand must provide the product identifier expected by the realtime order endpoint. The processor type is SKU_PER_PRODUCT, so the same configured product value is reused rather than looking up a separate SKU per denomination.
The processor supports two mutually exclusive customer-information modes. Configure only one for a Choice Digital brand; is_fulfilment_parameters_required includes the recipient name and email checks as well as the physical-address checks.
| Setting | Request validation | Choice Digital payload | Operational use |
|---|---|---|---|
is_personalisation_required | Requires fulfilment_parameters.to_first_name, fulfilment_parameters.to_last_name, and a valid fulfilment_parameters.to_email. | Sends card.customer_info.entity_type=individual, first_name, last_name, and email_address; no address fields are added. | Use when the order needs recipient personalisation but not a physical address. |
is_fulfilment_parameters_required | For Choice Digital, requires to_first_name, to_last_name, to_email, address_1, city, postal_code, and country; address_2, phone, and state are optional. country must be US or us, and the postal code must match the supported four-digit, five-digit, ZIP+4, or ABC-123 formats. | Sends the recipient name/email and the supplied fulfilment details under card.customer_info; the provider field names are address1, address2, city, postal_code, country, phone, and state. | Use for brands whose fulfilment requires physical customer details. |
Both settings are resolved by Brand: a non-empty brand attribute overrides the corresponding processor-level environment default. Do not enable both, Personalisation is a subset, so either disable both or enable one. The middleware evaluates isPersonalisationRequired() first and returns after those checks.
The application method is named isFulfillmentParametersRequired(), and configuration and brand attribute use is_fulfilment_parameters_required.
Brands can override the tenant header with a tenant_id attribute; otherwise the processor uses the default tenant configured in config/choice-digital.php. The funding source comes from the partner-brand identifier rather than a standalone brand attribute. The funding_source_id must be present for the Buyer/brand relationship and is entered through the Management Hub approval configuration.
If the brand is mapped to the wrong Choice Digital product, the provider may reject the order or return voucher data for the wrong product.
!IMPORTANT Choice Digital exposes a funding-sources operation that can be used operationally to monitor a Buyer’s
funding_source_idand approval status. It is not currently integrated into this processor; confirm the configured funding source and approval status through the approved onboarding process.
API operations
The application sends JSON REST requests to Choice Digital. The client exposes three operations:
| Operation | Use | Required data |
|---|---|---|
POST /oauth/token | Retrieve an access token | Client ID, client secret, audience |
POST /orders-realtime | Create a realtime order | Product identifier, amount, external card ID, tenant ID |
GET /card-products | Retrieve catalogue data | Bearer token, tenant ID, pagination |
The realtime order request uses the internal external-card ID as the x-idempotency-key, which makes that value especially important when investigating duplicate-order concerns. When personalisation or fulfilment parameters are enabled for a brand, the corresponding customer details are included under card.customer_info.
Response mapping and validation
The interaction accepts an issue only when all of these values are present and valid:
| Provider field | Required value | Application result |
|---|---|---|
response_data.order_id | Non-empty string | Stored as processor_reference. |
response_data.order_status | processed | Confirms the realtime order completed. Other values fail response validation; there is no separate polling flow in this integration. |
response_data.card.card_id | Non-empty string | Confirms provider card data is present. |
response_data.card.external_card_id | Non-empty string | Confirms the provider response contains the external transaction identifier. |
response_data.card.card_status | ready_for_activation | Confirms the card can be activated. |
response_data.card.activation_url | Valid URL | Stored as the returned card URL. |
The provider request uses funding_source_id, send_email, card.card_product_id, card.amount, and card.external_card_id. card.customer_info is omitted for an anonymous order. When present, it contains entity_type=individual, recipient name/email, and any non-null address, phone, or state fields; the country is uppercased before serialization.
Recent processor changes
The current branch extends Choice Digital ordering in these ways:
- Added optional address fields to the issue request data and forwarded them from
fulfilment_parametersthrough the synchronous processor interaction. - Added optional
phoneandstatefields to the issue request data and forwarded them fromfulfilment_parametersinto Choice Digitalcard.customer_info. - Added the
isFulfillmentParametersRequired()brand helper, theis_fulfilment_parameters_requiredprocessor default, and the corresponding Choice Digital issuer metadata so the setting can be configured at processor or brand level. - Made
card.customer_infooptional for anonymous orders and changed disabled address fields tonull, so they are not serialized into the provider payload. - Added Choice Digital-specific validation for physical fulfilment: recipient name/email, address line 1, city, postal code, and US country; address line 2, phone number, and state remain optional.
- Corrected the previous
isFulfillmentParametersRequired()spelling and added tests for request payloads, address handling, response validation, and the new middleware rules.
Customer-service investigation
When an order fails, check these values in order:
- The requested brand, currency, and face value.
- The brand's Choice Digital product sku.
- The brand's
is_personalisation_requiredandis_fulfilment_parameters_requiredattributes, plus the processor-level defaults when no brand override is set. - Whether the request supplied the required recipient and address fields, plus any optional phone number or state, for the enabled settings.
- The sale's processor reference or external card identifier used for idempotency.
- The processor interaction audit request and response, including the
card.customer_infofields sent to Choice Digital. - Whether the OAuth token call and tenant header configuration succeeded.
- Whether the realtime order response returned the expected voucher data.
Do not manually place a replacement order until the original idempotency key and provider response have been reviewed. Reusing or changing the key incorrectly can hide whether the original purchase already succeeded.
Limitations and support contacts
Choice Digital balance checks and cancellations are not implemented by this processor. Requests involving either operation must be handled through the applicable refund, cancellation, or balance-verification procedure rather than through a Choice Digital transaction.
When escalating to the provider, include the internal sale identifier, idempotency key or processor reference, timestamps, and the relevant audit evidence. Do not include stored voucher codes or credentials unless the approved support process requires them.
Related code
app/Processors/ChoiceDigital/ChoiceDigitalProcessor.php— realtime order flow and card mapping.app/Processors/Interaction/Integrations/ChoiceDigital/ChoiceDigitalProcessorInteraction.php— request construction and response validation.app/Processors/Interaction/Issue/IssueRequestData.php— recipient and optional address fields passed into issue interactions.app/Http/Middleware/V2/API/ValidateFulfilmentParametersAndPersonalisationMiddleware.php— API validation for the selected customer-information mode.app/Brand.php— processor-default and brand-attribute resolution for isPersonalisationRequired and isFulfillmentParametersRequired flags.app/Http/Clients/ChoiceDigital/ChoiceDigitalApi.php— OAuth, authenticated requests, and catalogue operations.app/Http/Clients/ChoiceDigital/Requests/— auth, realtime order, and catalogue request payloads.app/CatalogueService/Jobs/ChoiceDigital/ChoiceDigitalCatalogueCollector.php— catalogue import logic.config/choice-digital.php— processor environment settings.tests/Unit/App/Http/Clients/ChoiceDigital/ChoiceDigitalApiTest.php— request payload and API transport coverage.tests/Unit/Middleware/ValidateFulfilmentParametersAndPersonalisationMiddlewareTest.php— Choice Digital fulfilment validation coverage.tests/Unit/Processors/Interaction/Integrations/ChoiceDigital/ChoiceDigitalProcessorInteractionTest.php— order lifecycle and failure scenarios.