concardis / PHP_SDK

MIT License
3 stars 10 forks source link

Issue with placing an order #17

Open parths267 opened 4 years ago

parths267 commented 4 years ago

Using : $transactionResponse = $lib->orders()->preauth()->post($authorizingTransaction);

That caused an erro: Fatal error: Uncaught Concardis\Payengine\Lib\Internal\Exception\PayengineResourceException: HTTP/1.1 400 Bad Request in E:\xampp\htdocs\conc\src\Concardis\Payengine\Lib\Internal\Connection\Connection.php:89 Stack trace: #0 E:\xampp\htdocs\conc\src\Concardis\Payengine\Lib\Internal\AbstractClass\AbstractResource.php(61): Concardis\Payengine\Lib\Internal\Connection\Connection->post('/orders', '{"payment":{"pa...') #1 E:\xampp\htdocs\conc\src\Concardis\Payengine\Lib\Internal\Resource\Orders.php(29): Concardis\Payengine\Lib\Internal\AbstractClass\AbstractResource->post(Array) #2 E:\xampp\htdocs\conc\example\test.php(124): Concardis\Payengine\Lib\Internal\Resource\Orders->post(Object(Concardis\Payengine\Lib\Models\Request\Orders\AuthorizingTransaction)) #3 {main} thrown in E:\xampp\htdocs\conc\src\Concardis\Payengine\Lib\Internal\Connection\Connection.php on line 89

na-oma commented 3 years ago

Same Problem

We got the same error after an upgrade from PHP7.0 to PHP7.4 Our problem was a change introduced in PHP7.1: json_encode now uses the ini setting serialize_precision instead of precision. This changes the used precision of encoding floats to JSON from 14 to 17 (or maybe even -1 in the newest versions of PHP). Example: PHP7.0:

echo json_encode(round(284.03, 2) * 100);
28403

PHP7.4

echo json_encode(round(284.03, 2) * 100);
28402.999999999996

This breaks the API.

We had many places where we just rounded our prices to two decimals and multiplied by 100: $item->setUnitPrice(round($price, 2) * 100); This sets the price as a float type, even if the type hints of setUnitPrice require an int. But this int is never enforced in the library. So a float gets encoded. This worked in the past, but due to the different precision setting, the float now gets encoded with many decimals, but the API expects no decimals.

(Our) Solution

Just forcing the floats to ints. This does not work, since it converts 284.03 to 28402.999999999996 and then intval rounds down to 28402: $item->setUnitPrice(intval(round($price, 2) * 100));

This seems to work, altough I am not sure the intval is necessary if we do the rounding last: $item->setUnitPrice(intval(round($price * 100, 0)));

I am currently testing if this gets rid of the error in all cases.