-
Notifications
You must be signed in to change notification settings - Fork 7
/
index.js
155 lines (127 loc) · 4.8 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
var https = require('https')
, parser = require('xml2js')
, fs = require('fs')
, builder = new parser.Builder({headless: true});
var responseMap = {
createCustomerProfileFromTransaction: 'createCustomerProfile'
}
module.exports = (function() {
var AuthorizeRequest = function(options) {
options = options || {};
this.sandbox = options.sandbox || false;
this.api = options.api || '';
this.key = options.key || '';
this.cert = options.cert || '';
if (!!this.cert) {
this.cert = fs.readFileSync(this.cert);
}
this.LIVE_URL = {
host: 'api.authorize.net',
path: '/xml/v1/request.api'
};
this.SANDBOX_URL = {
host: 'apitest.authorize.net',
path: '/xml/v1/request.api'
};
this.validationMode = 'none';
this.refId = '';
}
/**
* @return string
*/
AuthorizeRequest.prototype.getPostUrl = function() {
return !!this.sandbox ? this.SANDBOX_URL : this.LIVE_URL;
}
AuthorizeRequest.prototype.send = function(action, xml, options) {
xml = typeof xml == 'object' ? builder.buildObject(xml).replace('<root>', '').replace('</root>', '') : xml;
var callback = arguments[arguments.length - 1], string = ''
, originalValidationMode = this.validationMode; // In order to reset after the transaction
options = options || {};
// Rule set by Authorize
if (action === "validateCustomerPaymentProfile") {
this.validationMode = (!!this.sandbox ? 'testMode' : 'liveMode');
}
// Rule set by Authorize
if (action === "createCustomerProfileRequest" && xml.match('/<payment>/') === null) {
this.validationMode = 'none';
}
string = '<?xml version="1.0" encoding="utf-8"?><' + action + 'Request xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">';
string += '<merchantAuthentication><name>' + this.api + '</name><transactionKey>' + this.key + '</transactionKey></merchantAuthentication>';
if (!!this.refId) {
string += '<refId>' + this.refId + '</refId>';
}
if (!!xml) {
string += xml;
}
if (!!this.validationMode && this.validationMode !== "none") {
string += '<validationMode>' + this.validationMode + '</validationMode>';
}
if (!!options && !!options.extraOptions) {
string += '<extraOptions><![CDATA[' + options.extraOptions + ']]></extraOptions>';
}
string += '</' + action + 'Request>';
this.validationMode = originalValidationMode; // Reset since we no longer need it to build the XML..
var url = this.getPostUrl();
var content = new Buffer(string, 'utf-8');
var req = https.request({
host: url.host,
path: url.path,
method: 'POST',
cert: this.cert,
rejectUnauthorized: options.rejectUnauthorized || false,
requestCert: options.requestCert || true,
agent: options.agent || false,
headers: {
'Content-Length': content.length,
'Content-Type': 'text/xml'
}
});
// This is the response received from Authorize.net
var responseAction = responseMap[action] || action;
req.write(content);
req.on('error', function(err) {
callback(err);
})
.on('response', function(res) {
if (!!res.connection.authorizationError) {
return callback(new Error('Connection authorization error: ' + res.connection.authorizationError));
}
var data = "";
res.on('data', function(dataStream) {
data += dataStream.toString();
});
res.on('end', function () {
parser.parseString(data, {object: true, explicitArray: false}, function (err, response) {
if (response.ErrorResponse) {
return callback(new AuthNetError(response.ErrorResponse));
}
if (!response[responseAction + 'Response']) {
return callback(new Error('Unexpected response: ' + data));
}
var keys = Object.keys(response[responseAction + 'Response']).filter(function(k) { return k !== 'xmlns:xsi' && k !== 'xmlns:xsd' && k !== 'xmlns'; })
, length = keys.length
, i = 0
, values = {};
for (i = 0; i < length; ++i) {
values[keys[i]] = response[responseAction + 'Response'][keys[i]];
}
var resultCode = values.messages.resultCode.toUpperCase();
if (resultCode != "OK" && resultCode != "SUCCESS") {
return callback(new AuthNetError(values));
}
callback(null, values);
});
});
});
req.end();
};
var AuthNetError = function(response) {
this.message = 'Authorize.net error: ' + response.messages.message.text;
this.code = response.messages.message.code;
this.response = response;
this.stack = (new Error()).stack;
};
AuthNetError.prototype = new Error();
AuthNetError.prototype.name = 'AuthNetError';
return AuthorizeRequest;
})();