question

icaro avatar image
icaro asked

http.request with 'application/x-www-form-urlencoded' is not working

I'm trying to implement a module very similar to the one in the Webhooks section:

//Cloud Script
var url = "https://api.yoursite.com/playfab_call/request_token";
var method = "post";
var contentBody = "grant_type=client_credentials";
var contentType = "application/x-www-form-urlencoded";
var headers = {};
Headers["client_id"] = clientId;
Headers["client_secret"] = clientSecret;

var tokenResponse =  http.request(url,method,contentBody,contentType,headers);


Here is my code:

var BOACOMPRA_URL = "https://ws.sandbox.pagseguro.uol.com.br/v2/checkout";


handlers.StartPurchaseBO = function (args) {
    var itemRef = args.Items[0];
    var item = GetCatalogItem("Coin Packs", itemRef.ItemId);


    var method = "post";
    var contentType = "application/x-www-form-urlencoded; charset=ISO-8859-1";
    var headers = {};
    var contentBody = {};
    contentBody["token"] = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
    contentBody["currency"] = 'BRL';
    contentBody["itemId1"] = item.ItemId;
    contentBody["itemDescription1"] = 'TEST';
    contentBody["itemAmount1"] = item.VirtualCurrencyPrices.RM;


    var tokenResponse =  http.request(BOACOMPRA_URL, method, contentBody, contentType, headers);
    
    return tokenResponse;
}

But it seems that playfab http.request doesn't support these arguments as you see in the log:
Error: The best overloaded method match for 'PlayFab.LogicServer.Source.PlayFabAPI.http_request(string, string, string, string, string, bool)' has some invalid arguments\n at Error (native)\n at handlers.StartPurchaseBO (2A7D-main.js:633:31)

How can I solve this issue?

Thanks,

CloudScript
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

brendan avatar image
brendan answered

The main issue in this case is the contentBody, which should be a string. Here's the full text of the example http request from the sample Cloud Script which is added as revision 1 to all new titles:

// This is a simple example of making a web request to an external HTTP API.
handlers.makeHTTPRequest = function (args, context) {
    var headers = {
        "X-MyCustomHeader": "Some Value"
    };
    
    var body = {
        input: args,
        userId: currentPlayerId,
        mode: "foobar"
    };


    var url = "http://httpbin.org/status/200";
    var content = JSON.stringify(body);
    var httpMethod = "post";
    var contentType = "application/json";


    // The pre-defined http object makes synchronous HTTP requests
    var response = http.request(url, httpMethod, content, contentType, headers);
    return { responseContent: response };
};

As you can see, the body is converted to a string via JSON.stringify before it is passed in. If you could try updating your code to make sure you perform that step, this should resolve the issue.

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

icaro avatar image
icaro answered


Okay, but now I'm getting the following error:

{"FunctionName":"StartPurchaseBO","Revision":189,"Logs":[{"Level":"Error","Message":"HTTP request error","Data":{"url":"https://ws.sandbox.pagseguro.uol.com.br/v2/checkout/?email=suporte@lojamode…01&itemDescription1=ProdutoPagSeguroI&itemAmount1=99999.99&itemQuantity1=1","method":"post","content":"","contentType":"application/x-www-form-urlencoded","headers":"","result":{"responseContent":null,"httpStatus":null,"httpStatusCode":0,"requestError":"InternalError"},"httpRequestError":"InternalError"}}],"ExecutionTimeSeconds":0.0193657,"ProcessorTimeSeconds":0,"MemoryConsumedBytes":133024,"APIRequestsIssued":1,"HttpRequestsIssued":1,"Error":{"Error":"CloudScriptHTTPRequestError","Message":"The script made an external HTTP request, which returned an error. See the Error logs for details.","StackTrace":"Error\n    at handlers.StartPurchaseBO (2A7D-main.js:640:31)"}}}

My code:

handlers.StartPurchaseBO = function (args) {
    
    var url = "https://ws.sandbox.pagseguro.uol.com.br/v2/checkout/?email=suporte@lojamodelo.com.br&token={
                {token}}&currency=BRL&itemId1=0001&itemDescription1=ProdutoPagSeguroI&itemAmount1=99999.99&itemQuantity1=1";

    var method = "post";
    var contentType = "application/x-www-form-urlencoded";
    var headers = "";
    var contentBody = "";

    var tokenResponse =  http.request(url, method, contentBody, contentType, headers);
    var code = tokenResponse.split('<code>')[1];
    code = tokenResponse.split('</code>')[0];

    return {code: code};
}

I tested the same request with Postman and it works perfectly.

capture.jpg

Thanks,


capture.jpg (72.3 KiB)
3 comments
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

brendan avatar image brendan commented ·

According to the info in the log you posted, the external service returned an error. Can you try logging the tokenResponse, to see what that service is saying about the call?

0 Likes 0 ·
icaro avatar image icaro brendan commented ·

Unfortunately, I can't logging the tokenResponse, since the http.request is throwing an exception before the method returns.

At first, I thought that the problem was with the external service, but I tested the same request using other tool(Postman) and I got the expected outcome.

0 Likes 0 ·
brendan avatar image brendan icaro commented ·

