Describe the bug
The OpenAPI specification (TerminalAPI-v1.yaml) contains multiple type mismatches where fields are defined as integer but the actual API responses return string values. Additionally, several fields are incorrectly marked as required when they are actually optional in certain response contexts. These mismatches cause JSON deserialization failures when using generated client code.
To Reproduce
Steps to reproduce the behavior:
- Generate client code from the official
TerminalAPI-v1.yaml OpenAPI specification
- Make a Payment request to an Adyen terminal
- Receive the PaymentResponse with fields like
POIReconciliationID, CardCountryCode
- Attempt to deserialize the JSON response
- Observe type cast exceptions:
type 'String' is not a subtype of type 'num?' in type cast
Alternative reproduction:
- Compare the official Adyen Terminal API Postman collection examples
- Check the data types in the example responses
- Compare against the OpenAPI specification
- Observe discrepancies in type definitions
Expected behavior
The OpenAPI specification should accurately reflect the actual API response types:
Type Mismatches Found
1. POIData.POIReconciliationID
- Current specification:
integer (lines 1570, 4739, 5336, 5362)
- Actual API response:
string (e.g., "1000")
- Expected: Should be defined as
type: string
2. CardData.CardCountryCode
- Current specification:
integer (line 1418)
- Actual API response:
string (e.g., "826" for GB)
- Expected: Should be defined as
type: string with minLength: 3 and maxLength: 3
3. SensitiveCardData fields
Multiple fields incorrectly defined as integer when they should be string:
- PAN (line 1431): Should be
string with minLength: 1, maxLength: 19
- CardSeqNumb (line 1437): Should be
string with minLength: 3, maxLength: 3
- ExpiryDate (lines 1443, 1449): Should be
string with minLength: 4, maxLength: 4
4. MobileData fields
Multiple fields incorrectly defined as integer when they should be string:
- MSISDN (line 3759): Should be
string with minLength: 1, maxLength: 25
- IMSI (line 3765): Should be
string with minLength: 1, maxLength: 25
- IMEI (line 3771): Should be
string with minLength: 1, maxLength: 25
- MobileCountryCode (line 3777): Should be
string with minLength: 3, maxLength: 3
- MobileNetworkCode (line 3783): Should be
string with minLength: 1, maxLength: 3
- MaskedMSISDN (line 3789): Should be
string with minLength: 1, maxLength: 25
5. Required fields in response schemas
Several response schemas incorrectly mark SaleData and POIData as required when they are actually optional in nested response contexts:
- PaymentResponse (lines 5174-5177):
SaleData and POIData should not be in the required array
- CardAcquisitionResponse (lines 5214-5217):
SaleData and POIData should not be in the required array
- LoyaltyResponse (lines 5245-5248):
SaleData and POIData should not be in the required array
- StoredValueResponse (lines 5277-5280):
SaleData and POIData should not be in the required array
Context: These fields are present in the initial payment response but are omitted when the same response structure is nested within a TransactionStatusResponse → RepeatedMessageResponse → RepeatedResponseMessageBody. Marking them as required causes deserialization to fail in these nested contexts.
Evidence
From Official Adyen Terminal API Postman Collection
The official Postman collection includes example responses that demonstrate these type mismatches:
- POIReconciliationID: Shown as string values in Postman examples
- CardCountryCode: ISO 3166-1 numeric country codes are transmitted as strings (e.g.,
"826")
- Card number fields: PAN, ExpiryDate, etc., are string fields per PCI-DSS standards
- Mobile identifiers: MSISDN, IMSI, IMEI are string fields per telecom standards
From Actual Terminal Responses
Decrypted terminal responses consistently show:
{
"POIData": {
"POIReconciliationID": "1000" // String, not integer
},
"CardData": {
"CardCountryCode": "826" // String, not integer
}
}
Environment
Impact
These type mismatches have significant impact:
- Client Code Generation: Generated clients fail at runtime with type cast exceptions
- Developer Experience: Developers must implement custom workarounds to handle type conversions
- Reliability: Applications crash when encountering these fields in API responses
- Maintenance: Custom workarounds must be maintained separately from generated code
- Receipt Printing: The incorrect
required fields cause complete failure of receipt printing functionality when accessing transaction status
Proposed Solution
Update the OpenAPI specification to match actual API behavior:
- Change all identified fields from
integer to string with appropriate constraints
- Remove
SaleData and POIData from required arrays in response schemas
- Add validation patterns where applicable (e.g., ISO country codes, PAN format)
- Validate the specification against actual terminal responses
- Ensure Postman collection examples align with specification
Additional Context
- These issues affect all programming languages using the OpenAPI specification for client generation
- The type mismatches are consistent across different terminal models and environments (cloud/local)
- Similar issues may exist in other parts of the specification that we haven't tested yet
- The specification should follow industry standards (ISO 3166-1 for country codes, PCI-DSS for card data, ITU-T for mobile identifiers)
Files Referenced
TerminalAPI-v1.yaml: OpenAPI specification with type errors
Adyen Terminal API.postman_collection.json: Official Postman collection showing correct types
- Actual terminal response logs: Consistently demonstrate string types for the fields listed above
Note: We have created a corrected version of the specification with all these fixes applied and successfully tested it with our Flutter/Dart application. The corrected specification eliminates all type cast exceptions and allows proper deserialization of all API responses.
Note2
This ticket has been generated using AI agent because comparison of the TerminalAPI-v1.yaml spec and Postman collection with examples was not really an option because of the size of the documents. Please have a closer look at the rest of the response types 🙏
terminal-api.yaml
Describe the bug
The OpenAPI specification (
TerminalAPI-v1.yaml) contains multiple type mismatches where fields are defined asintegerbut the actual API responses returnstringvalues. Additionally, several fields are incorrectly marked asrequiredwhen they are actually optional in certain response contexts. These mismatches cause JSON deserialization failures when using generated client code.To Reproduce
Steps to reproduce the behavior:
TerminalAPI-v1.yamlOpenAPI specificationPOIReconciliationID,CardCountryCodetype 'String' is not a subtype of type 'num?' in type castAlternative reproduction:
Expected behavior
The OpenAPI specification should accurately reflect the actual API response types:
Type Mismatches Found
1. POIData.POIReconciliationID
integer(lines 1570, 4739, 5336, 5362)string(e.g.,"1000")type: string2. CardData.CardCountryCode
integer(line 1418)string(e.g.,"826"for GB)type: stringwithminLength: 3andmaxLength: 33. SensitiveCardData fields
Multiple fields incorrectly defined as
integerwhen they should bestring:stringwithminLength: 1,maxLength: 19stringwithminLength: 3,maxLength: 3stringwithminLength: 4,maxLength: 44. MobileData fields
Multiple fields incorrectly defined as
integerwhen they should bestring:stringwithminLength: 1,maxLength: 25stringwithminLength: 1,maxLength: 25stringwithminLength: 1,maxLength: 25stringwithminLength: 3,maxLength: 3stringwithminLength: 1,maxLength: 3stringwithminLength: 1,maxLength: 255. Required fields in response schemas
Several response schemas incorrectly mark
SaleDataandPOIDataas required when they are actually optional in nested response contexts:SaleDataandPOIDatashould not be in therequiredarraySaleDataandPOIDatashould not be in therequiredarraySaleDataandPOIDatashould not be in therequiredarraySaleDataandPOIDatashould not be in therequiredarrayContext: These fields are present in the initial payment response but are omitted when the same response structure is nested within a
TransactionStatusResponse→RepeatedMessageResponse→RepeatedResponseMessageBody. Marking them as required causes deserialization to fail in these nested contexts.Evidence
From Official Adyen Terminal API Postman Collection
The official Postman collection includes example responses that demonstrate these type mismatches:
"826")From Actual Terminal Responses
Decrypted terminal responses consistently show:
{ "POIData": { "POIReconciliationID": "1000" // String, not integer }, "CardData": { "CardCountryCode": "826" // String, not integer } }Environment
Impact
These type mismatches have significant impact:
requiredfields cause complete failure of receipt printing functionality when accessing transaction statusProposed Solution
Update the OpenAPI specification to match actual API behavior:
integertostringwith appropriate constraintsSaleDataandPOIDatafromrequiredarrays in response schemasAdditional Context
Files Referenced
TerminalAPI-v1.yaml: OpenAPI specification with type errorsAdyen Terminal API.postman_collection.json: Official Postman collection showing correct typesNote: We have created a corrected version of the specification with all these fixes applied and successfully tested it with our Flutter/Dart application. The corrected specification eliminates all type cast exceptions and allows proper deserialization of all API responses.
Note2
This ticket has been generated using AI agent because comparison of the
TerminalAPI-v1.yamlspec and Postman collection with examples was not really an option because of the size of the documents. Please have a closer look at the rest of the response types 🙏terminal-api.yaml