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 || ""
});
}
});
});
};
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.