Description
After upgrading to Adyen .NET API Library v34.x, we are seeing a deserialization regression in a Checkout model after the library-wide System.Text.Json migration introduced in v34.0.0. Our concrete reproducible case is PaymentMethodsAsync: Adyen returns HTTP 200 OK, but the Adyen .NET API Library fails while deserializing the successful response into Adyen.Checkout.Models.PaymentMethodsResponse. The failure appears to be caused by the PaymentMethodsResponse model shape in 34.0.2. The type has a [JsonConstructor] whose parameters use Option<List<...>>, while the JSON-facing properties are List<...>. System.Text.Json rejects this constructor binding. This may be related to the broader STJ migration already visible elsewhere in the library, but this report is specifically about a Checkout model deserialization failure in 34.0.2.
Steps to reproduce
- Install Adyen .NET API Library
34.0.2.
- Call Checkout
paymentMethods through PaymentsService.PaymentMethodsAsync(...).
- Receive a valid HTTP
200 OK response from Adyen.
- Call
TryDeserializeOkResponse(out PaymentMethodsResponse result).
- Observe deserialization failure.
Minimal reproduction without making a real HTTP request:
- Install Adyen .NET API Library
34.0.2.
- Deserialize the following JSON into
Adyen.Checkout.Models.PaymentMethodsResponse using System.Text.Json.
- Observe
InvalidOperationException.
Actual behavior
Deserialization fails with:
System.InvalidOperationException: Each parameter in the deserialization constructor on type 'Adyen.Checkout.Models.PaymentMethodsResponse' must bind to an object property or field on deserialization. Each parameter name must match with a property or field on the object. Fields are only considered when 'JsonSerializerOptions.IncludeFields' is enabled. The match can be case-insensitive.
In the Adyen SDK logging this appears as:
An error occurred while deserializing the "OK" response.
Expected behavior
If Adyen returns HTTP 200 OK for /paymentMethods, the library should deserialize the response into PaymentMethodsResponse successfully.
More generally, the System.Text.Json migration introduced in v34.0.0 should not leave Checkout response models in a state where they cannot be deserialized by the library itself.
Code snippet or screenshots (if applicable)
Runtime path:
var apiResponse = await checkout.PaymentMethodsAsync(paymentMethodsRequest, null, default);
if (!apiResponse.TryDeserializeOkResponse(out PaymentMethodsResponse response))
{
throw new Exception("Failed to deserialize Adyen payment methods response.");
}
Minimal reproduction:
using System.Text.Json;
using Adyen.Checkout.Models;
var json = "{\"paymentMethods\":[],\"storedPaymentMethods\":[]}";
var result = JsonSerializer.Deserialize<PaymentMethodsResponse>(json);
Relevant model shape observed from 34.0.2:
[JsonConstructor]
PaymentMethodsResponse(
Option<List<PaymentMethod>> paymentMethods,
Option<List<StoredPaymentMethod>> storedPaymentMethods)
public List<PaymentMethod> PaymentMethods { get; set; } // json name: paymentMethods
public List<StoredPaymentMethod> StoredPaymentMethods { get; set; } // json name: storedPaymentMethods
This seems incompatible with System.Text.Json constructor binding.
Adyen .NET API Library version
34.0.2
.NET version
.NET 8
Operating System
Windows
Additional context
- The HTTP request itself succeeds and Adyen returns
200 OK.
- This appears to be a model/deserialization issue, not a request formatting issue.
- We reproduced the problem locally without calling the real API by deserializing a minimal JSON payload directly into
PaymentMethodsResponse.
PropertyNameCaseInsensitive = true does not fix it.
IncludeFields = true does not fix it.
- Forcing
System.Text.Json to use the parameterless constructor for this type does work, which suggests the problem is specifically the [JsonConstructor] path on PaymentMethodsResponse.
v34.0.0 release notes explicitly mention:
Support native System.Text.Json for serialization and deserialization.
- We do not see anything in the
v34.0.0 release notes that suggests consumers should apply a special Checkout-specific migration step for PaymentMethodsResponse.
34.0.2 release notes do not mention a fix related to Checkout model deserialization; they only mention:
Fix Classic Recurring live URL (#1444)
.Net Fiddle: https://dotnetfiddle.net/eaXF1g
Description
After upgrading to Adyen .NET API Library
v34.x, we are seeing a deserialization regression in a Checkout model after the library-wideSystem.Text.Jsonmigration introduced inv34.0.0. Our concrete reproducible case isPaymentMethodsAsync: Adyen returns HTTP200 OK, but the Adyen .NET API Library fails while deserializing the successful response intoAdyen.Checkout.Models.PaymentMethodsResponse. The failure appears to be caused by thePaymentMethodsResponsemodel shape in34.0.2. The type has a[JsonConstructor]whose parameters useOption<List<...>>, while the JSON-facing properties areList<...>.System.Text.Jsonrejects this constructor binding. This may be related to the broader STJ migration already visible elsewhere in the library, but this report is specifically about a Checkout model deserialization failure in34.0.2.Steps to reproduce
34.0.2.paymentMethodsthroughPaymentsService.PaymentMethodsAsync(...).200 OKresponse from Adyen.TryDeserializeOkResponse(out PaymentMethodsResponse result).Minimal reproduction without making a real HTTP request:
34.0.2.Adyen.Checkout.Models.PaymentMethodsResponseusingSystem.Text.Json.InvalidOperationException.Actual behavior
Deserialization fails with:
In the Adyen SDK logging this appears as:
Expected behavior
If Adyen returns HTTP
200 OKfor/paymentMethods, the library should deserialize the response intoPaymentMethodsResponsesuccessfully.More generally, the
System.Text.Jsonmigration introduced inv34.0.0should not leave Checkout response models in a state where they cannot be deserialized by the library itself.Code snippet or screenshots (if applicable)
Runtime path:
Minimal reproduction:
Relevant model shape observed from
34.0.2:This seems incompatible with
System.Text.Jsonconstructor binding.Adyen .NET API Library version
34.0.2
.NET version
.NET 8
Operating System
Windows
Additional context
200 OK.PaymentMethodsResponse.PropertyNameCaseInsensitive = truedoes not fix it.IncludeFields = truedoes not fix it.System.Text.Jsonto use the parameterless constructor for this type does work, which suggests the problem is specifically the[JsonConstructor]path onPaymentMethodsResponse.v34.0.0release notes explicitly mention:Support native System.Text.Json for serialization and deserialization.v34.0.0release notes that suggests consumers should apply a special Checkout-specific migration step forPaymentMethodsResponse.34.0.2release notes do not mention a fix related to Checkout model deserialization; they only mention:Fix Classic Recurring live URL (#1444).Net Fiddle: https://dotnetfiddle.net/eaXF1g