How do i send a PUT request in Laravel - php

I am trying to update data through sending an http put request to ServiceDesk plus api. When using the console that comes with the system, it works well but when I try to send a request to the same api from Laravel it does not work.
request from the console below
I am trying to send a request to the same url using the code below.
private function openTicket($notification)
{
$data = json_encode(['input_data' => ['request' => ['subject' => $notification->subject,
'description' => $notification->description,
'status' => ['name' => 'Open']]]]);
$request_id = $notification->request_id;
$response = Http::withHeaders([
'technician_key' => 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX',
'Accept' => 'application/json'
])->put('http://localhost:8082/api/v3/requests/' . $request_id, $data);
dd($response);
}
and im getting an error 400 bad request.

You should not do json_encode, laravel Http module will automatically do it for you. I think your data is json_encoded twice right now.
$data = [
'input_data' => [
'request' => [
'subject' => $notification->subject,
'description' => $notification->description,
'status' => ['name' => 'Open']
]
]
]);
$request_id = $notification->request_id;
$response = Http::withHeaders([
'technician_key' => 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX',
'Accept' => 'application/json'
])->put('http://localhost:8082/api/v3/requests/' . $request_id, $data);
dd($response);
I just noticed. From the documentation you provided in the screenshot, the input_data nesting level in the array should not exist
$data = [
'request' => [
'subject' => $notification->subject,
'description' => $notification->description,
'status' => ['name' => 'Open']
]
]);

I managed to find a solution and it is as follows,
private function openTicket($notification): bool
{
$data = json_encode(['request' => ['subject' => $notification->subject,
'description' => $notification->description,
'status' => ['name' => 'Open']]]);
$request_id = $notification->request_id;
$response = Http::withHeaders([
'technician_key' => 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX',
'Content-Type' => 'application/x-www-form-urlencoded'
//added asForm() before put
])->asForm()->put('http://localhost:8082/api/v3/requests/' . $request_id, [
'input_data' => $data
]);
if ($response->status() == 200) {
return true;
}
return false;
}
I added asForm() before the put function. This is because asForm() indicates that the request contains form parameters. I also modified the $data object from
$data = json_encode(['input_data' => ['request' => ['subject' => $notification->subject,
'description' => $notification->description,
'status' => ['name' => 'Open']]]]);
to
$data = json_encode(['request' => ['subject' => $notification->subject,
'description' => $notification->description,
'status' => ['name' => 'Open']]]);
Then it worked as i had expected.

Related

How to make PayPalCheckout return value by post method?

