Activate Voucher
POST/client/users/:correlation_id/voucher/:voucher_id/activate
POST /voucher/{voucherId}/activate — PAC Voucher Activation
Activates a Product Authorization Code (PAC) voucher via an external provider (e.g., Kesseltronics car-wash terminals). Only vouchers with rewardType = PRODUCT_AUTHORIZATION_CODE can be activated.
Path Parameters
| Param | Type | Description |
|---|---|---|
correlationId | string | Session correlation ID |
voucherId | string | Voucher issuance code, format: {definitionId}::{issuanceUuid} |
Request
No body. All input is conveyed via path + session context (OAuth token → account).
Preconditions
- Voucher exists under the current session's account → else
404 VOUCHER_NOT_FOUND - Voucher is in
AVAILABLEstate → else409 VOUCHER_NOT_AVAILABLE(e.g., alreadyREDEEMED,EXPIRED,INVALIDATED) - Voucher definition has
rewardType = PRODUCT_AUTHORIZATION_CODE→ else400 INVALID_VOUCHER_TYPE - Provider is configured on the voucher definition → else
422 PROVIDER_NOT_CONFIGURED
Activation Flow
- Load voucher instance + hydrate definition via
BatchGetItem - Idempotency check: if
activation.activatedAtpresent andcodeExpiryin future → return existing code, skip provider call (flagidempotent: true) - Call provider (e.g., Kesseltronics) → receive
authorizationCode - Atomic write: transition instance
status → ACTIVATED, persistactivation.{activatedAt, provider, codeExpiry, authorizationCode}— partial writes are rejected - Emit
VoucherEvents: ACTIVATEDentry - Return response
Idempotency
Duplicate calls within the active activation window return the same authorization code without hitting the provider. Detection is based on:
activation.activatedAtpresent, ANDactivation.codeExpiryin the future
After expiry, the voucher returns to a re-activatable state and a new provider call is made. Response includes idempotent: true on the duplicate case.
Response — 200
| Field | Type | Description |
|---|---|---|
authorizationCode | string | PAC returned by provider |
voucherId | string | Echo of path param |
status | string | Always ACTIVATED |
provider | string | e.g., KESSELTRONICS |
productName | string | Display name (e.g., Car Wash) |
activatedAt | string | ISO-8601 |
codeExpiry | string | ISO-8601 — when the code is no longer usable at the terminal |
idempotent | boolean | Present = true only when call was a duplicate (no new provider hit) |
Error Responses
| Status | errorCode | When |
|---|---|---|
| 400 | INVALID_VOUCHER_TYPE | Not a PAC voucher |
| 401 | — | Missing/expired OAuth token |
| 404 | VOUCHER_NOT_FOUND | Voucher doesn't exist under this account |
| 409 | VOUCHER_NOT_AVAILABLE | Already redeemed, expired, or invalidated |
| 422 | PROVIDER_NOT_CONFIGURED | Voucher definition missing activation provider config |
| 500 | — | Unexpected server error |
| 502 | EXTERNAL_SERVICE_RESPONSE_ERROR | Provider returned malformed/unparseable response |
| 504 | EXTERNAL_SERVICE_TIMEOUT | Provider did not respond within timeout |
Console (CSR) Note
CSRs can VIEW activation status but cannot activate on behalf of the member — activation requires the member to be present at the terminal (security policy).
Related
GET .../issuances?type=VOUCHER— find PAC vouchers (rewardType=PRODUCT_AUTHORIZATION_CODE+ noactivation.activatedAt)
Request
Responses
- 200
- 400
- 403
- 404
- 409
- 422
- 502
- 504
200 - Activation Successful
400 - Invalid Voucher ID Format
403 - Ghost Member Not Allowed
404 - Voucher Not Found
409 - Voucher Not Activatable (Wrong Reward Type)
422 - Provider Not Configured
502 - Provider Returned Invalid Response
504 - Provider Request Timed Out