Wordpress HTTP API results in JSON_ERROR_SYNTAX - php

I'm Trying to correctly use wp_remote_get in my wordpress plugin which uses our API. The API checks the request body for is_json, which returns 4 - aka JSON_ERROR_SYNTAX. Using cURL has the desired response. Here's my code:
$args = array(
'body' => array('api_key' => 123),
'timeout' => '5',
'httpversion' => '1.0',
'blocking' => true,
'headers' => array(),
'cookies' => array()
);
$result = wp_remote_request('https://myapi.endpoint/api/1.0/request', $args);
var_dump($result['body'])
var_dump: string(13) ""api_key=123""
whereas the var_dump of my cURL request is string(15) "{"api_key=123"}"
Any ideas as to what I am doing incorrectly?

As Marc B stated, wp isn't sending json. You need to set the content type in the headers, and also send it as json:
$body = array('api_key' => 123);
$headers = array (
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'Content-Length' => strlen(json_encode($body)
);
$args = array(
'method' => 'POST',
'headers' => $headers,
'body' => json_encode($body)
);

Related

Got 415 error "Unsupported Media Type" when use wp_remote_post

I tried to send a POST request from WordPress to an external API (assign a tag to an user in a CRM system). When I used cURL, everything was OK. Here is the cURL code:
function my_function () {
$body = array ( 'tags' => array ( array (
'email' => 'xxx#gmail.com',
'tag' => 'Customer5'
))
);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "$api_url",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode($body, true),
CURLOPT_HTTPHEADER => array(
"Content-Type: application/json",
"User-Agent: Your App Name (www.yourapp.com)",
"Authorization: Basic xxxxxx"
),
));
$response = curl_exec($curl);
curl_close($curl);
var_dump($response);
}
add_action( 'init', 'my_function');
But then I switched to use wp_remote_post, I got a "415 - Unsupported Media Type" response.
$body = array ( 'tags' => array (
array(
'email' => 'xxx#gmail.com',
'tag' => 'Customer5'
))
);
$headers = array (
'Content-Type' => 'application/json',
'User-Agent' => 'Your App Name (www.yourapp.com)',
'Authorization' => 'Basic xxxxxx',
);
$request = wp_remote_post('$api_url', $arg );
$arg = array (
'header' => $headers,
'body' => json_encode($body, true),
'method' => 'POST',
'sslverify' => false,
);
echo '<pre>';
print_r($request);
echo '</pre>';
I tried a lot of modifications (changed associative array format to key:value pair, add AddType to htaccess file...), but nothing worked. Please help, I'm stuck
Excerpt from KeyCDN:
A 415 Unsupported Media Type error occurs when the origin server
refuses a particular request since the resource is in a format that is not supported by the server for the HTTP
method
used. This unsupported format type issue can be caused by what is
defined in the resource's Content-Type or Content-Encoding
headers.
And in your case, the error happened most likely because your remote request sent the wrong Content-Type header — which defaults to application/x-www-form-urlencoded when the HTTP method is POST.
And yes, you did include the right Content-Type value in your $headers array. But unfortunately in your $arg array which you passed to wp_remote_post(), you used the wrong array key — header, which should actually be headers (note the "s").
So use headers and not header, just as you can see below:
$api_url = 'your API URL';
$body = array(
'tags' => array(
array(
'email' => 'xxx#gmail.com',
'tag' => 'Customer5',
),
),
);
$headers = array(
'Content-Type' => 'application/json',
'User-Agent' => 'Your App Name (www.yourapp.com)',
'Authorization' => 'Basic xxxxxx',
);
$arg = array(
'headers' => $headers, // good
// 'header' => $headers, // bad; i.e. wrong array key ('header')
'body' => json_encode( $body ),
// 'method' can be omitted since you're using wp_remote_post()
'method' => 'POST',
'sslverify' => false,
);
$request = wp_remote_post( $api_url, $arg );
// ..if the response still isn't good, what's the output of this:
var_dump( $request );

Active Campaign API 403 Error using wp_remote_post();

