POST request in a route

I’m trying to get a JSON response back from an API in a route using remote::post so that i can pick up the response using javascript fetch(). This is to avoid CORs issues. Trouble is, i keep getting the sites error page when hitting the route. Am i doing it wrong?

array(
  'pattern' => 'createsession.json',
  'method' => 'POST',
  'action'  => function() {

    $postData = array(
        "apiOperation" => "CREATE_CHECKOUT_SESSION",

        "order" => array(
          "amount" => "5",
          "currency" => "USD",
          "description" => "Donation",
        ),

        "interaction" => array(
          "operation" => 'PURCHASE',
          "returnUrl" => "https://example.com",
            "merchant" => array(
              "name:" => "NAME",
                  "address" => array(
                    "line1" => site()->find('address')->streetaddress()->value(),
                    "line2" => site()->find('address')->addresslocality()->value()
                  )
            )
        )
    );

    remote::post($url, $postData);

  }
),

What is $url in your example? That variable is not defined…

So your sending a POST request to your route and then you want your route to send another post request to somewhere else. But your route doesn’t return anything?

Oops yes… it should return somthing. Also I also I’m missing basic auth headers. How do i add those?

I just need a JSON respnose to show up, and i need to able to set the orderID and and amount from the url parameters. Not sure how to do that.

http://mysites.com/createsession.json&amount=5&id-1003

Something like that, so that when i pick up details in javascript, i can seend them through to the route.

Probably in the params array of the remote::post() method, see

So you would add a headers array to your second argument.

But honestly, I’m not quite sure what you are doing there.

Do you want your route to send a request, then wait for the response and then return that? Because currently, your route only sends a post request, nothing else.

Yes, i want to return the response body, becuase i need the information sent back in some javascript in a template. Im using a route to hit the API becuase i was getting CORs errors doing it directly from javascript fetch()… so im trying to use the route as a proxy since Curl wont cause those errors.

So instead, im going to call the route above from fetch() in javascript.

Ok, but you don’t send any data to the route, don’t you? So the route itself can be called with a GET request?

I need to tell the curl request an order ID, and an order amount. So, yes, i will need to pick those up in the route to use in the request. I havent got that far, im just trying to get a valid response back with hard coded values for the minute.

Ok, so the POST request to the route makes sense.

Next, you send your remote::post(), but the part after that is missing. Because as a next step, you have to wait for the response from that request if successful, then return that response as JSON to your Javascript.

Yes… the response from the API looks like this…

{
    "merchant": "example",
    "result": "SUCCESS",
    "session": {
        "id": "SESSION0002228153621F31874537F2",
        "updateStatus": "SUCCESS",
        "version": "7662bc6501"
    },
    "successIndicator": "b74e1e19f1a64799"
}

Basically i need to pick up the session ID from that json before i can configure a checkout lightbox script on a dontation page.

So i dont need to turn the response into JSON, because it already is.

But you don’t have URL parameters if you send a post request, but post data.

Im confused. when i hit the route from javascript, i need to send the route 2 bits of information, the order ID and the order Amount… so that i can pass those through to the remote::post()

This stuff is not something im used to doing… so im kind of not familiar with the tecnical terms.

Yes, but since your route is a post route, it expected this information in the post data. Are you actually sending a post request from your Javascript with this data?

Not yet but i will be later.

Basically its this…

  1. Dontation page on website, click event on a button that triggers the fetch request and picks up the donation amount from a form field, together with a unique order ID.
  2. Fetch hits the route and gets a response back as json
  3. Use the response data in the rest of the javasvript in the template

Could you post this fetch request, please?

If you don’t hit your route with a POST request but with a GET request, you will end up with an error, because your route only listens to POST requests…

See… those are the technical terms im not totally familiar with :slight_smile: Only generally.

I havent written the fetch request, its still the old one that hits the api directly and gets corse errors.

But its along thse lines…

// Replace ./data.json with your JSON feed
fetch('./data.json')
  .then(response => {
    return response.json()
  })
  .then(data => {
    // Work with JSON data here
    console.log(data)
  })
  .catch(err => {
    // Do something for an error here
  })

Ok, that is a get request, it will return an error.

You need to send something like this:

fetch("./data.json'",
{
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    method: "POST",
    body: JSON.stringify({a: 1, b: 2}) // the body would contain the data you want to send to the route
})

With 'method' => 'POST' you tell your route: listen to POST requests only (this has nothing to do with what you actually do inside your route).

Thanks. I think i understand. If i wanted to hit the route with the body data in the browsers address bar so i can see it works before put the fetch code together, how would i structure the URL?

Use a tool or browser add-on that allows you to send a post request with the data, you can’t put a POST address into a browser address bar.

Ah ok… I used the Rested app to check my credentials where ok and the API was letting me. So i just use that again… i see :slight_smile:

This is the worst saturday…

Ah ha! ok im starting to get somewhere. The routes working, and hitting the API ok, but its responding that authorisation failed, which means there is something up with the headers… heres my route…

array(
  'pattern' => 'createsession.json',
  'method' => 'GET',
  'action'  => function() {

    $url = 'APIURL';

    $postData = array(
        'apiOperation' => 'CREATE_CHECKOUT_SESSION',

        'order' => array(
          'amount' => '5',
          'currency' => 'USD',
          'id' => 'ORDER1003',
          'description' => 'Donation',
        ),

        'interaction' => array(
          'operation' => 'PURCHASE',
          'returnUrl' => 'https://example.com',
            'merchant' => array(
              'name:' => 'NAME',
                  'address' => array(
                    'line1' => site()->find('address')->streetaddress()->value(),
                    'line2' => site()->find('address')->addresslocality()->value()
                  )
            )
        )
    );

    $params = array(
      'headers' => array(
        'Content-Type' => 'application/json;charset=ISO-8859-1',
        'Authorization' => 'Basic SECRET'
      ),
      'method' => 'POST',
      'body' => $postData,
    );

    echo remote::post($url, $params);

  }
),