You can use a try/catch in order to get the specifics of the exception and log it. At a guess, the first thing I would recommend is moving all your POST parameters into the body of the request.

0 Likes 0 ·
icaro avatar image
icaro answered

The exception doesn't give a hint of what is the problem.

{"code":200,"status":"OK","data":{"FunctionName":"StartPurchasePagueSeguro","Revision":192,"FunctionResult":{"error":{"cloudScriptErrorCode":"CloudScriptHTTPRequestError","stack":"Error\n    at Object.__playfab_internal_v2.http_request (Script Document:205:28)\n    at Object.http.request (Script Document:241:35)\n    at handlers.StartPurchasePagueSeguro (2A7D-main.js:643:35)\n    at Object.__playfab_internal_v2.invokeFunction (Script Document:110:33)","requestInfo":{"url":"https://ws.sandbox.pagseguro.uol.com.br/v2/checkout/","method":"post","content":"{\"token\":\"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\",\"email\":\"xxxxxxx@xxxxx.com\",\"currency\":\"BRL\",\"itemId1\":\"com.bighutgames.bh18.pack_1\",\"itemDescription1\":\"Pile of Coins\",\"itemAmount1\":4.99,\"itemQuantity1\":1}","contentType":"application/x-www-form-urlencoded","headers":"","result":{"responseContent":null,"httpStatus":null,"httpStatusCode":0,"requestError":"InternalError"},"httpRequestError":"InternalError"}}},"Logs":[{"Level":"Error","Message":"HTTP request error","Data":{"url":"https://ws.sandbox.pagseguro.uol.com.br/v2/checkout/","method":"post","content":"{\"token\":\"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\",\"email\":\"xxxxxxx@xxxxx.com\",\"currency\":\"BRL\",\"itemId1\":\"com.bighutgames.bh18.pack_1\",\"itemDescription1\":\"Pile of Coins\",\"itemAmount1\":4.99,\"itemQuantity1\":1}","contentType":"application/x-www-form-urlencoded","headers":"","result":{"responseContent":null,"httpStatus":null,"httpStatusCode":0,"requestError":"InternalError"},"httpRequestError":"InternalError"}}],"ExecutionTimeSeconds":0.19606949999999998,"ProcessorTimeSeconds":0,"MemoryConsumedBytes":4294606720,"APIRequestsIssued":1,"HttpRequestsIssued":1}}

I moved the parameters to the contentBody and it didn't work.

Also, I've tested move the parameters to the contentBody in Postman tool and I got the expected output.

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

icaro avatar image
icaro answered

@Brendan ,

I created an empty php and I uploaded it to http://developer.joguedomino.com.br/server/startpayment_pagseguro.php:

<?php 
?>


And I'm requesting this php through the following code:

handlers.StartPurchasePagueSeguro = function (args) {

    var contentBody = {};

    var url = "http://developer.joguedomino.com.br/server/startpayment_pagseguro.php";

    var method = "post";
    var contentType = "application/json";
    var headers = "";

    try{
        var tokenResponse =  http.request(url, method, JSON.stringify(contentBody), contentType, headers);

        return {code: tokenResponse};
    }
    catch(e)
    {
        return {error: e};
    }
}

But I still got the same error:

{"code":200,"status":"OK","data":{"FunctionName":"StartPurchasePagueSeguro","Revision":196,"FunctionResult":{"error":{"cloudScriptErrorCode":"CloudScriptHTTPRequestError","stack":"Error\n    at Object.__playfab_internal_v2.http_request (Script Document:205:28)\n    at Object.http.request (Script Document:241:35)\n    at handlers.StartPurchasePagueSeguro (2A7D-main.js:628:35)\n    at Object.__playfab_internal_v2.invokeFunction (Script Document:110:33)","requestInfo":{"url":"http://developer.joguedomino.com.br/server/startpayment_pagseguro.php","method":"post","content":"{}","contentType":"application/json","headers":"","result":{"responseContent":null,"httpStatus":null,"httpStatusCode":0,"requestError":"InternalError"},"httpRequestError":"InternalError"}}},"Logs":[{"Level":"Error","Message":"HTTP request error","Data":{"url":"http://developer.joguedomino.com.br/server/startpayment_pagseguro.php","method":"post","content":"{}","contentType":"application/json","headers":"","result":{"responseContent":null,"httpStatus":null,"httpStatusCode":0,"requestError":"InternalError"},"httpRequestError":"InternalError"}}],"ExecutionTimeSeconds":0.0070902,"ProcessorTimeSeconds":0,"MemoryConsumedBytes":129664,"APIRequestsIssued":0,"HttpRequestsIssued":1}}

There is no server error when I try to access the same URL using other tools or chrome browser.

Note: I changed the method from post to get and got the same error.

1 comment
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

brendan avatar image brendan commented ·

Ah, I see the issue. In your original code at the top, you correctly had headers defined as a JSON object, but in the more recent code, you've switched it to be a string - I missed that in the post from yesterday. If you change it back to an object, your StartPurchasePagueSeguro handler will work fine - I just copied it to my own test project and ran it to verify.

0 Likes 0 ·

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.