11

I am looking for a way to make a post request from a controller to an external url. The data being posted is a php array. The url to recieve is an ecommerce API in an external url. The post has to be done from the controller method. The url should reply with 'success', 'error', 'failure' or 'trylater' string. I have tried the following with no success:

    return Redirect::to("https://backoffice.host.iveri.com/Lite/Transactions/New/Authorise.aspx", compact($array));

I have tried curl too:

    $url = 'https://backoffice.host.iveri.com/Lite/Transactions/New/Authorise.aspx';
    //url-ify the data for the POST
    $fields_string ='';
    foreach($array as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
    rtrim($fields_string,'& ');

    //open connection
    $ch = curl_init();

    //set the url, number of POST vars, POST data
    curl_setopt($ch,CURLOPT_URL, $url);
    curl_setopt($ch,CURLOPT_POST, count($array));
    curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

    //execute post
    $result = curl_exec($ch);

    //close connection
    curl_close($ch);

Part of the array being sent is the callbacks that the API uses to responds:

'Lite_Website_Successful_url' => 'https://mydomain.com/order/'.$order_id,
'Lite_Website_Fail_url' => 'https://mydomain.com/checkout/fail',
'Lite_Website_TryLater_url' => 'https://mydomain.com/checkout/trylater',
'Lite_Website_Error_url' => 'https://mydomain.com/checkout/error'

Please let me know how to do a POST request properly with data carried with it to an external url. An ajax post from the controller too would help but I have tried with no success. But I would prefer a laravel php answer more. Thank you.

Mwirabua Tim
  • 3,894
  • 5
  • 44
  • 55

3 Answers3

8

We can use package Guzzle in Laravel, it is a PHP HTTP client to send HTTP requests.

You can install Guzzle through composer

composer require guzzlehttp/guzzle:~6.0

Or you can specify Guzzle as a dependency in your project's existing composer.json

{
   "require": {
      "guzzlehttp/guzzle": "~6.0"
   }
}

Example code of POST Request in laravel, using Guzzle is as shown below,

use GuzzleHttp\Client;
class yourController extends Controller {
public function saveApiData()
{
    $client = new Client();
    $res = $client->request('POST', 'https://url_to_the_api', [
        'form_params' => [
            'client_id' => 'test_id',
            'secret' => 'test_secret',
        ]
    ]);

    $result= $res->getBody();
    dd($result);

}

Mohammed Safeer
  • 17,481
  • 8
  • 66
  • 74
7

Let me clarify some stuff and try to point you in the right direction.

First, what you're attempting to do sounds like "making an API request from your web app". The difference in that wording in how I stated it vs yours is that it's more general.

  1. You can make an API request anywhere in your application, not necessarily in your controller (Don't be afraid to make extra classes/models for things like API calls!)
  2. I'm curious about why it "has to be" done in your controller? What's your use case?
  3. AJAX doesn't exist on the server-side (in PHP). That's purely a javascript-specific "technology" that describes javascript making a request to a URL on the client-side.

Lastly, what are you trying to do? Do you need a user to be redirected? Or do you need to make an API call and parse the result within your application?

The cURL request you've attempted should work for making an API request. That's one of the main ways of making an API request within PHP code. It won't, however, allow a user on the front-end to see that request being made and processed. With cURL (and any API request), the processing is all happening behind the scenes in your PHP (which your users can't see).

fideloper
  • 11,935
  • 1
  • 38
  • 35
  • Thank you. It has to be done from the controller because the same form that submits your log in details submits credit card details. So I have to validate input, log you in then transact and recieve, evaluate and save the API response all behind the scenes after you click submit. How could I make it simpler? – Mwirabua Tim Sep 12 '13 at 17:55
  • Sorry, the API has to respond by redirecting the user to one of the defined urls check the bottom of my edited question. – Mwirabua Tim Sep 12 '13 at 18:43
  • Cool - I think the only question then is to ask what the results of your cURL request are? Something unexpected? Are you sure their API isn't expecting you to send your user to their site via a form POST request? (Instead of an API call?) – fideloper Sep 12 '13 at 19:37
  • Yes they expect a form submission but that just posts the same way I would post an array with an API call, right? I decided to use "return Redirect::to($url.'?'.http_build_query($array));" Im redirected to a page that says "Invalid Return URL specified" meaning im testing from the wrong environment maybe. Im cant test on the right https live environment now. Im not sure if its safe to do that over https coz that reveals the transaction details on the url string.... – Mwirabua Tim Sep 13 '13 at 04:09
  • any answer to this yet? Have exact same issue with iveri and laracwl – Ben A. Hilleli Dec 05 '13 at 05:59
2

Either use CURL the way you've been trying, or check this thread for a brief answer on doing it with the Guzzle http client. Guzzle seems to be the preferred client for use with Laravel...

Call external API function from controller, LARAVEL 4

Community
  • 1
  • 1
minorgod
  • 554
  • 5
  • 7