@simonbackx/paynl-node
Version:
Simple PayNL SDK for Node.js that uses promises and no singletons
199 lines • 7.88 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.Paynl = exports.PaynlError = void 0;
const tslib_1 = require("tslib");
const https_1 = tslib_1.__importDefault(require("https"));
const TransactionStart_1 = require("./interfaces/TransactionStart");
const StartResult_1 = require("./interfaces/StartResult");
const TransactionResult_1 = require("./interfaces/TransactionResult");
class PaynlError extends Error {
}
exports.PaynlError = PaynlError;
/**
*
* Contains the configurations for transactions.
*/
class Paynl {
constructor(config) {
var _a;
this.hostname = "rest-api.pay.nl";
this.apiToken = config.apiToken;
this.serviceId = config.serviceId;
this.verbose = (_a = config.verbose) !== null && _a !== void 0 ? _a : false;
}
/**
* Generate the url of the API to call
*/
getUrl(controller, action, version) {
let url = "/v" + version;
url += "/" + controller;
url += "/" + action;
url += "/json";
return url;
}
/**
* Checks if the result is an error (there are many ways the api can return an error)
*/
isError(body) {
if (body["status"] && body["status"] == "FALSE") {
return body["error"];
}
if (body["request"] && body["request"]["result"] && body["request"]["result"] == "0" && body["request"]["errorId"] && body["request"]["errorMessage"]) {
return body["request"]["errorId"] + " " + body["request"]["errorMessage"];
}
return false;
}
objectToQueryString(obj) {
const str = [];
// eslint-disable-next-line no-prototype-builtins
for (const p in obj)
if (obj.hasOwnProperty(p)) {
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
}
return str.join("&");
}
/**
* Do a post request on the API.
*/
post(controller, action, version, data = {}, type = "json") {
return new Promise((resolve, reject) => {
// Append credentials in body
data["token"] = this.apiToken;
data["serviceId"] = this.serviceId;
let jsonData;
if (type == "json") {
jsonData = JSON.stringify(data);
}
else {
jsonData = this.objectToQueryString(data);
}
if (this.verbose) {
console.log(jsonData);
}
const req = https_1.default.request({
hostname: this.hostname,
path: this.getUrl(controller, action, version),
method: "POST",
headers: {
"Content-Type": type == "json" ? "application/json" : "application/x-www-form-urlencoded",
"Content-Length": jsonData.length,
},
timeout: 10000,
}, (response) => {
if (this.verbose) {
console.log(`statusCode: ${response.statusCode}`);
console.log(`HEADERS: ${JSON.stringify(response.headers)}`);
}
const chunks = [];
response.on("data", (chunk) => {
chunks.push(chunk);
});
response.on("end", () => {
try {
if (!response.statusCode) {
reject(new Error("Unexpected order of events"));
return;
}
const body = Buffer.concat(chunks).toString();
if (this.verbose) {
console.log(body);
}
let json;
try {
json = JSON.parse(body);
}
catch (error) {
if (this.verbose) {
console.error(error);
}
// invalid json
if (response.statusCode < 200 || response.statusCode >= 300) {
if (body.length == 0) {
console.error(response.statusCode);
reject(new PaynlError("Status " + response.statusCode));
return;
}
console.error(response.statusCode + " " + body);
reject(new PaynlError(body));
return;
}
else {
// something wrong: throw parse error
reject(error);
return;
}
}
if (response.statusCode < 200 || response.statusCode >= 300) {
if (this.isError(json) !== false) {
reject(new PaynlError(this.isError(json)));
return;
}
reject(new PaynlError(response.statusCode + " " + response.statusMessage));
return;
}
if (this.isError(json) !== false) {
reject(new PaynlError(this.isError(json)));
return;
}
resolve(json);
}
catch (error) {
if (this.verbose) {
console.error(error);
}
reject(error);
}
});
});
// use its "timeout" event to abort the request
req.on("timeout", () => {
req.abort();
});
req.on("error", (error) => {
if (this.verbose) {
console.error(error);
}
reject(error);
});
req.write(jsonData);
req.end();
});
}
async startTransaction(options) {
// Basic validation for non TypeScript environments
if (!options.amount) {
throw new Error("Amount is not set or 0");
}
if (!options.returnUrl) {
throw new Error("returnUrl is not set");
}
if (!options.ipAddress) {
throw new Error("ipAddress is not set");
}
const startData = new TransactionStart_1.TransactionStart(options);
const result = await this.post("transaction", "start", 8, startData.getForApi());
return new StartResult_1.StartResult(result);
}
async getTransaction(transactionId) {
const response = await this.post("transaction", "info", 8, { transactionId: transactionId });
response["transactionId"] = transactionId;
return new TransactionResult_1.TransactionResult(response);
}
async getTransactionDetails(transactionId) {
const response = await this.post("transaction", "details", 14, { transactionId: transactionId });
response["transactionId"] = transactionId;
return response;
}
async addInvoice(invoiceData) {
return await this.post("Alliance", "addInvoice", 6, invoiceData);
}
/**
* Request all the available payment methods and settings of the current merchant / service
*/
async getService() {
const result = await this.post("Transaction", "getService", 12, {});
return result;
}
}
exports.Paynl = Paynl;
//# sourceMappingURL=Paynl.js.map
;