Im creating a simple integration that should post our WooCommerce orders over to the Deep Data seciton via the API (V3)
Here is a simple example of the request Im trying to make.
Im running this script manually for the time being just to get it working. This is the array Im sending as my request using wp_remote_post($url, $request)
Array
(
[key] => KEY
[url] => URL/ecomOrders
[settings] => Array
(
[method] => POST
[timeout] => 5
[redirection] => 5
[httpversion] => 1.0
[user-agent] => WordPress/5.2.1; https://www.XXXX.com
[blocking] => 1
[body] => {"ecomOrder":{JSONORDER}}
[headers] => Array
(
[Api-Token] => KEY
)
)
)
This is (part of) what I get back from my response.
[body] =>
[response] => Array
(
[code] => 403
[message] => Forbidden
)
I have double checked the API key and URL and just a side note, we are already using the same method and script details in a similar reques to add contacts which is working fine.
Here is the code Im using (all $var's are defined earlier in the script):
$request = array(
'key' => $key,
'url' => $url,
'settings' => array(
'method' => 'POST',
'sslverify' => false,
'timeout' => 5,
'redirection' => 0,
'httpversion' => '1.0',
'user-agent' => 'WordPress/' . $wp_version . '; ' . home_url(),
'blocking' => true,
'body' => $body,
'headers' => array(
'Api-Token' => $key,
)
)
);
$response = wp_remote_post($url, $request);
We just ran into a similar issue today; where all the headers and payload were set correctly, but the API was returning a 401.
Our payload needed to be sent as json and we had to explicitly define that in the headers. Like so:
'content-type' => 'application/json'
Also, it look likes the request/args array isn't structured how WordPress recommends in the codex. (arguements)
$key = 'myKey';
$url = 'myURL'
$body = array('ecomOrder' => $myOrder);
$request = array(
'method' => 'POST',
'sslverify' => false,
'timeout' => 5,
'redirection' => 0,
'httpversion' => '1.0',
'user-agent' => 'WordPress/' . $wp_version . '; ' . home_url(),
'blocking' => true,
'body' => json_encode($body),
'headers' => array(
'content-type' => 'application/json',
'Api-Token' => $key,
)
);
$response = wp_remote_post($url, $request);
This may be a shot in the dark as I'm not familiar with Active Campaign's API, but hopefully it helps.
Resources
This stackoverflow article really helped.

Php, Guzzle, Schema validation failed but working in curl

I'm in the process of convert from cURL to Guzzle, and got most of it working.
GET requests working great etc.
My problem is the POST request, getting Schema validation errors.
It works in curl, so I'm a bit confused... well, a lot.
Client error: `POST https://restapi.e-conomic.com/customers` resulted in a `400 Bad Request` response:
{"message":"Schema validation failed.","errorCode":"E00500"
I hope one of you can tell me, if I did something wrong in the convert? Maybe my arrays needs to be formatted in another way.
This is my old working "cURL code":
$data = array(
'name' => 'Test User',
'address' => 'Road 123',
'email' => 'morten#domain.com',
'zip' => '9000',
'city' => 'City',
'country' => 'Danmark',
'corporateIdentificationNumber' => '12345678',
'customerGroup' => array(
'customerGroupNumber' => 1
),
'currency' => 'DKK',
'paymentTerms' => array(
'paymentTermsNumber' => 1
),
'vatZone' => array(
'vatZoneNumber' => 1
)
);
$options = array(
CURLOPT_URL => 'https://restapi.e-conomic.com/customers',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => array(
'X-AppSecretToken:[removed]',
'X-AgreementGrantToken:[removed]',
'Content-Type:application/json; charset=utf-8'
),
CURLOPT_POSTFIELDS => json_encode($data)
);
curl_setopt_array($ch, $options);
This is my new "guzzle code", that is causing me problems:
$client = new GuzzleHttp\Client();
$headers = [
'X-AppSecretToken' => '[removed]',
'X-AgreementGrantToken' => '[removed]',
'Content-Type' => 'application/json;charset=utf-8',
'debug' => false
];
$form_params = [
'name' => 'Test User',
'address' => 'Road 123',
'email' => 'test#email.dk',
'zip' => '9000',
'city' => 'City',
'country' => 'Danmark',
'corporateIdentificationNumber' => '12345678',
'customerGroup' => [
'customerGroupNumber' => 1
],
'currency' => 'DKK',
'paymentTerms' => [
'paymentTermsNumber' => 1
],
'vatZone' => [
'vatZoneNumber' => 1
]
];
$response = $client->post('https://restapi.e-conomic.com/customers', [
'headers' => $headers,
'form_params' => $form_params
]);
I tried to use the "body" parameter, as stated in the Guzzle documentation, but received this error:
Passing in the "body" request option as an array to send a POST request has been deprecated. Please use the "form_params" request option to send a application/x-www-form-urlencoded request, or the "multipart" request option to send a multipart/form-data request.
I'm not sure what to do and really hope, that one of you guys will tell me what i'm doing wrong.
https://restapi.e-conomic.com/schema/customers.post.schema.json#_ga=2.167601086.1488491524.1500877149-796726383.1499933074
https://restdocs.e-conomic.com/#post-customers
I had to post the quest as json:
$response = $client->post('https://restapi.e-conomic.com/customers', [
'headers' => $headers,
'json' => $form_params
]);

Codename one push notifications with php issue

I've enabled push notifications in my app, added the build hints, registered the api on the play developer console, created and loaded the apple certificates on my server. When I test the app on a device it successfully registers for push notifications. However my issue comes in with trying to actually send a push notification. I want it to send through PHP. I use this code which is taken straight from the developer guide. However this does not work... Is it a problem with my code or did I do something wrong in the enabling push notifications process.
<?php
include("config.php");
$args = http_build_query(array( 'certPassword' => 'XXXXXXXX', 'cert'
=>
'http://kyven.co.za/mibrand/certificate/XXXX.p12',
'production' => false,
'device' => null, 'packageName' => 'za.co.bonyelo.mibrand', 'email'
=>
'kyri88#gmail.com', 'type' => 1,
'auth' => 'XXXXXXXXXXXXXXXXXXXXXXXXXX',
'body' => 'Test'));
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content'
=> $args
) );
$context = stream_context_create($opts);
$response = file_get_contents("https://codename-
one.appspot.com/sendPushMessage", false, $context);
die(json_encode($response));
?>
Got it. This is the code I used
<?php
include("config.php");
$args = http_build_query(array('token' => 'XXXXXXXXXXXXXXXXXXX',
'certPassword' => 'XXXXXXXX', 'cert' =>
'http://XXXXXXX/XXXXX/XXXXX/Certificates.p12',
'production' => false,
'device' => 'cn1-ios-XXXXXXXXXXXXXXXXXXXXXXXX',
'packageName' => 'za.co.bonyelo.mibrand', 'email' =>
'kyri88#gmail.com', 'type' => 1,
'auth' => 'XXXXXXXXXXX',
'body' => 'EAT MY BALLS'));
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $args
) );
$context = stream_context_create($opts);
$response =
file_get_contents("https://push.codenameone.com/push/push", false,
$context);
die(json_encode($response));
?>

