ePay Processor and API
This page describes the ePay integration for operations and customer-service teams. It covers synchronous voucher issuance, manual and automatic cancellation, host and SKU selection, response validation, and the audit fields needed to investigate an order.
What ePay does
ePay is a synchronous digital voucher processor. The application sends one JSON request to a configured ePay host, maps the response into a card, and then creates the application delivery URL. The provider response calls the voucher code PINCREDENTIALS.PIN; this value is stored as the card code, while the application card PIN is empty.
| Property | Behaviour |
|---|---|
| Processor type | SKU per denomination or SKU per product, depending on brand configuration |
| Processing | Synchronous request and response |
| Delivery | Digital voucher code with an application-generated delivery URL |
| Balance lookup | Unsupported by the ePay processor; the shared synchronous default rejects it |
| Cancellation | Supported through manual CANCEL requests and automatic cancellation after a create-call failure |
| Issue success rule | Response has a successful RESULT value and PINCREDENTIALS |
| Provider reference | HOSTTXID |
Order lifecycle
- A partner requests an ePay brand, face value, currency, and digital delivery.
- The processor reads the brand
hostattribute and selects the matching host credentials and endpoint fromconfig/epay.php. - It resolves the product identifier. Fixed-denomination brands use
epay-sku-<amount with two decimals>; open-value brands useepay-sku. - It reads the partner attribute
epaystoreid-<partner slug>forSHOPID. - It sends a
SALErequest. Amounts are converted to minor units, currency is uppercased, and the partner client request ID is sent asTXID. - A successful response must contain
PINCREDENTIALS.HOSTTXIDbecomes the processor reference,PINCREDENTIALS.PINbecomes the voucher code, and the expiry is mapped from the configured brand expiry or providerVALIDTO. - The application creates the delivery URL and records the successful ePay audit. A Wrappr failure after provider success is an error and must be investigated as a potentially issued voucher.
- A manual cancellation uses
CANCELwith the original client request ID inTXREF. If the initial create call fails before a response is received, the processor attempts an automatic cancellation using a transaction ID suffixed withAC.
Example API order flow
The ePay client posts JSON to the selected host endpoint. Credentials are part of the JSON authorization object in this integration; the examples redact them. Values, product IDs, transaction IDs, and voucher data are illustrative.
Create a voucher
For a non-central host such as gb or rest_of_europe, the request includes MODE and PRODUCTID:
POST ${EPAY_ENDPOINTURI}
Accept: application/json
Content-Type: application/json;charset=utf-8
{
"TYPE": "SALE",
"AUTHORIZATION": {
"USERNAME": "[REDACTED]",
"PASSWORD": "[REDACTED]"
},
"TERMINALID": "[REDACTED]",
"LOCALDATETIME": "2026-08-21 17:17:00",
"TXID": "client-request-id-example",
"AMOUNT": 10000,
"CURRENCY": "GBP",
"SHOPID": "[PARTNER SHOP ID]",
"RECEIPT": {
"LANGUAGE": "ENG"
},
"MODE": "DIRECT",
"PRODUCTID": "product-sku-example"
}
For a central.* host, the processor sends the product identifier as CARD.EAN and does not add MODE or PRODUCTID:
{
"TYPE": "SALE",
"AUTHORIZATION": {
"USERNAME": "[REDACTED]",
"PASSWORD": "[REDACTED]"
},
"TERMINALID": "[REDACTED]",
"LOCALDATETIME": "2026-08-21 17:17:00",
"TXID": "client-request-id-example",
"AMOUNT": 10000,
"CURRENCY": "EUR",
"SHOPID": "[PARTNER SHOP ID]",
"RECEIPT": {
"LANGUAGE": "ENG"
},
"CARD": {
"EAN": "product-sku-example"
}
}
A redacted successful response has this relevant shape:
{
"AMOUNT": 10000,
"CURRENCY": "GBP",
"HOSTTXID": "epay-reference-example",
"MODE": "DIRECT",
"PINCREDENTIALS": {
"PIN": "[REDACTED VOUCHER CODE]",
"SERIAL": "[REDACTED SERIAL]",
"VALIDTO": "2027-08-21T00:00:00.000Z"
},
"RESULT": 0,
"RESULTTEXT": "OK",
"SERVERDATETIME": "2026-08-21 17:17:01",
"TERMINALID": "[REDACTED]",
"TXID": "provider-transaction-example",
"TXNERROR": 0,
"TYPE": "SALE"
}
Cancel a voucher
Manual cancellation uses TYPE: CANCEL, MODE: MANUAL, and a TXREF containing the original client transaction ID. The serial number from the saved issue response is compared with the cancellation response when PINCREDENTIALS is present.
{
"TYPE": "CANCEL",
"AUTHORIZATION": {
"USERNAME": "[REDACTED]",
"PASSWORD": "[REDACTED]"
},
"TERMINALID": "[REDACTED]",
"LOCALDATETIME": "2026-08-21 17:18:00",
"TXID": "cancellation-request-id-example",
"AMOUNT": 10000,
"CURRENCY": "GBP",
"SHOPID": "[PARTNER SHOP ID]",
"RECEIPT": {
"LANGUAGE": "ENG"
},
"MODE": "MANUAL",
"PRODUCTID": "product-sku-example",
"TXREF": {
"TYPE": "CLIENT",
"Value": "original-client-request-id-example"
}
}
Automatic cancellation uses the same TXREF type, sets MODE: AUTOMATIC, and appends AC to the original transaction ID. It is an internal recovery request, not a second customer order.
Response mapping and validation
The processor treats a response as unsuccessful when RESULT is present and is not 0. Empty responses and transport errors are also failures. For an issue response, PINCREDENTIALS must exist; otherwise the sale is not completed.
| Provider data | Application result |
|---|---|
RESULT: 0 | Successful provider result check |
Non-zero RESULT | ePay error containing RESULT and RESULTTEXT; no card is completed |
| Missing or empty response | ePay error; no card is completed |
Missing PINCREDENTIALS on SALE | ePay error even when another response field is present |
HOSTTXID | processor_reference |
PINCREDENTIALS.PIN | Card code; it is not copied into the application PIN field |
PINCREDENTIALS.SERIAL | Returned only when the brand returnSerialNumber attribute is truthy; used for cancellation comparison when available |
Provider VALIDTO | Expiration fallback unless it is the sentinel 3000-01-01... value |
Brand expiry_months | Preferred application expiry when configured |
Cancellation PINCREDENTIALS.SERIAL | Must match the saved issue serial when the response includes it |
Cancellation AMOUNT | Divided by 100 for the returned cancellation card face value |
Receipt arrays, server timestamps, and other response fields are retained in the raw audit response but do not by themselves establish voucher completion. The application-generated URL is created after the ePay card has been mapped; a failure in that later URL step leaves a provider-issued voucher requiring manual cancellation review.
Provider states and retry behaviour
ePay does not expose a status-polling flow in this processor. The outcome is determined by the one synchronous response or by a cancellation response.
| Condition | Processor result | Operational consequence |
|---|---|---|
HTTP response 200 with successful provider result and issue credentials | Success | Voucher code and processor reference are available |
Non-zero RESULT or missing issue credentials | Processor error | Do not issue a replacement until the original transaction and audit are checked |
Transport/connection failure before a response is received for SALE | Automatic cancellation is attempted | Check both the failed sale audit and automatic cancellation evidence |
| Response received but parsing or URL generation fails | Error; automatic cancellation is not triggered by the create-response guard | Treat the voucher as potentially issued and arrange cancellation review |
| Cancellation response has a mismatched serial | Error | Do not regard the cancellation as confirmed |
Cancellation message contains PRODUCT ALREADY USED | Warning-level cancellation error | Escalate with the original serial and redacted audits; the code treats this as a warning, not success |
| Request timeout | External service-unavailable error | Check ePay outcome before retrying because the provider may have processed the sale |
There is no general idempotency key separate from the ePay TXID in the processor. The sale client request ID is used as the issue transaction ID, while an automatic cancellation uses the original ID plus AC. A manual re-order after an uncertain network result can create a duplicate voucher; compare the original transaction first.
Audit comparison fields
ePay stores the legacy AuditEpay record and also writes processor interaction request/response entries keyed by the sale record UUID. Compare:
AuditEpay.clientRequestID,partnerID,transactionTime,status, anderrorMessage.- The request fields
TYPE,MODE,TXID,TXREF,AMOUNT,CURRENCY,SHOPID, the selected product field, and host endpoint. Never exposeAUTHORIZATIONvalues. - The response fields
RESULT,RESULTTEXT,TYPE,HOSTTXID,TXID,AMOUNT,CURRENCY, and provider date/time fields. - For issue, compare
HOSTTXIDwith the card processor reference and compare the saved serial with any later cancellation serial without copying either credential into a ticket. - For manual cancellation, confirm the cancellation
TXREF.Valuepoints to the original client request ID and thatMODEisMANUAL. - For automatic cancellation, look for the
ACtransaction ID,MODE: AUTOMATIC, and the original issue transaction inTXREF. - Confirm the audit sequence: issue request, issue response, any automatic cancellation request/response, and any later manual cancellation request/response. A successful provider issue followed by a failed application URL generation is not the same as a provider rejection.
The AuditEpay table contains requestParams, responseParams, raw request and response, requestID, gcClaimCodeHash, and the status values REQUESTED, SUCCESS, or ERROR. Interaction audit content is encrypted at rest and supports redaction when read through the audit model.
Settings
Processor settings
The host configuration is read from config/epay.php. Each host entry supplies credentials and an endpoint:
| Host value | Configuration path | Environment variables |
|---|---|---|
gb | epay.hosts.gb | EPAY_USERNAME, EPAY_PASSWORD, EPAY_TERMINALID, EPAY_ENDPOINTURI |
rest_of_europe | epay.hosts.rest_of_europe | EPAY_USERNAME_ROE, EPAY_PASSWORD_ROE, EPAY_TERMINALID_ROE, EPAY_ENDPOINTURI_ROE |
central.france, central.italy, central.spain, central.germany, central.denmark, central.sweden, central.norway, central.finland, central.belgium, central.netherlands, central.austria, central.luxembourg, central.switzerland, central.portugal | epay.hosts.central.<country> | Country-specific EPAY_USERNAME_CENTRAL_* and EPAY_TERMINALID_CENTRAL_* values, with EPAY_ENDPOINTURI_CENTRAL for the endpoint |
The request timeout is fixed in EpayProcessor at 20.0 seconds. The provider credentials are sent in the JSON AUTHORIZATION object. No live endpoint, credential, terminal ID, or shop ID should be copied into operational documentation or tickets.
Brand settings
The host brand attribute is required and selects the host configuration. Supported values are gb, rest_of_europe, and the listed central.<country> values. A missing host produces a configuration error.
Product mappings follow the brand's denomination model:
| Brand model | Attribute used by the processor | Request field |
|---|---|---|
| Fixed denominations | epay-sku-<face value with two decimals>, for example epay-sku-123.00 | PRODUCTID for non-central hosts or CARD.EAN for central hosts |
| Open value | epay-sku | PRODUCTID for non-central hosts or CARD.EAN for central hosts |
The partner must have epaystoreid-<partner slug> as a partner attribute for SHOPID. Missing product or shop mappings stop request construction. The optional returnSerialNumber brand attribute controls whether the serial is included in the returned application card; its default behavior is false.
The checked-in onboarding migration includes host assignments for brands such as itunes-de, itunes-fr, just-eat-ie, Nintendo country variants, share-now-de, share-now-it, and Xbox country variants. It also records product identifiers for brands including itunes, google-play, just-eat, digiigifts, and YouChoose variants. These migration values are onboarding history, not a substitute for checking the current brand attributes.
API operations
| Operation | Internal service | Provider request | Use |
|---|---|---|---|
| Issue | ePayCreateGC | TYPE: SALE | Synchronously issue a voucher |
| Manual cancellation | ePayCancelGC | TYPE: CANCEL, MODE: MANUAL | Cancel an existing issue using TXREF |
| Automatic cancellation | ePayCancelAutomatic | TYPE: CANCEL, MODE: AUTOMATIC | Recovery attempt after a create-call failure |
No ePay catalogue, balance, or status-retrieval operation is defined in the inspected processor/client code. ePay uses the issue response itself rather than a separate retrieval call.
Customer-service investigation
For a failed, uncertain, or cancellation-related order:
- Confirm the sale UUID, client request ID, partner slug, brand slug, denomination, currency, and the requested transaction type.
- Confirm the current brand
host, fixed/open denomination flag, matchingepay-sku-*orepay-sku, and partnerepaystoreid-<partner slug>attribute. - Locate the
AuditEpayrecord byclientRequestIDand partner ID. Compare its status, error message, request/response, and transaction time. - In the redacted interaction audit, verify the endpoint family and compare
TYPE,MODE,TXID,TXREF,AMOUNT,CURRENCY, and product field. Never include the authorization object in an escalation. - If ePay returned
HOSTTXIDor issue credentials, treat the voucher as potentially issued even if the application URL failed. Check for an automatic cancellation attempt before considering a manual cancellation. - For cancellation, compare the original response serial with the cancellation response serial, and verify
RESULT: 0,TYPE: CANCEL, and the expectedTXREF. - Do not manually re-order after a timeout, connection failure, or malformed response until the original
TXIDand any automatic cancellation audit have been reviewed.
Limitations and support contacts
The ePay integration supports issue and cancellation only. Balance lookup, provider catalogue retrieval, and a separate order-status retrieval operation are not implemented here. The codebase does not define an ePay-specific technical or support contact in the inspected config, migrations, or tests; use the established internal escalation route when the redacted audit comparison is inconclusive.
Escalations should include the internal sale UUID, client request ID, partner ID/slug, brand and host value, processor reference if present, transaction times, sanitized result code/text, and the ordered audit sequence. Do not include passwords, authorization headers, voucher codes, serial numbers, full shop IDs, or live card data.
Related code
app/Processors/EpayProcessor.php— synchronous issue, cancellation, request construction, response mapping, timeout handling, and automatic cancellation.app/AuditEpay.php— legacy ePay audit model and stored fields.app/ProcessorInteractionAuditLog.php— encrypted processor request/response interaction records.config/epay.php— host, endpoint, credential, and terminal configuration.app/DataIssuer.php— ePay additional brand attributes and SKU format.database/migrations/2017_05_22_091328_create_audit_epay.php— ePay audit schema and issuer creation.database/migrations/2019_08_13_145053_RCC-5187_move_epay_store_id_to_partner_attribute.php— partner shop-ID migration.database/migrations/2024_06_26_074902_rcc-11795_epay-sku-configuration.php— host, serial-return, and product-ID onboarding mappings.database/migrations/2024_10_07_134754_r_c_c-15073-correct-bad-epay-skus-and-convert-to-new-format-fixed-denom.php— fixed-denomination SKU attribute format.database/migrations/2024_10_08_153937_r_c_c-15073-convert-open-value-epay-sku-attribute-names-to-new-format.php— open-valueepay-skuattribute format.tests/Unit/Processors/EpayProcessorTest.php— issue, cancellation, host selection, SKU mapping, expiry, serial-return, audit, and transport scenarios.