aporat / store-receipt-validator

PHP receipt validator for Apple iTunes, Google Play and Amazon App Store
Apache License 2.0
633 stars 153 forks source link

Client Error with 400 Bad Request #146

Closed eranthaWELIKALA closed 3 years ago

eranthaWELIKALA commented 3 years ago

Hi!, I have two servers and this works in one, and in the other one, it is not working(Can not validate the receipt). Let me name them as dev server, and test sever. Both servers use the Laravel framework.

Dev server is the development server which runs wth "php artisan serve --host=[IP] --port=[port]" Dev server validates the receipt without any issue.

But in the test server receipt validation fails with the below error. The test server runs on an apache server. I'm still in the testing process and using a sandbox account.

Do I have to add additional changes when moving from a development server? Can anyone direct me to the right path?

The solution for this issue did not work for me.

Environment new iTunesValidator(iTunesValidator::ENDPOINT_SANDBOX);

Error Client error:POST https://sandbox.itunes.apple.com/verifyReceiptresulted in a400 Bad Requestresponse:\n<html>\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\"/>\n<title>Error 400 Bad Request</title>\n< (truncated...)\n

Stafox commented 3 years ago

Do a debug using xdebug and check what data being sent to Apple server.

mochibits commented 3 years ago

Experiencing the same issue. Here's the whole message.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Error 400 Bad Request</title>
</head>
<body><h2>HTTP ERROR 400 Bad Request</h2>
<table>
<tr><th>URI:</th><td>/verifyReceipt</td></tr>
<tr><th>STATUS:</th><td>400</td></tr>
<tr><th>MESSAGE:</th><td>Bad Request</td></tr>
<tr><th>SERVLET:</th><td>io.dropwizard.jersey.setup.JerseyServletContainer-60433b90</td></tr>
</table>
</body>
</html>

Even with no receipt or password, the sandbox server should return a 21000 status.

It works locally with postman, and on my server with curl. Just can't get the code working.

Any ideas? Thanks.

mochibits commented 3 years ago

Figured it out. Had to dig deep. @eranthaWELIKALA

You need to specify Content-type in the request call, otherwise, the request with a body doesn't know it's JSON.

Validator.php line 275

$httpResponse = $client->request('POST', '/verifyReceipt', 
    [
        'body' => $this->prepareRequestData(), 
        'headers' => [ 'Content-type' => 'application/json']
    ]
);
bonep commented 3 years ago

@mochibits thank you! This code is working for me


$response = (new iTunesValidator(iTunesValidator::ENDPOINT_PRODUCTION))
            ->setReceiptData($receiptBase64Data)
            ->setRequestOptions(['headers' => ['Content-type' => 'application/json']])
            ->validate();