Bigcommerce API - Creating Webhooks - Invalid Header

I'm making small steps into this project I am working on. Now creating and registering a webhook. I'm getting the below response:
400 - Invalid Header
I have tried the following code:
// Send a request to register a web hook
$http2 = new Client('https://api.bigcommerce.com', array(
'request.options' => array(
'exceptions' => false,
'headers' => array(
'X-Auth-Client' => $client_id,
'X-Auth-Token' => $access_token,
'Content-Type' => 'application/json',
'X-Custom-Auth-Header' => $access_token,
)
)
));
$request = $http2->post('/'.$store_hash.'/v2/hooks', null, array(
'scope' => 'store/order/*',
'destination' => 'https://example.com/process_order.php',
'is_active' => true
));
$response = $request->send();
$body = $response->getBody(true);
var_dump($body);
echo '<p>Status Code: ' . $response->getStatusCode() . '</p>';
... and
// Send a request to register a web hook
$http2 = new Client('https://api.bigcommerce.com', array(
'request.options' => array(
'exceptions' => false,
'headers' => array(
'X-Auth-Client' => $client_id,
'X-Auth-Token' => $access_token,
'Content-Type' => 'application/json',
)
)
));
$request = $http2->post('/'.$store_hash.'/v2/hooks', null, array(
'scope' => 'store/order/*',
'headers' => array(
'X-Custom-Auth-Header' => $access_token,
),
'destination' => 'https://example.com/process_order.php',
'is_active' => true
));
$response = $request->send();
$body = $response->getBody(true);
var_dump($body);
echo '<p>Status Code: ' . $response->getStatusCode() . '</p>';
I am working with the documentation here:
https://developer.bigcommerce.com/api/stores/v2/webhooks#create-a-hook
However, I can't seem to work out what {secret_auth_password} is as well? The documentation doesn't explain this. I am sending the Client ID and Client Header as part of the headers as well.
Still getting Invalid Header as a response.
I am using Guzzle.
Can anyone assist me on this please?
I have finally worked out what I did wrong after numerous attempts.
Answer: send the data in JSON format.
Resolved Code:
// Send a request to register a web hook
$http3 = new Client('https://api.bigcommerce.com', array(
'request.options' => array(
'exceptions' => false,
'headers' => array(
'X-Auth-Client' => $client_id,
'X-Auth-Token' => $access_token,
'Content-Type' => 'application/json',
'Accept' => 'application/json',
)
)
));
$request = $http3->post('/'.$store_hash.'/v2/hooks', null, json_encode(array(
'scope' => 'store/order/statusUpdated',
'destination' => 'https://example.com/process_order.php',
)));
$response = $request->send();

Categories