I am using PayPalCheckoutSdk library following the examples, I have the following:
<?php
require __DIR__ . '/PayPalCheckout/vendor/autoload.php';
use PayPalCheckoutSdk\Core\PayPalHttpClient;
use PayPalCheckoutSdk\Core\SandboxEnvironment;
$clientId = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$clientSecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$environment = new SandboxEnvironment($clientId, $clientSecret);
$client = new PayPalHttpClient($environment);
$invoiceNumber = uniqid();
$items = array();
$items[0] = [
'name' => 'HTML5',
'description' => 'Video streaming service',
'type' => 'SERVICE',
'sku' => 'sku03',
'unit_amount' =>
[
'currency_code' => 'USD',
'value' => '90.00',
],
'quantity' => '1',
'category' => 'DIGITAL_GOODS',
];
$new_item = [
'name' => 'CSS3',
'description' => 'Video streaming service',
'type' => 'SERVICE',
'sku' => 'sku02',
'unit_amount' =>
[
'currency_code' => 'USD',
'value' => '45.00',
],
'quantity' => '2',
'category' => 'DIGITAL_GOODS',
];
array_push($items , $new_item);
use PayPalCheckoutSdk\Orders\OrdersCreateRequest;
$request = new OrdersCreateRequest();
$request->prefer('return=representation');
$request->body = [
'intent' => 'CAPTURE',
'application_context' => [
'brand_name' => 'COMPANY',
'locale' => 'us-US',
'user_action' => 'PAY_NOW',
"cancel_url" => "http://localhost/PayPal/cancel.php",
"return_url" => "http://localhost/PayPal/return.php",
'landing_page' => 'BILLING',
],
'purchase_units' => [0 => [
'reference_id' => $invoiceNumber,
'amount' => [
'currency_code' => 'USD',
'value' => '160.00',
'breakdown' => [
'item_total' => [
'currency_code' => 'USD',
'value' => '180.00',
],
'shipping_discount' => [
'currency_code' => 'USD',
'value' => '20.00',
],
],
],
'items' =>
$items,
]],
];
try {
$response= $client->execute($request);
if ($response->statusCode == 201){
for ($i = 0; $i < count($response->result->links); ++$i){
$link = $response->result->links[$i];
if ($link->rel =='approve') {
header("location: $link->href");
}
}
} else {
exit(1);
}
} catch (HttpException $ex) {
echo $ex->statusCode;
print_r($ex->getMessage());
}
?>
I am receiving the data by get method print_r($_REQUEST);:
Array ( [token] => 3JX899952R0552721 [PayerID] => J95XSJRX4WXVS
And, that information is processed in the file return.php which has the following code: https://ideone.com/ncVjIt
I would like to be able to receive the information but by post method, what configurations should I make so that the data is sent by post and not by get?
As explained in comments, you can't change the redirect method back from PayPal. It will always be a GET string appended to your return_url.
However, the ideal and recommended solution is to not use any redirects. At all. Instead, use the PayPal-Checkout-SDK you have to make two routes on your server, one for 'Create Order' and one for 'Capture Order', documented here, that return only JSON data (no HTML or text). The latter one should (on success) store the payment details in your database before it does the return (particularly purchase_units[0].payments.captures[0].id, the PayPal transaction ID)
Pair these two JSON-only routes with the following approval flow that does not use any redirects, and instead keeps your site loaded in the background (lightboxed) at all times during payment approval: https://developer.paypal.com/demo/checkout/#/pattern/server

How do I pass apikey and other keys to header in guzzle 6.3?

I have a simple registration form that the user can register in my app, now I want to send submitted data to another service.
First I test my request using postman as follows using a raw option in a postman panel.
Api url : app3.salesmanago.pl/api/contact/upsert
JSON DATA:
{
"clientId":"w2ncrw06k7ny45umsssc",
"apiKey":"ssssj2q8qp4fbp9qf2b8p49fz",
"requestTime":1327056031488,
"sha":"ba0ddddddb543dcaf5ca82b09e33264fedb509cfb4806c",
"async" : true,
"owner" : "adam#rce.com",
"contact" : {
"email" : "test-1#konri.com",
"name" : "Test",
"address":{
"streetAddress":"Brzyczynska 123",
}
}
}
UPDATE I get the following success result
{
"success": true,
"message": [],
"contactId": "b52910be-9d22-4830-82d5-c9dc788888ba",
"externalId": null
}
Now using guuzle htpp request in laravel
protected function create(array $data)
{
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
$client = new client();
$current_timestamp = Carbon::now()->timestamp;
try {
$request = $client->post('app3.salesmanago.pl/api/contact/upsert', [
\GuzzleHttp\RequestOptions::HEADERS => array(
'debug' => true,
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'clientId' => 's255hncrw06k7ny45umc',
'apiKey' => 'sj2q8rt5qp4fbp9qf2b8p49fz',
'sha' => 'ba0br45543dcaf5ca82b09e33264fedb509cfb4806c',
'requestTime' => $current_timestamp,
'owner' => 'adwamtrw#fere.com',
'http_error' => true
),
\GuzzleHttp\RequestOptions::JSON => [
'form_params' => [
'name' => $data['name'],
'email' => $data['email'],
],
],
]);
}
catch (GuzzleHttp\Exception\ClientException $e) {
$response = $e->getResponse();
$responseBodyAsString = $response->getBody()->getContents();
}
$status = $request->getStatusCode();
$response = $request->getBody();
$r = json_decode($response);
dd($r);
dd($status, $r );
return $user;
}
When I run my app and send the form data I get this using the same data as in postman I get this
{#306 ▼
+"success": false
+"message": array:1 [▼
0 => "Not authenticated"
]
+"contactId": null
+"externalId": null
}
It seems like my API key and other header data are not passed to the header as required,
Can someone tell me what am I doing wrong here?
Maybe something like this. Notice that according to the API some values should be passed as headers (Accept, and Content-Type -commonly used as headers, btw-), and other values as part of the body. This is the case of the authentication values like clientId and apiKey.
I don't have guzzle 6 installed at hand but you can try and modify the code to include that data not in the headers section of the request but in the body:
$request = $client->post('app3.salesmanago.pl/api/contact/upsert', [
\GuzzleHttp\RequestOptions::HEADERS => array(
'debug' => true,
'Accept' => 'application/json',
'Content-Type' => 'application/json',
),
\GuzzleHttp\RequestOptions::JSON => [
'form_params' => [
'name' => $data['name'],
'email' => $data['email'],
'clientId' => 's255hncrw06k7ny45umc',
'apiKey' => 'sj2q8rt5qp4fbp9qf2b8p49fz',
'sha' => 'ba0br45543dcaf5ca82b09e33264fedb509cfb4806c',
'requestTime' => $current_timestamp,
'owner' => 'adwamtrw#fere.com',
'http_error' => true
],
],
]);
I'm not sure about the 'form_params' in under the RequestOptions::JSON, but mabye you can put the values directly under RequestOptions::JSON.
Just FYI, not sure what Laravel you're using but there's now The Laravel HTTP client which make this sooo much easier.
$response = Http::withHeaders([
'Accept' => 'application/json, application/json',
'Content-Type' => 'application/json',
'clientId' => 'dd2ncrw06k7ny45umce',
'apiKey' => 'ddjdd2q8qp4fbp9qf2b8p49fdzd',
'sha' => ' wba0b543dcaf5ca82b09e33264fedb4509cfb4806ec',
"requestTime" => $current_timestamp,
"owner" => "testemail#wp.com",
])->post('app3.salesmanago.pl/api/contact/upsert', [
'name' => $data['name'],
'email' => $data['email'],
]);
if($response->successful()){
dd($response->json())
}else{
// handle yo errors
}

Post data and file using Guzzle - PHP & Laravel

I am using guzzle 6.3 to post a file along with some data to my api built on laravel 5.5. When i post the data, i am not able to get the data sent to the api except the file posted.
Client Side
$client = new Client([
'headers' => [ 'Content-Type' => 'application/json' ]
]);
$response = $client->request('POST',$url, [
'multipart' => [
[
'name' => 'body',
'contents' => json_encode(['documentation' => 'First Doc', 'recipient' => ['78011951231']]),
'headers' => ['Content-Type' => 'application/json']
],
[
'name' => 'file',
'contents' => fopen('/path/public/media/aaaah.wav', 'r'),
'headers' => ['Content-Type' => 'audio/wav']
],
],
]);
echo($response->getBody()->getContents());
API Controller
if (($Key)) {
return response()->json([
'status' => 'success',
'documenation' => $request->get('documentation'),
'recipient' => $request->get('recipient'),
'file' =>$request->get('file'),
'media'=>$request->hasFile('file')
]);
}
Response
{"status":"error","documentation":null,,"recipient":null,"file":null,"media":true}
Why am i getting NULL returned for the data that i am posting? Could it be because of the file that i am posting ?

Why is Guzzle POST showing this foreach error?

I am using
"guzzlehttp/guzzle": "^6.3"
and I am running
$client = new \GuzzleHttp\Client([
'base_uri' => 'http://myapp.loc',
'headers' => [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
]
]);
Then
$response = $client->post('/api/books', [
'json' => [
'bookId' => '123',
'title' => 'My Random Test Book',
'author' => 'Test Author'
]
]);
But I get
GuzzleHttp\Exception\ClientException : Client error: POST http://myapp.loc/api/books resulted in a 404 Not Found response:
Invalid argument supplied for foreach()
If I use the same route and data in Postman everything works, so the route and method is ok.
I have tried also
$response = $client->post('/api/books', [
'headers' => [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'body' => json_encode([
'bookId' => '123',
'title' => 'My Random Test Book',
'author' => 'Test Author'
])
]);
but it returns the same foreach error.
Any ideas on why Guzzle is showing this foreach error?
Digging a bit into this with Xdebug, the error arises from \GuzzleHttp\Psr7\Stream at the fread point
public function read($length)
{
...
$string = fread($this->stream, $length);
So the solution was to form the request like:
$response = $client->request('POST', 'http://myapp.loc/api/books', [
'form_params' => [
'parameters' => json_encode([[
'bookId' => '123',
'title' => 'My Random Test Book',
'author' => 'Test Author'
]])
]
]);

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
]);

Categories