I’m trying to create an order from Woocommerce API and it is not working as intended: the request (sent as POST) is returning all orders (like it would be a GET request), instead of creating a new one. The reald odd thing is that the same exact request is working on the pre-production server but not on the production server.
This seems to be a global issue with the API, as other requests (like creating a post from the WP API) are not working, except the POST request used to get the access token.
Here is the request I send as POST:
curl -X POST https://www.domain.tld/wp-json/wc/v2/orders?access_token=... -H "Content-Type: application/json" -d '{ "customer_id": "1", "payment_method": "app", "payment_method_title": "Test payment", "set_paid": false, "billing": { "first_name": "test", "last_name": "test", "address_1": "test", "address_2": "test", "city": "test", "postcode": "00000", "country": "FR", "phone": "0123456789", "email": "test@test.tld" }, "shipping": { "first_name": "test", "last_name": "test", "address_1": "test", "address_2": "test", "city": "test", "postcode": "00000", "country": "FR", "phone": "0123456789", "email": "test@test.tld" }, "shipping_lines": [ { "method_id": "livraison_gratuite", "method_title": "Livraison gratuite", "total": 0 } ], "line_items": [ { "product_id": 302, "variation_id": 589, "quantity": 1 }, { "product_id": 798, "quantity": 1 } ] }'
Again the same request is working on pre-production server so I don’t think the problem is related to the request itself.
Here is the return I get in postman for this request on production server:
I eliminated all the potentiel causes:
- Both websites are using the same plugins, WordPress version and plugins are both up to date,
- Both websites are using https,
- Cache plugin has been deactivated,
- API settings in Woocommerce and WP Oauth Server are identical,
- User used for sending the request (identified with the access token provided by WP Oauth Server) is admin,
- Server configuration is the same so far as I know (PHP7).
I’m running out of idea about why this is happening. Anyone have a clue about what could cause this?
Advertisement
Answer
I finally found out what was happening here. There is a redirection rule on the production server that add the trailing slash to URL when it is missing. This was causing the request recognized as GET instead of POST (POST data are not sent when HTTP request is redirected).
Adding a trailing slash fixed the issue:
curl -X POST https://www.domain.tld/wp-json/wc/v2/orders/?access_token=...
As a note, this can be used as well on the pre-production server that doesn’t use any redirect rule of this kind, so always adding a trailing slash to POST API requests can be a good idea for not stumbling upon this kind of issue.
An alternative solution can be to add a RewriteCond of this kind to prevent the redirection for POST requests:
RewriteCond %{REQUEST_URI} !(/$|.) RewriteCond %{THE_REQUEST} !POST RewriteRule (.*) %{REQUEST_URI}/ [R=301,L]