0

I'm attempting to make a POST request to an API. I've created a javascript file in my theme and i have tried two approaches so far:

Approach 1:

$.ajax({
        headers:{  
            "Content-Type":"application/json"               
        },   
        data:{
            "command": "request",
            "data": {
                "api_key": "my_api_key",
                "api_username": "my_api_username",
                "vendor_type": 2,
                "from": {
                  "from_name": "",
                  "from_lat": "",
                  "from_long": "",
                  "from_description": ""
                },
                "to": {
                  "to_name": customerLocation,
                  "to_lat": cityLat,
                  "to_long": cityLng,
                  "to_description": ""
                },
                "recepient": {
                    "recepient_name": name,
                    "recepient_phone": phone,
                    "recepient_email": email,
                    "recepient_notes": ""
                },
                "delivery_details": {
                  "pick_up_date": pickupdate,
                  "collect_payment": {
                    "status": false,
                    "pay_method": 0,
                    "amount": amountTotal
                  },
                                      "return": true,
             "note": " Sample note",
              "note_status": true,
              "request_type": "quote"
            }
            },
            "request_token_id": requestToken
            },
        type: 'POST',
        url:"https://apitest.sendyit.com/v1/",
        success: function(response){
           console.log('success');
           console.log(response);
        },
        error: function(response){
            console.log('error');
            console.log(response);
        }
    });

The above code will not return a response payload from the API as any call will be blocked because of CORS(Cross-Origin Resource Sharing)

Approach 2

I then attempt to pass the endpoint to my functions.php file as follows:

//make api call to sendy
function foo() 
{
     echo 'https://apitest.sendyit.com/v1/';
}
add_action('wp_ajax_foo', 'foo' );
add_action('wp_ajax_nopriv_foo', 'foo' );

I declare an ajaxUrl variable in my theme's header.php file:

<script type="text/javascript">
var ajaxUrl = "<?php echo admin_url('admin-ajax.php'); ?>";
</script>

Then format my Ajax call as shown below:

$.ajax({
        headers:{  
            "Content-Type":"application/json"               
        },   
        data:{
            "action": 'foo',
            "command": "request",
            "data": {
                "api_key": "my_api_key",
                "api_username": "my_api_username",
                "vendor_type": 2,
                "from": {
                  "from_name": "",
                  "from_lat": "",
                  "from_long": "",
                  "from_description": ""
                },
                "to": {
                  "to_name": customerLocation,
                  "to_lat": cityLat,
                  "to_long": cityLng,
                  "to_description": ""
                },
                "recepient": {
                    "recepient_name": name,
                    "recepient_phone": phone,
                    "recepient_email": email,
                    "recepient_notes": ""
                },
                "delivery_details": {
                  "pick_up_date": pickupdate,
                  "collect_payment": {
                    "status": false,
                    "pay_method": 0,
                    "amount": amountTotal
                  },
                                      "return": true,
             "note": " Sample note",
              "note_status": true,
              "request_type": "quote"
            }
            },
            "request_token_id": requestToken
            },
        type: 'POST',
        url:ajaxurl,
        success: function(response){
           console.log('success');
           console.log(response);
        },
        error: function(response){
            console.log('error');
            console.log(response);
        }
    });

But this is giving me a 400 (Bad Request) error.

I should mention that i have correctly set up my javascript file in the functions.php file:

wp_enqueue_script('sendy', get_template_directory_uri() . '/assets/js/sendy.js', array('jquery'));
wp_localize_script('sendy', 'wc_checkout_params', array('ajaxurl' => admin_url('admin-ajax.php')));

Would like therefore to request for assistance in setting up my POST endpoint.

1

You got the error 400 Bad Request because the Content-Type header is application/json:

$.ajax({
  headers:{
    "Content-Type":"application/json"
  },
  data: {
    ...
  },
  ...
});

And when the request content is a JSON string, the $_REQUEST['action'] which WordPress uses to identify the proper AJAX action (which is foo in your code) is not available (i.e. it's a NULL).

So based on your code, and with your second approach, you can just omit the headers part.

$.ajax({
  // No "headers" here.
  data: {
    ...
  },
  ...
});

UPDATE

You can use wp_remote_post() to make the external API request from the foo() function; example:

function foo() {
    if ( empty( $_POST['data'] ) ) {
        wp_die( 'Missing data' );
    }

    $post_data = wp_unslash( $_POST['data'] );
    $post_data['command'] = wp_unslash( $_POST['command'] );
    $post_data['request_token_id'] = wp_unslash( $_POST['request_token_id'] );

    $api_url = 'https://apitest.sendyit.com/v1/';
    $response = wp_remote_post( $api_url, array(
        // Set the Content-Type header.
        'headers' => array(
            'Content-Type' => 'application/json',
        ),
        // Set the request payload/body.
        'body'    => json_encode( $post_data ),
    ) );

    $res_body = wp_remote_retrieve_body( $response );
    echo $res_body;

    wp_die();
}
  • You're right Sally. Thanks. Now this opens up a different discussion.. The response now returned after removing the header is the endpoint string i.e. apitest.sendyit.com/v1. The entire purpose of passing the endpoint in the functions.php file is to avoid passing it in the ajax(which will result in a CORS issue). And i should mention that the data being passed to the API are obtained using jquery. So how do I pass the data this way and use the endpoint to receive the required response payload? – suo Jan 26 at 16:11
  • Check the updated answer. – Sally CJ Jan 26 at 17:54
  • Excellent. I now make a successful API call and get the data i need. The last bit it grabbing the required value, in this case the shipping cost, and updating the checkout page using ajax. i've been looking around and the most common way i've seen is $( document.body ).bind( 'update_checkout' ); but doesn't seem to work. i'm passing it in my success callback as: success: function(response){ $( document.body ).bind( 'update_checkout' ); var responseData = JSON.parse(''+response+''); ... but not getting the page reload. any idea how i can get this last bit to work? thanks – suo Jan 27 at 13:23
  • I can only say that you're not binding any callback to the update_checkout event - it should look like $( document.body ).bind( 'update_checkout', function(){ ...your code... } ). But I have no idea of the relation between the update_checkout and the things you want to do. And if you need further help, you can ask a question on Stack Overflow. (I'd be happy to help, but please do not ask new questions via the comments) – Sally CJ Jan 27 at 18:00
  • ah ok. will do just that as i'm currently stuck. thankyou so much for your input – suo Jan 28 at 2:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.