Home > OS >  function for USAePay API in TWilio functions returns 504 code
function for USAePay API in TWilio functions returns 504 code

Time:11-05

I'm trying to make a post request in Twilio functions to process a charge with the USAePay gateway API but my code seems to be tripping somewhere. Any insight is appreciated. I think it may be the callback() function being in the wrong place.

I also get a a warning that buffer is depreciated, how can I work around that?

Here is my code:

exports.handler = function(context, event, callback) {
//setup dependencies
const express = require('express');
const bodyParser = require('body-parser');
const request = require('request');
const sha256 = require('sha256');

const app = express();
app.use(express.static('public'));
app.use(bodyParser.json());

//setup authorization for API request
var seed = "abcdefghijklmnop";
var apikey = "xxxxxxxxxxxxxxxxxxxxxxxx";
var prehash = apikey   seed;
var apihash = 's2/'  seed   '/'   sha256(prehash);
var authKey = new Buffer(apikey   ":"   apihash).toString('base64');
var authorization = "Basic "   authKey;

//POST endpoint for API request
app.post('/', (req, res) => {
    //setup request for API using provided info from user
    let options = {
        url: 'https://sandbox.usaepay.com/api/v2/transactions',
        method: 'POST',
        json: true,
        headers: {
            "Authorization": authorization
        },
        body: {
    "command": "cc:sale",
    "amount": "5.00",
    "amount_detail": {
        "tax": "1.00",
        "tip": "0.50"
    },
    "creditcard": {
        "cardholder": "John doe",
        "number": "4000100011112224",
        "expiration": "0919",
        "cvc": "123",
        "avs_street": "1234 Main",
        "avs_zip": "12345"
    }
        }
    };
    //make request and handle response
    request(options, (err, apiRes, body) => {
        if(err) {
            res.status(500).json({message: "internal server error"});
        }
        else{
            res.status(200).json({
                result: body.result,
                error: body.error || ""
            });
        
        }
    });
        });
        
};

CodePudding user response:

Twilio developer evangelist here.

I recommend you read up about how Twilio Functions works. You do not just import a Node application without changes. You need to export a function called handler.

The handler function is called when a request is made to the URL of the Twilio function.

The function receives three arguments, a context, an event and the callback function. The context contains environment variables amongst other things, the event contains all the parameters from an HTTP request (either query string parameters or parameters in the request body) and the callback is for returning a response.

A basic Twilio Function looks like this:

exports.handler = function (context, event, callback) {
    return callback(null, { hello: "World!" });
}

In this case, making a request to the Function's URL will receive a JSON response of { "hello": "World!" }.

Now, in your case you need to make a request to an external API as part of the request to the Function. First, I recommend you set secrets like your API Key in environment variables. They can then be accessed from the context object. Your API call will be asynchronous, so the important thing is to only call the callback function when all your asynchronous calls are finished.

Something like this might work:

const request = require("request");
const sha256 = require("sha256");

exports.handler = function (context, event, callback) {
  const seed = context.SEED;
  const apikey = context.API_KEY;
  const prehash = apikey   seed;
  const apihash = "s2/"   seed   "/"   sha256(prehash);
  const authKey = Buffer.from(apikey   ":"   apihash).toString("base64");
  const authorization = "Basic "   authKey;

  const options = {
    url: "https://sandbox.usaepay.com/api/v2/transactions",
    method: "POST",
    json: true,
    headers: {
      Authorization: authorization,
    },
    body: {
      command: "cc:sale",
      amount: "5.00",
      amount_detail: {
        tax: "1.00",
        tip: "0.50",
      },
      creditcard: {
        cardholder: "John doe",
        number: "4000100011112224",
        expiration: "0919",
        cvc: "123",
        avs_street: "1234 Main",
        avs_zip: "12345",
      },
    },
  };
  //make request and handle response
  request(options, (err, apiRes, body) => {
    if (err) {
      const response = new Twilio.Response();
      response.setStatusCode(500);
      response.appendHeader("Content-Type", "application/json");
      response.setBody({ message: "internal server error" });
      callback(null, response);
    } else {
      callback(null, {
        result: body.result,
        error: body.error || "",
      });
    }
  });
};

The request package has been deprecated for some time now, so you might want to consider updating it to something that is still maintained.

But the most important thing to do is learn how Twilio Functions work by reading the documentation.

  • Related