exact4r 0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/certs/equifax_ca.cer +19 -0
- data/certs/exact.cer +18 -0
- data/doc/classes/EWS/Transaction/Request.html +488 -0
- data/doc/classes/EWS/Transaction/Response.html +280 -0
- data/doc/classes/EWS/Transaction/Transporter.html +251 -0
- data/doc/created.rid +1 -0
- data/doc/files/README.html +230 -0
- data/doc/files/lib/ews/transaction/mapping_rb.html +108 -0
- data/doc/files/lib/ews/transaction/request_rb.html +101 -0
- data/doc/files/lib/ews/transaction/response_rb.html +101 -0
- data/doc/files/lib/ews/transaction/transporter_rb.html +108 -0
- data/doc/files/lib/exact4r_rb.html +113 -0
- data/doc/fr_class_index.html +29 -0
- data/doc/fr_file_index.html +32 -0
- data/doc/fr_method_index.html +33 -0
- data/doc/index.html +24 -0
- data/doc/rdoc-style.css +208 -0
- data/lib/ews/transaction/mapping.rb +170 -0
- data/lib/ews/transaction/request.rb +158 -0
- data/lib/ews/transaction/response.rb +18 -0
- data/lib/ews/transaction/transporter.rb +128 -0
- data/lib/exact4r.rb +7 -0
- metadata +91 -0
@@ -0,0 +1,170 @@
|
|
1
|
+
require 'builder'
|
2
|
+
|
3
|
+
module EWS # :nodoc:
|
4
|
+
module Transaction # :nodoc:
|
5
|
+
|
6
|
+
# This class handles encoding of transaction requests to the various transport formats,
|
7
|
+
# and the decoding of responses to transaction response objects.
|
8
|
+
#
|
9
|
+
# The supported formats are:
|
10
|
+
# * REST/JSON
|
11
|
+
# * REST/XML
|
12
|
+
# * SOAP/XML
|
13
|
+
class Mapping # :nodoc:
|
14
|
+
|
15
|
+
XML_REQUEST_TAGS_TO_ATTRS = {
|
16
|
+
:ExactID => :gateway_id,
|
17
|
+
:Password => :password,
|
18
|
+
:Transaction_Type => :transaction_type,
|
19
|
+
:DollarAmount => :amount,
|
20
|
+
:SurchargeAmount => :surcharge_amount,
|
21
|
+
:Card_Number => :cc_number,
|
22
|
+
:Transaction_Tag => :transaction_tag,
|
23
|
+
:Track1 => :track1,
|
24
|
+
:Track2 => :track2,
|
25
|
+
:PAN => :pan,
|
26
|
+
:Authorization_Num => :auth_number,
|
27
|
+
:Expiry_Date => :cc_expiry,
|
28
|
+
:CardHoldersName => :cardholder_name,
|
29
|
+
:VerificationStr1 => :cc_verification_str1,
|
30
|
+
:VerificationStr2 => :cc_verification_str2,
|
31
|
+
:CVD_Presence_Ind => :cvd_presence_ind,
|
32
|
+
:Tax1Amount => :tax1_amount,
|
33
|
+
:Tax1Number => :tax1_number,
|
34
|
+
:Tax2Amount => :tax2_amount,
|
35
|
+
:Tax2Number => :tax2_number,
|
36
|
+
:Secure_AuthRequired => :secure_auth_required,
|
37
|
+
:Secure_AuthResult => :secure_auth_result,
|
38
|
+
:Ecommerce_Flag => :ecommerce_flag,
|
39
|
+
:XID => :xid,
|
40
|
+
:CAVV => :cavv,
|
41
|
+
:CAVV_Algorithm => :cavv_algorithm,
|
42
|
+
:Reference_No => :reference_no,
|
43
|
+
:Customer_Ref => :customer_ref,
|
44
|
+
:Reference_3 => :reference_3,
|
45
|
+
:Language => :language,
|
46
|
+
:Client_IP => :client_ip,
|
47
|
+
:Client_Email => :client_email,
|
48
|
+
:User_Name => :user_name
|
49
|
+
} unless defined?(XML_REQUEST_TAGS_TO_ATTRS)
|
50
|
+
|
51
|
+
XML_RESPONSE_TAGS_TO_ATTRS = {
|
52
|
+
:LogonMessage => :logon_message,
|
53
|
+
:Error_Number => :error_number,
|
54
|
+
:Error_Description => :error_description,
|
55
|
+
:Transaction_Error => :transaction_error,
|
56
|
+
:Transaction_Approved => :transaction_approved,
|
57
|
+
:EXact_Resp_Code => :exact_resp_code,
|
58
|
+
:EXact_Message => :exact_message,
|
59
|
+
:Bank_Resp_Code => :bank_resp_code,
|
60
|
+
:Bank_Message => :bank_message,
|
61
|
+
:Bank_Resp_Code_2 => :bank_resp_code_2,
|
62
|
+
:SequenceNo => :sequence_no,
|
63
|
+
:AVS => :avs,
|
64
|
+
:CVV2 => :cvv2,
|
65
|
+
:Retrieval_Ref_No => :retrieval_ref_no,
|
66
|
+
:CAVV_Response => :cavv_response,
|
67
|
+
:MerchantName => :merchant_name,
|
68
|
+
:MerchantAddress => :merchant_address,
|
69
|
+
:MerchantCity => :merchant_city,
|
70
|
+
:MerchantProvince => :merchant_province,
|
71
|
+
:MerchantCountry => :merchant_country,
|
72
|
+
:MerchantPostal => :merchant_postal,
|
73
|
+
:MerchantURL => :merchant_url,
|
74
|
+
:CTR => :CTR
|
75
|
+
}.merge(XML_REQUEST_TAGS_TO_ATTRS) unless defined?(XML_RESPONSE_TAGS_TO_ATTRS)
|
76
|
+
|
77
|
+
def self.request_to_json(request)
|
78
|
+
request.to_json
|
79
|
+
end
|
80
|
+
def self.request_to_rest(request)
|
81
|
+
xml = Builder::XmlMarkup.new
|
82
|
+
|
83
|
+
xml.instruct!
|
84
|
+
xml.tag! 'Transaction' do
|
85
|
+
add_request_hash(xml, request)
|
86
|
+
end
|
87
|
+
xml.target!
|
88
|
+
end
|
89
|
+
def self.request_to_soap(request)
|
90
|
+
xml = Builder::XmlMarkup.new(:indent => 2)
|
91
|
+
|
92
|
+
xml.instruct!
|
93
|
+
xml.tag! 'soap:Envelope', REQUEST_ENVELOPE_NAMESPACES do
|
94
|
+
xml.tag! 'soap:Body' do
|
95
|
+
xml.tag! 'n1:SendAndCommit', REQUEST_SAC_ATTRIBUTES do
|
96
|
+
xml.tag! 'SendAndCommitSource', REQUEST_SAC_SOURCE_ATTRIBUTES do
|
97
|
+
add_request_hash(xml, request)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
xml.target!
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.json_to_response(content)
|
106
|
+
response = EWS::Transaction::Response.new
|
107
|
+
ActiveSupport::JSON.decode(content).each { |k,v| response.send "#{k}=", v if response.respond_to?(k) }
|
108
|
+
response
|
109
|
+
end
|
110
|
+
def self.rest_to_response(content)
|
111
|
+
response = EWS::Transaction::Response.new
|
112
|
+
response_xml_string_to_hash(response, content)
|
113
|
+
response
|
114
|
+
end
|
115
|
+
def self.soap_to_response(content)
|
116
|
+
response = EWS::Transaction::Response.new
|
117
|
+
response_xml_string_to_hash(response, content, xpath = "//types:TransactionResult")
|
118
|
+
response
|
119
|
+
end
|
120
|
+
|
121
|
+
private
|
122
|
+
|
123
|
+
# Adds the request's attributes to the XmlMarkup.
|
124
|
+
def self.add_request_hash(xml, request)
|
125
|
+
XML_REQUEST_TAGS_TO_ATTRS.each do |k, v|
|
126
|
+
xml.tag! k.to_s, request.send(v.to_s)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# parses xml response string into the response attributes. The XPath identifies the root element
|
131
|
+
# of the payload. For REST (default) this is "//TransactionResult", for SOAP this is name space
|
132
|
+
# prefixed "//types:TransactionResult".
|
133
|
+
def self.response_xml_string_to_hash(response, xml_string, xpath = "//TransactionResult")
|
134
|
+
xml = REXML::Document.new(xml_string)
|
135
|
+
if root = REXML::XPath.first(xml, xpath)
|
136
|
+
root.elements.to_a.each do |node|
|
137
|
+
gwlib_prop_name = XML_RESPONSE_TAGS_TO_ATTRS[node.name.to_sym]
|
138
|
+
logger.warn("No mapping for the tag #{node.name}.") if gwlib_prop_name.nil?
|
139
|
+
value = (ATTR_FORMATS.include?(gwlib_prop_name)) ? node.text.send("to_#{ATTR_FORMATS[gwlib_prop_name]}") : node.text
|
140
|
+
response.send "#{gwlib_prop_name}=", value
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# type-conversion from strings for certain attributes
|
146
|
+
ATTR_FORMATS = {
|
147
|
+
:transaction_tag => "i",
|
148
|
+
:transaction_approved => "i",
|
149
|
+
:amount => "f",
|
150
|
+
:surcharge_amount => "f",
|
151
|
+
:tax1_amount => "f",
|
152
|
+
:tax2_amount => "f"
|
153
|
+
}
|
154
|
+
|
155
|
+
REQUEST_ENVELOPE_NAMESPACES = {
|
156
|
+
"xmlns:xsd" => "http://www.w3.org/2001/XMLSchema",
|
157
|
+
"xmlns:env" => "http://schemas.xmlsoap.org/soap/envelope/",
|
158
|
+
"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance"
|
159
|
+
}
|
160
|
+
REQUEST_SAC_ATTRIBUTES = {
|
161
|
+
"xmlns:n1" => "http://secure2.e-xact.com/vplug-in/transaction/rpc-enc/Request",
|
162
|
+
"env:encodingStyle" => "http://schemas.xmlsoap.org/soap/encoding/"
|
163
|
+
}
|
164
|
+
REQUEST_SAC_SOURCE_ATTRIBUTES = {
|
165
|
+
"xmlns:n2" => "http://secure2.e-xact.com/vplug-in/transaction/rpc-enc/encodedTypes",
|
166
|
+
"xsi:type" => "n2:Transaction"
|
167
|
+
}
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
module EWS # :nodoc:
|
2
|
+
module Transaction # :nodoc:
|
3
|
+
|
4
|
+
# The Request class allows you to build transaction requests for
|
5
|
+
# submission to the E-xact Web Service.
|
6
|
+
#
|
7
|
+
# All requests will result in a financial transaction occurring, with the exception
|
8
|
+
# of the <tt>:transaction_details</tt> request, which looks up the details of a pre-existing
|
9
|
+
# transaction.
|
10
|
+
#
|
11
|
+
# The following fields are *mandatory* on all requests:
|
12
|
+
# :gateway_id the gateway to which this request should be sent
|
13
|
+
# :password your password for that gateway
|
14
|
+
# :transaction_type the type of transaction you want to perform
|
15
|
+
#
|
16
|
+
# Different transaction types will have their own additional requirements when it comes to
|
17
|
+
# mandatory and optional fields, and it is recommended that the E-xact Web Service Programming
|
18
|
+
# Reference Guide, v8.5 be consulted. This document is contained in the Webservice Plugin ZIP file:
|
19
|
+
# http://www.e-xact.com/wp-content/uploads/2007/06/E-xact_Payment_Webservice_Plug-In.zip
|
20
|
+
#
|
21
|
+
# Please note that, if your chosen transaction requires it, credit card expiry dates *must* be entered in YYMM format.
|
22
|
+
#
|
23
|
+
# =Allowable transaction types
|
24
|
+
# :purchase
|
25
|
+
# :pre_auth
|
26
|
+
# :pre_auth_completion
|
27
|
+
# :forced_post
|
28
|
+
# :refund
|
29
|
+
# :pre_auth_only
|
30
|
+
# :purchase_correction
|
31
|
+
# :refund_correction
|
32
|
+
# :void
|
33
|
+
# :tagged_purchase
|
34
|
+
# :tagged_pre_auth
|
35
|
+
# :tagged_pre_auth_completion
|
36
|
+
# :tagged_void
|
37
|
+
# :tagged_refund
|
38
|
+
# :tagged_online_debit_refund
|
39
|
+
# :recurring_seed_pre_auth
|
40
|
+
# :recurring_seed_purchase
|
41
|
+
# :idebit_purchase
|
42
|
+
# :idebit_refund
|
43
|
+
# :secure_storage
|
44
|
+
# :secure_storage_eft
|
45
|
+
# :transaction_details
|
46
|
+
class Request
|
47
|
+
|
48
|
+
attr_accessor :errors
|
49
|
+
attr_accessor :gateway_id, :password, :transaction_type, :amount, :surcharge_amount, :cc_number, :transaction_tag, :track1, :track2, :pan, :auth_number, :cc_expiry, :cardholder_name
|
50
|
+
attr_accessor :cc_verification_str1, :cc_verification_str2, :cvd_presence_ind, :tax1_amount, :tax1_number, :tax2_amount, :tax2_number, :secure_auth_required, :secure_auth_result
|
51
|
+
attr_accessor :ecommerce_flag, :xid, :cavv, :cavv_algorithm, :reference_no, :customer_ref, :reference_3, :language, :client_ip, :client_email, :user_name
|
52
|
+
|
53
|
+
# Initialize a Request with a hash of values
|
54
|
+
def initialize(hash = {})
|
55
|
+
hash.each {|k,v| self.send "#{k.to_s}=", v}
|
56
|
+
@errors = {}
|
57
|
+
end
|
58
|
+
|
59
|
+
# Set the <tt>transasction_type<tt> using either a symbol or the relevant code, e.g: for a purchase
|
60
|
+
# you can use either <tt>:purchase</tt> or <tt>'00'</tt>
|
61
|
+
def transaction_type=(type_sym)
|
62
|
+
# assume we're given a symbol, so look up the code
|
63
|
+
value = @@transaction_codes[type_sym]
|
64
|
+
# if nothing found, then maybe we were given an actual code?
|
65
|
+
value = type_sym if value.nil? and @@transaction_codes.values.include? type_sym
|
66
|
+
|
67
|
+
@transaction_type = value
|
68
|
+
end
|
69
|
+
|
70
|
+
# Indicates whether or not this transaction is a <tt>:transaction_details</tt> transaction
|
71
|
+
def is_find_transaction?
|
72
|
+
self.transaction_type == "CR"
|
73
|
+
end
|
74
|
+
|
75
|
+
def valid?
|
76
|
+
errors[:transaction_type] = "transaction_type must be supplied" if self.transaction_type.blank?
|
77
|
+
errors[:transaction_type] = "invalid transaction_type supplied" unless @@transaction_codes.values.include? self.transaction_type
|
78
|
+
|
79
|
+
# need to authenticate
|
80
|
+
errors[:gateway_id] = "gateway_id must be supplied" if self.gateway_id.blank?
|
81
|
+
errors[:password] = "password must be supplied" if self.password.blank?
|
82
|
+
|
83
|
+
# ensure we've been given valid amounts
|
84
|
+
errors[:amount] = "invalid amount supplied" unless valid_amount?(self.amount)
|
85
|
+
errors[:surcharge_amount] = "invalid surcharge_amount supplied" unless valid_amount?(self.surcharge_amount)
|
86
|
+
errors[:tax1_amount] = "invalid tax1_amount supplied" unless valid_amount?(self.tax1_amount)
|
87
|
+
errors[:tax2_amount] = "invalid tax2_amount supplied" unless valid_amount?(self.tax2_amount)
|
88
|
+
|
89
|
+
errors[:cc_number] = "invalid cc_number supplied" unless valid_card_number?
|
90
|
+
errors[:cc_expiry] = "invalid cc_expiry supplied" unless valid_expiry_date?
|
91
|
+
|
92
|
+
errors.empty?
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
def valid_amount?(amount)
|
97
|
+
return true if amount.blank?
|
98
|
+
|
99
|
+
(amount.class == Float) or (amount.class == Fixnum) or !amount.match /[^0-9.]/
|
100
|
+
end
|
101
|
+
|
102
|
+
def valid_card_number?
|
103
|
+
return true if self.cc_number.blank?
|
104
|
+
|
105
|
+
# do a mod10 check
|
106
|
+
weight = 1
|
107
|
+
card_number = self.cc_number.scan(/./).map(&:to_i)
|
108
|
+
result = card_number.reverse[1..-1].inject(0) do |sum, num|
|
109
|
+
weight = 1 + weight%2
|
110
|
+
digit = num * weight
|
111
|
+
sum += (digit / 10) + (digit % 10)
|
112
|
+
end
|
113
|
+
card_number.last == (10 - result % 10 ) % 10
|
114
|
+
end
|
115
|
+
|
116
|
+
def valid_expiry_date?
|
117
|
+
return true if self.cc_expiry.blank?
|
118
|
+
|
119
|
+
# check format
|
120
|
+
return false unless self.cc_expiry.match /^\d{4}$/
|
121
|
+
|
122
|
+
# check date is not in past
|
123
|
+
year, month = 2000 + self.cc_expiry[0..1].to_i, self.cc_expiry[2..3].to_i
|
124
|
+
|
125
|
+
# CC is still considered valid during the month of expiry,
|
126
|
+
# so just compare year and month, ignoring the rest.
|
127
|
+
now = DateTime.now
|
128
|
+
return ((1..12) === month) && DateTime.new(year, month) >= DateTime.new(now.year, now.month)
|
129
|
+
end
|
130
|
+
|
131
|
+
@@transaction_codes = {
|
132
|
+
:purchase => '00',
|
133
|
+
:pre_auth => '01',
|
134
|
+
:pre_auth_completion => '02',
|
135
|
+
:forced_post => '03',
|
136
|
+
:refund => '04',
|
137
|
+
:pre_auth_only => '05',
|
138
|
+
:purchase_correction => '11',
|
139
|
+
:refund_correction => '12',
|
140
|
+
:void => '13',
|
141
|
+
:tagged_purchase => '30',
|
142
|
+
:tagged_pre_auth => '31',
|
143
|
+
:tagged_pre_auth_completion => '32',
|
144
|
+
:tagged_void => '33',
|
145
|
+
:tagged_refund => '34',
|
146
|
+
:tagged_online_debit_refund => '35',
|
147
|
+
:recurring_seed_pre_auth => '40',
|
148
|
+
:recurring_seed_purchase => '41',
|
149
|
+
:idebit_purchase => '50',
|
150
|
+
:idebit_refund => '54',
|
151
|
+
:secure_storage => '60',
|
152
|
+
:secure_storage_eft => '61',
|
153
|
+
:transaction_details => 'CR'
|
154
|
+
}.freeze unless defined?(@@transaction_codes)
|
155
|
+
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module EWS # :nodoc:
|
2
|
+
module Transaction # :nodoc:
|
3
|
+
|
4
|
+
# This class encapsulates all the data returned from the E-xact Web Service.
|
5
|
+
class Response < EWS::Transaction::Request
|
6
|
+
|
7
|
+
attr_accessor :logon_message, :error_number, :error_description, :transaction_error, :transaction_approved
|
8
|
+
attr_accessor :exact_resp_code, :exact_message, :bank_resp_code, :bank_message, :bank_resp_code_2
|
9
|
+
attr_accessor :sequence_no, :avs, :cvv2, :retrieval_ref_no, :cavv_response
|
10
|
+
attr_accessor :merchant_name, :merchant_address, :merchant_city, :merchant_province, :merchant_country, :merchant_postal, :merchant_url, :CTR
|
11
|
+
|
12
|
+
# Indicates whether or not the transaction was approved
|
13
|
+
def approved?
|
14
|
+
self.transaction_approved == 1
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'net/https'
|
2
|
+
|
3
|
+
module EWS # :nodoc:
|
4
|
+
module Transaction # :nodoc:
|
5
|
+
|
6
|
+
# A Transporter is responsible for communicating with the E-xact Web Service in
|
7
|
+
# whichever dialect is chosen by the user. The available options are:
|
8
|
+
# :json REST with JSON payload
|
9
|
+
# :rest REST with XML payload
|
10
|
+
# :soap SOAP
|
11
|
+
#
|
12
|
+
# The Transporter will connect to the service, using SSL if required, and will
|
13
|
+
# encode Reqests to send to the service, and decode Responses received from the
|
14
|
+
# service.
|
15
|
+
#
|
16
|
+
# Once configured to connect to a particular service, it can be used repeatedly
|
17
|
+
# to send as many transactions as required.
|
18
|
+
class Transporter
|
19
|
+
|
20
|
+
# Initialize a Transporter.
|
21
|
+
#
|
22
|
+
# You can specify the URL you would like the Transporter to connect to,
|
23
|
+
# although it defaults to https://api.e-xact.com, the location of our web
|
24
|
+
# service.
|
25
|
+
#
|
26
|
+
# You can also specify a hash of options as follows:
|
27
|
+
# :server_cert the path to the server's certificate
|
28
|
+
# :issuer_cert the path to the certificate of the issuer of the server certificate
|
29
|
+
# :transport_type the default transport_type for this transporter
|
30
|
+
#
|
31
|
+
# The default certificates are those required to connect to https://api.e-xact.com and the
|
32
|
+
# default <tt>transport_type</tt> is <tt>:rest</tt>. The default <tt>transport_type</tt> can be overridden on a per-transaction
|
33
|
+
# basis, if you choose to do so, by specifying it as a parameter to the <tt>send</tt> method.
|
34
|
+
def initialize(url = "https://api.e-xact.com/", options = {})
|
35
|
+
@url = URI.parse(url)
|
36
|
+
@server_cert = options[:server_cert] || "certs/exact.cer"
|
37
|
+
@issuer_cert = options[:issuer_cert] || "certs/equifax_ca.cer"
|
38
|
+
@transport_type = options[:issuer_cert] || :rest
|
39
|
+
end
|
40
|
+
|
41
|
+
# Send a transaction request to the server
|
42
|
+
#
|
43
|
+
# <tt>request</tt>:: the Request object to encode for transmission to the server
|
44
|
+
# <tt>transport_type</tt>:: (optional) the transport type to use for this transaction only. If it not specified, the default transport type for this Transporter will be used
|
45
|
+
def send(request, transport_type = nil)
|
46
|
+
raise "Request not supplied" if request.nil?
|
47
|
+
return false unless request.valid?
|
48
|
+
|
49
|
+
transport_type ||= @transport_type
|
50
|
+
|
51
|
+
raise "Transport type #{transport_type} is not supported" unless @@transport_types.include? transport_type
|
52
|
+
|
53
|
+
if !request.is_find_transaction? or transport_type == :soap
|
54
|
+
content = post(request, transport_type)
|
55
|
+
else
|
56
|
+
content = get(request, transport_type)
|
57
|
+
end
|
58
|
+
|
59
|
+
EWS::Transaction::Mapping.send "#{transport_type}_to_response", content
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def post(request, transport_type)
|
65
|
+
# build the request
|
66
|
+
req = Net::HTTP::Post.new(@url.path + "/transaction.#{@@transport_types[transport_type]}")
|
67
|
+
req.basic_auth(request.gateway_id, request.password)
|
68
|
+
if transport_type == :soap
|
69
|
+
# add the SOAPAction header
|
70
|
+
soapaction = (request.is_find_transaction?) ? "TransactionInfo" : "SendAndCommit"
|
71
|
+
req.add_field "soapaction", "http://secure2.e-xact.com/vplug-in/transaction/rpc-enc/#{soapaction}"
|
72
|
+
end
|
73
|
+
req.content_type = (transport_type == :json) ? "application/json" : "application/xml"
|
74
|
+
req.body = EWS::Transaction::Mapping.send "request_to_#{transport_type.to_s}", request
|
75
|
+
|
76
|
+
response = get_connection.request(req)
|
77
|
+
|
78
|
+
case response
|
79
|
+
when Net::HTTPSuccess then response.body
|
80
|
+
else
|
81
|
+
response.error!
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def get(request, transport_type)
|
86
|
+
# build the request
|
87
|
+
req = Net::HTTP::Get.new(@url.path + "/transaction/#{request.transaction_tag}.#{@@transport_types[transport_type]}")
|
88
|
+
req.basic_auth(request.gateway_id, request.password)
|
89
|
+
req.content_type = (transport_type == :json) ? "application/json" : "application/xml"
|
90
|
+
|
91
|
+
response = get_connection.request(req)
|
92
|
+
|
93
|
+
case response
|
94
|
+
when Net::HTTPSuccess then response.body
|
95
|
+
else
|
96
|
+
response.error!
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def get_connection
|
101
|
+
connection = Net::HTTP.new(@url.host, @url.port)
|
102
|
+
if @url.scheme == 'https'
|
103
|
+
connection.use_ssl = true
|
104
|
+
connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
105
|
+
connection.ca_file = @issuer_cert
|
106
|
+
connection.verify_callback = method(:validate_certificate)
|
107
|
+
end
|
108
|
+
connection
|
109
|
+
end
|
110
|
+
|
111
|
+
def validate_certificate(is_ok, ctx)
|
112
|
+
# Don't check the root CA cert
|
113
|
+
unless (ctx.current_cert.subject.to_s == ctx.current_cert.issuer.to_s)
|
114
|
+
is_ok &&= File.open(@server_cert).read == ctx.current_cert.to_pem
|
115
|
+
end
|
116
|
+
is_ok
|
117
|
+
end
|
118
|
+
|
119
|
+
# what transport types we support, and their corresponding suffixes
|
120
|
+
@@transport_types = {
|
121
|
+
:rest => "xml",
|
122
|
+
:json => "json",
|
123
|
+
:soap => "xmlsoap"
|
124
|
+
}
|
125
|
+
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|