diff --git a/CHANGELOG.md b/CHANGELOG.md index 3194ef0..0e7dcf9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ Check our main [developer changelog](https://developer.paddle.com/?utm_source=dx - `details->lineItems[]->priceId` is now nullable - `items[]->priceId` is now nullable - `details->lineItems[]->product` can now return `Product` (with `id`) or `TransactionPreviewProduct` (with nullable `id`) +- Empty custom data array will now serialize to empty JSON object `{}` ### Added - `TransactionsClient::create()` now supports operation items with optional properties: diff --git a/src/Client.php b/src/Client.php index 328d259..3bf87de 100644 --- a/src/Client.php +++ b/src/Client.php @@ -43,6 +43,7 @@ use Psr\Log\NullLogger; use Symfony\Component\Serializer\Encoder\JsonEncoder; use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter; +use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer; use Symfony\Component\Serializer\Normalizer\BackedEnumNormalizer; use Symfony\Component\Serializer\Normalizer\JsonSerializableNormalizer; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; @@ -177,7 +178,9 @@ private function requestRaw(string $method, string|UriInterface $uri, array|\Jso ); if ($payload !== null) { - $body = $serializer->serialize($payload, 'json'); + $body = $serializer->serialize($payload, 'json', [ + AbstractObjectNormalizer::PRESERVE_EMPTY_OBJECTS => true, + ]); $request = $request->withBody( // Satisfies empty body requests. diff --git a/src/Entities/Shared/CustomData.php b/src/Entities/Shared/CustomData.php index 4ba2593..f60433a 100644 --- a/src/Entities/Shared/CustomData.php +++ b/src/Entities/Shared/CustomData.php @@ -18,8 +18,10 @@ public function __construct( ) { } - public function jsonSerialize(): array|\JsonSerializable + public function jsonSerialize(): array|\JsonSerializable|\stdClass { - return $this->data; + return $this->data === [] + ? (object) [] + : $this->data; } } diff --git a/src/Notifications/Entities/Shared/CustomData.php b/src/Notifications/Entities/Shared/CustomData.php index 019422c..fcd4b3e 100644 --- a/src/Notifications/Entities/Shared/CustomData.php +++ b/src/Notifications/Entities/Shared/CustomData.php @@ -18,8 +18,10 @@ public function __construct( ) { } - public function jsonSerialize(): array|\JsonSerializable + public function jsonSerialize(): array|\JsonSerializable|\stdClass { - return $this->data; + return $this->data === [] + ? (object) [] + : $this->data; } } diff --git a/tests/Functional/Resources/Transactions/_fixtures/request/create_with_multiple_non_catalog_price_and_product.json b/tests/Functional/Resources/Transactions/_fixtures/request/create_with_multiple_non_catalog_price_and_product.json index c652d39..8d744ff 100644 --- a/tests/Functional/Resources/Transactions/_fixtures/request/create_with_multiple_non_catalog_price_and_product.json +++ b/tests/Functional/Resources/Transactions/_fixtures/request/create_with_multiple_non_catalog_price_and_product.json @@ -6,7 +6,7 @@ "description": "Annual (per seat)", "name": "Annual (per seat)", "product": { - "custom_data": [], + "custom_data": {}, "description": "Some description", "image_url": "https://paddle-sandbox.s3.amazonaws.com/user/10889/2nmP8MQSret0aWeDemRw_icon1.png", "name": "Annual (per seat)", diff --git a/tests/Functional/Resources/Transactions/_fixtures/request/create_with_non_catalog_price_and_product.json b/tests/Functional/Resources/Transactions/_fixtures/request/create_with_non_catalog_price_and_product.json index e665ce2..3d1f134 100644 --- a/tests/Functional/Resources/Transactions/_fixtures/request/create_with_non_catalog_price_and_product.json +++ b/tests/Functional/Resources/Transactions/_fixtures/request/create_with_non_catalog_price_and_product.json @@ -6,7 +6,7 @@ "description": "Annual (per seat)", "name": "Annual (per seat)", "product": { - "custom_data": [], + "custom_data": {}, "description": "Some description", "image_url": "https://paddle-sandbox.s3.amazonaws.com/user/10889/2nmP8MQSret0aWeDemRw_icon1.png", "name": "Annual (per seat)", diff --git a/tests/Functional/Resources/Transactions/_fixtures/request/preview_with_multiple_non_catalog_price_and_product.json b/tests/Functional/Resources/Transactions/_fixtures/request/preview_with_multiple_non_catalog_price_and_product.json index d43c8ef..9af26ef 100644 --- a/tests/Functional/Resources/Transactions/_fixtures/request/preview_with_multiple_non_catalog_price_and_product.json +++ b/tests/Functional/Resources/Transactions/_fixtures/request/preview_with_multiple_non_catalog_price_and_product.json @@ -6,7 +6,7 @@ "description": "Annual (per seat)", "name": "Annual (per seat)", "product": { - "custom_data": [], + "custom_data": {}, "description": "Some description", "image_url": "https://paddle-sandbox.s3.amazonaws.com/user/10889/2nmP8MQSret0aWeDemRw_icon1.png", "name": "Annual (per seat)", diff --git a/tests/Functional/Resources/Transactions/_fixtures/request/preview_with_non_catalog_price_and_product.json b/tests/Functional/Resources/Transactions/_fixtures/request/preview_with_non_catalog_price_and_product.json index 1473e76..fb433a7 100644 --- a/tests/Functional/Resources/Transactions/_fixtures/request/preview_with_non_catalog_price_and_product.json +++ b/tests/Functional/Resources/Transactions/_fixtures/request/preview_with_non_catalog_price_and_product.json @@ -6,7 +6,7 @@ "description": "Annual (per seat)", "name": "Annual (per seat)", "product": { - "custom_data": [], + "custom_data": {}, "description": "Some description", "image_url": "https://paddle-sandbox.s3.amazonaws.com/user/10889/2nmP8MQSret0aWeDemRw_icon1.png", "name": "Annual (per seat)", diff --git a/tests/Functional/Resources/Transactions/_fixtures/request/update_with_non_catalog_price_and_product.json b/tests/Functional/Resources/Transactions/_fixtures/request/update_with_non_catalog_price_and_product.json index c652d39..8d744ff 100644 --- a/tests/Functional/Resources/Transactions/_fixtures/request/update_with_non_catalog_price_and_product.json +++ b/tests/Functional/Resources/Transactions/_fixtures/request/update_with_non_catalog_price_and_product.json @@ -6,7 +6,7 @@ "description": "Annual (per seat)", "name": "Annual (per seat)", "product": { - "custom_data": [], + "custom_data": {}, "description": "Some description", "image_url": "https://paddle-sandbox.s3.amazonaws.com/user/10889/2nmP8MQSret0aWeDemRw_icon1.png", "name": "Annual (per seat)",