activemerchant 1.29.1 → 1.34.0
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/CHANGELOG +143 -0
- data/CONTRIBUTORS +43 -0
- data/README.md +59 -51
- data/lib/active_merchant/billing/check.rb +15 -14
- data/lib/active_merchant/billing/credit_card.rb +14 -5
- data/lib/active_merchant/billing/credit_card_formatting.rb +8 -8
- data/lib/active_merchant/billing/gateway.rb +2 -2
- data/lib/active_merchant/billing/gateways/authorize_net.rb +36 -8
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +17 -5
- data/lib/active_merchant/billing/gateways/balanced.rb +9 -3
- data/lib/active_merchant/billing/gateways/banwire.rb +15 -1
- data/lib/active_merchant/billing/gateways/barclays_epdq.rb +8 -1
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +7 -2
- data/lib/active_merchant/billing/gateways/beanstream.rb +26 -24
- data/lib/active_merchant/billing/gateways/blue_pay.rb +201 -187
- data/lib/active_merchant/billing/gateways/bogus.rb +1 -1
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +7 -3
- data/lib/active_merchant/billing/gateways/card_stream_modern.rb +155 -0
- data/lib/active_merchant/billing/gateways/cc5.rb +156 -0
- data/lib/active_merchant/billing/gateways/cyber_source.rb +55 -22
- data/lib/active_merchant/billing/gateways/data_cash.rb +3 -3
- data/lib/active_merchant/billing/gateways/evo_ca.rb +308 -0
- data/lib/active_merchant/billing/gateways/eway.rb +114 -171
- data/lib/active_merchant/billing/gateways/eway_managed.rb +52 -22
- data/lib/active_merchant/billing/gateways/finansbank.rb +22 -0
- data/lib/active_merchant/billing/gateways/firstdata_e4.rb +314 -0
- data/lib/active_merchant/billing/gateways/garanti.rb +0 -4
- data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +13 -2
- data/lib/active_merchant/billing/gateways/iridium.rb +8 -2
- data/lib/active_merchant/billing/gateways/litle.rb +354 -105
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +28 -7
- data/lib/active_merchant/billing/gateways/merchant_ware.rb +44 -9
- data/lib/active_merchant/billing/gateways/merchant_warrior.rb +190 -0
- data/lib/active_merchant/billing/gateways/moneris.rb +4 -6
- data/lib/active_merchant/billing/gateways/moneris_us.rb +1 -1
- data/lib/active_merchant/billing/gateways/nab_transact.rb +20 -3
- data/lib/active_merchant/billing/gateways/net_registry.rb +8 -3
- data/lib/active_merchant/billing/gateways/netaxept.rb +65 -117
- data/lib/active_merchant/billing/gateways/netbilling.rb +1 -0
- data/lib/active_merchant/billing/gateways/netpay.rb +223 -0
- data/lib/active_merchant/billing/gateways/ogone.rb +7 -5
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +43 -18
- data/lib/active_merchant/billing/gateways/orbital.rb +190 -53
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +12 -10
- data/lib/active_merchant/billing/gateways/payment_express.rb +62 -1
- data/lib/active_merchant/billing/gateways/paymill.rb +179 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +12 -7
- data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +14 -9
- data/lib/active_merchant/billing/gateways/paypal_express.rb +59 -18
- data/lib/active_merchant/billing/gateways/pin.rb +165 -0
- data/lib/active_merchant/billing/gateways/qbms.rb +3 -2
- data/lib/active_merchant/billing/gateways/quickpay.rb +66 -28
- data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +16 -11
- data/lib/active_merchant/billing/gateways/sage/sage_core.rb +1 -1
- data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +21 -16
- data/lib/active_merchant/billing/gateways/sage.rb +10 -5
- data/lib/active_merchant/billing/gateways/sage_pay.rb +7 -0
- data/lib/active_merchant/billing/gateways/smart_ps.rb +1 -1
- data/lib/active_merchant/billing/gateways/spreedly_core.rb +233 -0
- data/lib/active_merchant/billing/gateways/stripe.rb +49 -21
- data/lib/active_merchant/billing/gateways/transnational.rb +239 -0
- data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +9 -4
- data/lib/active_merchant/billing/gateways/webpay.rb +8 -0
- data/lib/active_merchant/billing/gateways/wirecard.rb +15 -9
- data/lib/active_merchant/billing/gateways/worldpay.rb +60 -24
- data/lib/active_merchant/billing/integrations/direc_pay/status.rb +1 -1
- data/lib/active_merchant/billing/integrations/direc_pay.rb +1 -1
- data/lib/active_merchant/billing/integrations/dwolla/common.rb +23 -0
- data/lib/active_merchant/billing/integrations/dwolla/helper.rb +18 -6
- data/lib/active_merchant/billing/integrations/dwolla/notification.rb +16 -7
- data/lib/active_merchant/billing/integrations/dwolla/return.rb +16 -5
- data/lib/active_merchant/billing/integrations/dwolla.rb +5 -12
- data/lib/active_merchant/billing/integrations/notification.rb +13 -8
- data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +19 -3
- data/lib/active_merchant/billing/integrations/paypal/notification.rb +39 -31
- data/lib/active_merchant/billing/integrations/payu_in/helper.rb +74 -0
- data/lib/active_merchant/billing/integrations/payu_in/notification.rb +167 -0
- data/lib/active_merchant/billing/integrations/payu_in/return.rb +53 -0
- data/lib/active_merchant/billing/integrations/payu_in.rb +43 -0
- data/lib/active_merchant/billing/integrations/pxpay/helper.rb +1 -0
- data/lib/active_merchant/billing/integrations/quickpay/helper.rb +13 -10
- data/lib/active_merchant/billing/integrations/quickpay/notification.rb +78 -15
- data/lib/active_merchant/billing/integrations/rbkmoney/helper.rb +23 -0
- data/lib/active_merchant/billing/integrations/rbkmoney/notification.rb +91 -0
- data/lib/active_merchant/billing/integrations/rbkmoney.rb +17 -0
- data/lib/active_merchant/billing/integrations/robokassa/common.rb +1 -1
- data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +7 -3
- data/lib/active_merchant/billing/integrations/world_pay.rb +15 -8
- data/lib/active_merchant/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +124 -50
- metadata.gz.sig +0 -0
|
@@ -89,7 +89,18 @@ module ActiveMerchant #:nodoc:
|
|
|
89
89
|
commit("ProcessPayment", post)
|
|
90
90
|
end
|
|
91
91
|
|
|
92
|
-
#
|
|
92
|
+
# Get customer's stored credit card details given by billing_id
|
|
93
|
+
#
|
|
94
|
+
# ==== Parameters
|
|
95
|
+
#
|
|
96
|
+
# * <tt>billing_id</tt> -- The eWay provided card/customer token to charge (managedCustomerID)
|
|
97
|
+
def retrieve(billing_id)
|
|
98
|
+
post = {}
|
|
99
|
+
post[:managedCustomerID] = billing_id.to_s
|
|
100
|
+
|
|
101
|
+
commit("QueryCustomer", post)
|
|
102
|
+
end
|
|
103
|
+
|
|
93
104
|
# TODO: eWay API also provides QueryPayment
|
|
94
105
|
|
|
95
106
|
private
|
|
@@ -146,25 +157,29 @@ module ActiveMerchant #:nodoc:
|
|
|
146
157
|
# Successful payment
|
|
147
158
|
reply=parse_purchase(root)
|
|
148
159
|
else
|
|
149
|
-
if root = REXML::XPath.first(xml, '//
|
|
150
|
-
reply
|
|
151
|
-
reply[:CreateCustomerResult]=root.text
|
|
152
|
-
reply[:success]=true
|
|
160
|
+
if root = REXML::XPath.first(xml, '//QueryCustomerResult') then
|
|
161
|
+
reply=parse_query_customer(root)
|
|
153
162
|
else
|
|
154
|
-
if root = REXML::XPath.first(xml, '//
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
163
|
+
if root = REXML::XPath.first(xml, '//CreateCustomerResult') then
|
|
164
|
+
reply[:message]='OK'
|
|
165
|
+
reply[:CreateCustomerResult]=root.text
|
|
166
|
+
reply[:success]=true
|
|
167
|
+
else
|
|
168
|
+
if root = REXML::XPath.first(xml, '//UpdateCustomerResult') then
|
|
169
|
+
if root.text.downcase == 'true' then
|
|
170
|
+
reply[:message]='OK'
|
|
171
|
+
reply[:success]=true
|
|
172
|
+
else
|
|
173
|
+
# ERROR: This state should never occur. If there is a problem,
|
|
174
|
+
# a soap:Fault will be returned. The presence of this
|
|
175
|
+
# element always means a success.
|
|
176
|
+
raise StandardError, "Unexpected \"false\" in UpdateCustomerResult"
|
|
177
|
+
end
|
|
158
178
|
else
|
|
159
|
-
# ERROR: This state should never occur.
|
|
160
|
-
#
|
|
161
|
-
|
|
162
|
-
raise StandardError, "Unexpected \"false\" in UpdateCustomerResult"
|
|
179
|
+
# ERROR: This state should never occur currently. We have handled
|
|
180
|
+
# responses for all the methods which we support.
|
|
181
|
+
raise StandardError, "Unexpected response"
|
|
163
182
|
end
|
|
164
|
-
else
|
|
165
|
-
# ERROR: This state should never occur currently. We have handled
|
|
166
|
-
# responses for all the methods which we support.
|
|
167
|
-
raise StandardError, "Unexpected response"
|
|
168
183
|
end
|
|
169
184
|
end
|
|
170
185
|
end
|
|
@@ -188,6 +203,17 @@ module ActiveMerchant #:nodoc:
|
|
|
188
203
|
reply
|
|
189
204
|
end
|
|
190
205
|
|
|
206
|
+
def parse_query_customer(node)
|
|
207
|
+
reply={}
|
|
208
|
+
reply[:message]='OK'
|
|
209
|
+
reply[:success]=true
|
|
210
|
+
reply[:CCNumber]=REXML::XPath.first(node, '//CCNumber').text
|
|
211
|
+
reply[:CCName]=REXML::XPath.first(node, '//CCName').text
|
|
212
|
+
reply[:CCExpiryMonth]=REXML::XPath.first(node, '//CCExpiryMonth').text
|
|
213
|
+
reply[:CCExpiryYear]=REXML::XPath.first(node, '//CCExpiryYear').text
|
|
214
|
+
reply
|
|
215
|
+
end
|
|
216
|
+
|
|
191
217
|
def commit(action, post)
|
|
192
218
|
raw = begin
|
|
193
219
|
ssl_post(test? ? self.test_url : self.live_url, soap_request(post, action), 'Content-Type' => 'application/soap+xml; charset=utf-8')
|
|
@@ -206,11 +232,15 @@ module ActiveMerchant #:nodoc:
|
|
|
206
232
|
def soap_request(arguments, action)
|
|
207
233
|
# eWay demands all fields be sent, but contain an empty string if blank
|
|
208
234
|
post = case action
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
235
|
+
when 'QueryCustomer'
|
|
236
|
+
arguments
|
|
237
|
+
when 'ProcessPayment'
|
|
238
|
+
default_payment_fields.merge(arguments)
|
|
239
|
+
when 'CreateCustomer'
|
|
240
|
+
default_customer_fields.merge(arguments)
|
|
241
|
+
when 'UpdateCustomer'
|
|
242
|
+
default_customer_fields.merge(arguments)
|
|
243
|
+
end
|
|
214
244
|
|
|
215
245
|
xml = Builder::XmlMarkup.new :indent => 2
|
|
216
246
|
xml.instruct!
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/cc5'
|
|
2
|
+
|
|
3
|
+
module ActiveMerchant #:nodoc:
|
|
4
|
+
module Billing #:nodoc:
|
|
5
|
+
class FinansbankGateway < CC5Gateway
|
|
6
|
+
self.live_url = self.test_url = 'https://www.fbwebpos.com/servlet/cc5ApiServer'
|
|
7
|
+
|
|
8
|
+
# The countries the gateway supports merchants from as 2 digit ISO country codes
|
|
9
|
+
self.supported_countries = ['US', 'TR']
|
|
10
|
+
|
|
11
|
+
# The card types supported by the payment gateway
|
|
12
|
+
self.supported_cardtypes = [:visa, :master]
|
|
13
|
+
|
|
14
|
+
# The homepage URL of the gateway
|
|
15
|
+
self.homepage_url = 'https://www.fbwebpos.com/'
|
|
16
|
+
|
|
17
|
+
# The name of the gateway
|
|
18
|
+
self.display_name = 'Finansbank WebPOS'
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
|
2
|
+
module Billing #:nodoc:
|
|
3
|
+
class FirstdataE4Gateway < Gateway
|
|
4
|
+
# TransArmor support requires v11 or lower
|
|
5
|
+
self.test_url = "https://api.demo.globalgatewaye4.firstdata.com/transaction/v11"
|
|
6
|
+
self.live_url = "https://api.globalgatewaye4.firstdata.com/transaction/v11"
|
|
7
|
+
|
|
8
|
+
TRANSACTIONS = {
|
|
9
|
+
:sale => "00",
|
|
10
|
+
:authorization => "01",
|
|
11
|
+
:capture => "32",
|
|
12
|
+
:void => "33",
|
|
13
|
+
:credit => "34",
|
|
14
|
+
:store => "05"
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
POST_HEADERS = {
|
|
18
|
+
"Accepts" => "application/xml",
|
|
19
|
+
"Content-Type" => "application/xml"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
SUCCESS = "true"
|
|
23
|
+
|
|
24
|
+
SENSITIVE_FIELDS = [:verification_str2, :expiry_date, :card_number]
|
|
25
|
+
|
|
26
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :jcb, :discover]
|
|
27
|
+
self.supported_countries = ["CA", "US"]
|
|
28
|
+
self.default_currency = "USD"
|
|
29
|
+
self.homepage_url = "http://www.firstdata.com"
|
|
30
|
+
self.display_name = "FirstData Global Gateway e4"
|
|
31
|
+
|
|
32
|
+
# Create a new FirstdataE4Gateway
|
|
33
|
+
#
|
|
34
|
+
# The gateway requires that a valid login and password be passed
|
|
35
|
+
# in the +options+ hash.
|
|
36
|
+
#
|
|
37
|
+
# ==== Options
|
|
38
|
+
#
|
|
39
|
+
# * <tt>:login</tt> -- The EXACT ID. Also known as the Gateway ID.
|
|
40
|
+
# (Found in your administration terminal settings)
|
|
41
|
+
# * <tt>:password</tt> -- The terminal password (not your account password)
|
|
42
|
+
def initialize(options = {})
|
|
43
|
+
requires!(options, :login, :password)
|
|
44
|
+
@options = options
|
|
45
|
+
|
|
46
|
+
super
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def authorize(money, credit_card_or_store_authorization, options = {})
|
|
50
|
+
commit(:authorization, build_sale_or_authorization_request(money, credit_card_or_store_authorization, options))
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def purchase(money, credit_card_or_store_authorization, options = {})
|
|
54
|
+
commit(:sale, build_sale_or_authorization_request(money, credit_card_or_store_authorization, options))
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def capture(money, authorization, options = {})
|
|
58
|
+
commit(:capture, build_capture_or_credit_request(money, authorization, options))
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def void(authorization, options = {})
|
|
62
|
+
commit(:void, build_capture_or_credit_request(money_from_authorization(authorization), authorization, options))
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def refund(money, authorization, options = {})
|
|
66
|
+
commit(:credit, build_capture_or_credit_request(money, authorization, options))
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Tokenize a credit card with TransArmor
|
|
70
|
+
#
|
|
71
|
+
# The TransArmor token and other card data necessary for subsequent
|
|
72
|
+
# transactions is stored in the response's +authorization+ attribute.
|
|
73
|
+
# The authorization string may be passed to +authorize+ and +purchase+
|
|
74
|
+
# instead of a +ActiveMerchant::Billing::CreditCard+ instance.
|
|
75
|
+
#
|
|
76
|
+
# TransArmor support must be explicitly activated on your gateway
|
|
77
|
+
# account by FirstData. If your authorization string is empty, contact
|
|
78
|
+
# FirstData support for account setup assistance.
|
|
79
|
+
#
|
|
80
|
+
# === Example
|
|
81
|
+
#
|
|
82
|
+
# # Generate token
|
|
83
|
+
# result = gateway.store(credit_card)
|
|
84
|
+
# if result.success?
|
|
85
|
+
# my_record.update_attributes(:authorization => result.authorization)
|
|
86
|
+
# end
|
|
87
|
+
#
|
|
88
|
+
# # Use token
|
|
89
|
+
# result = gateway.purchase(1000, my_record.authorization)
|
|
90
|
+
#
|
|
91
|
+
# https://firstdata.zendesk.com/entries/21303361-transarmor-tokenization
|
|
92
|
+
def store(credit_card, options = {})
|
|
93
|
+
commit(:store, build_store_request(credit_card, options), credit_card)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
private
|
|
97
|
+
|
|
98
|
+
def build_request(action, body)
|
|
99
|
+
xml = Builder::XmlMarkup.new
|
|
100
|
+
|
|
101
|
+
xml.instruct!
|
|
102
|
+
xml.tag! "Transaction" do
|
|
103
|
+
add_credentials(xml)
|
|
104
|
+
add_transaction_type(xml, action)
|
|
105
|
+
xml << body
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
xml.target!
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def build_sale_or_authorization_request(money, credit_card_or_store_authorization, options)
|
|
112
|
+
xml = Builder::XmlMarkup.new
|
|
113
|
+
|
|
114
|
+
add_amount(xml, money)
|
|
115
|
+
|
|
116
|
+
if credit_card_or_store_authorization.is_a? String
|
|
117
|
+
add_credit_card_token(xml, credit_card_or_store_authorization)
|
|
118
|
+
else
|
|
119
|
+
add_credit_card(xml, credit_card_or_store_authorization)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
add_customer_data(xml, options)
|
|
123
|
+
add_invoice(xml, options)
|
|
124
|
+
|
|
125
|
+
xml.target!
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def build_capture_or_credit_request(money, identification, options)
|
|
129
|
+
xml = Builder::XmlMarkup.new
|
|
130
|
+
|
|
131
|
+
add_identification(xml, identification)
|
|
132
|
+
add_amount(xml, money)
|
|
133
|
+
add_customer_data(xml, options)
|
|
134
|
+
|
|
135
|
+
xml.target!
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def build_store_request(credit_card, options)
|
|
139
|
+
xml = Builder::XmlMarkup.new
|
|
140
|
+
|
|
141
|
+
add_credit_card(xml, credit_card)
|
|
142
|
+
add_customer_data(xml, options)
|
|
143
|
+
|
|
144
|
+
xml.target!
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def add_credentials(xml)
|
|
148
|
+
xml.tag! "ExactID", @options[:login]
|
|
149
|
+
xml.tag! "Password", @options[:password]
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def add_transaction_type(xml, action)
|
|
153
|
+
xml.tag! "Transaction_Type", TRANSACTIONS[action]
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def add_identification(xml, identification)
|
|
157
|
+
authorization_num, transaction_tag, _ = identification.split(";")
|
|
158
|
+
|
|
159
|
+
xml.tag! "Authorization_Num", authorization_num
|
|
160
|
+
xml.tag! "Transaction_Tag", transaction_tag
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def add_amount(xml, money)
|
|
164
|
+
xml.tag! "DollarAmount", amount(money)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def add_credit_card(xml, credit_card)
|
|
168
|
+
xml.tag! "Card_Number", credit_card.number
|
|
169
|
+
xml.tag! "Expiry_Date", expdate(credit_card)
|
|
170
|
+
xml.tag! "CardHoldersName", credit_card.name
|
|
171
|
+
xml.tag! "CardType", credit_card.brand
|
|
172
|
+
|
|
173
|
+
if credit_card.verification_value?
|
|
174
|
+
xml.tag! "CVD_Presence_Ind", "1"
|
|
175
|
+
xml.tag! "VerificationStr2", credit_card.verification_value
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def add_credit_card_token(xml, store_authorization)
|
|
180
|
+
params = store_authorization.split(";")
|
|
181
|
+
credit_card = CreditCard.new(
|
|
182
|
+
:brand => params[1],
|
|
183
|
+
:first_name => params[2],
|
|
184
|
+
:last_name => params[3],
|
|
185
|
+
:month => params[4],
|
|
186
|
+
:year => params[5])
|
|
187
|
+
|
|
188
|
+
xml.tag! "TransarmorToken", params[0]
|
|
189
|
+
xml.tag! "Expiry_Date", expdate(credit_card)
|
|
190
|
+
xml.tag! "CardHoldersName", credit_card.name
|
|
191
|
+
xml.tag! "CardType", credit_card.brand
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def add_customer_data(xml, options)
|
|
195
|
+
xml.tag! "Customer_Ref", options[:customer] if options[:customer]
|
|
196
|
+
xml.tag! "Client_IP", options[:ip] if options[:ip]
|
|
197
|
+
xml.tag! "Client_Email", options[:email] if options[:email]
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def add_address(xml, options)
|
|
201
|
+
if address = (options[:billing_address] || options[:address])
|
|
202
|
+
xml.tag! "ZipCode", address[:zip]
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def add_invoice(xml, options)
|
|
207
|
+
xml.tag! "Reference_No", options[:order_id]
|
|
208
|
+
xml.tag! "Reference_3", options[:description] if options[:description]
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def expdate(credit_card)
|
|
212
|
+
"#{format(credit_card.month, :two_digits)}#{format(credit_card.year, :two_digits)}"
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def commit(action, request, credit_card = nil)
|
|
216
|
+
url = (test? ? self.test_url : self.live_url)
|
|
217
|
+
begin
|
|
218
|
+
response = parse(ssl_post(url, build_request(action, request), POST_HEADERS))
|
|
219
|
+
rescue ResponseError => e
|
|
220
|
+
response = parse_error(e.response)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
Response.new(successful?(response), message_from(response), response,
|
|
224
|
+
:test => test?,
|
|
225
|
+
:authorization => response_authorization(action, response, credit_card),
|
|
226
|
+
:avs_result => {:code => response[:avs]},
|
|
227
|
+
:cvv_result => response[:cvv2]
|
|
228
|
+
)
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def successful?(response)
|
|
232
|
+
response[:transaction_approved] == SUCCESS
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def response_authorization(action, response, credit_card)
|
|
236
|
+
if action == :store
|
|
237
|
+
store_authorization_from(response, credit_card)
|
|
238
|
+
else
|
|
239
|
+
authorization_from(response)
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def authorization_from(response)
|
|
244
|
+
if response[:authorization_num] && response[:transaction_tag]
|
|
245
|
+
[
|
|
246
|
+
response[:authorization_num],
|
|
247
|
+
response[:transaction_tag],
|
|
248
|
+
(response[:dollar_amount].to_f * 100).to_i
|
|
249
|
+
].join(";")
|
|
250
|
+
else
|
|
251
|
+
""
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def store_authorization_from(response, credit_card)
|
|
256
|
+
if response[:transarmor_token].present?
|
|
257
|
+
[
|
|
258
|
+
response[:transarmor_token],
|
|
259
|
+
credit_card.brand,
|
|
260
|
+
credit_card.first_name,
|
|
261
|
+
credit_card.last_name,
|
|
262
|
+
credit_card.month,
|
|
263
|
+
credit_card.year
|
|
264
|
+
].map { |value| value.to_s.gsub(/;/, "") }.join(";")
|
|
265
|
+
else
|
|
266
|
+
raise StandardError, "TransArmor support is not enabled on your #{display_name} account"
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def money_from_authorization(auth)
|
|
271
|
+
_, _, amount = auth.split(/;/, 3)
|
|
272
|
+
amount.to_i # return the # of cents, no need to divide
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def message_from(response)
|
|
276
|
+
if(response[:faultcode] && response[:faultstring])
|
|
277
|
+
response[:faultstring]
|
|
278
|
+
elsif(response[:error_number] && response[:error_number] != "0")
|
|
279
|
+
response[:error_description]
|
|
280
|
+
else
|
|
281
|
+
result = (response[:exact_message] || "")
|
|
282
|
+
result << " - #{response[:bank_message]}" if response[:bank_message].present?
|
|
283
|
+
result
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def parse_error(error)
|
|
288
|
+
{
|
|
289
|
+
:transaction_approved => "false",
|
|
290
|
+
:error_number => error.code,
|
|
291
|
+
:error_description => error.body
|
|
292
|
+
}
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def parse(xml)
|
|
296
|
+
response = {}
|
|
297
|
+
xml = REXML::Document.new(xml)
|
|
298
|
+
|
|
299
|
+
if root = REXML::XPath.first(xml, "//TransactionResult")
|
|
300
|
+
parse_elements(response, root)
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
response.delete_if{ |k,v| SENSITIVE_FIELDS.include?(k) }
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def parse_elements(response, root)
|
|
307
|
+
root.elements.to_a.each do |node|
|
|
308
|
+
response[node.name.gsub(/EXact/, "Exact").underscore.to_sym] = (node.text || "").strip
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
end
|
|
313
|
+
end
|
|
314
|
+
|
|
@@ -9,12 +9,23 @@ module ActiveMerchant #:nodoc:
|
|
|
9
9
|
#
|
|
10
10
|
# ActiveMerchant expects the amounts to be given as an Integer in cents. In this case, 10 EUR becomes 1000.
|
|
11
11
|
#
|
|
12
|
+
# Create certificates for authentication:
|
|
13
|
+
#
|
|
14
|
+
# The PEM file expected should contain both the certificate and the generated PEM file.
|
|
15
|
+
# Some sample shell commands to generate the certificates:
|
|
16
|
+
#
|
|
17
|
+
# openssl genrsa -aes128 -out priv.pem -passout pass:[YOUR PASSWORD] 1024
|
|
18
|
+
# openssl req -x509 -new -key priv.pem -passin pass:[YOUR PASSWORD] -days 3000 -out cert.cer
|
|
19
|
+
# cat cert.cer priv.pem > ideal.pem
|
|
20
|
+
#
|
|
21
|
+
# Following the steps above, upload cert.cer to the ideal web interface and pass the path of ideal.pem to the :pem option.
|
|
22
|
+
#
|
|
12
23
|
# Configure the gateway using your iDEAL bank account info and security settings:
|
|
13
24
|
#
|
|
14
25
|
# Create gateway:
|
|
15
26
|
# gateway = ActiveMerchant::Billing::IdealRabobankGateway.new(
|
|
16
|
-
# :login => '123456789', # merchant number
|
|
17
|
-
# :pem => File.read(
|
|
27
|
+
# :login => '123456789', # 9 digit merchant number
|
|
28
|
+
# :pem => File.read(Rails.root + 'config/ideal.pem'),
|
|
18
29
|
# :password => 'password' # password for the PEM key
|
|
19
30
|
# )
|
|
20
31
|
#
|
|
@@ -38,8 +38,14 @@ module ActiveMerchant #:nodoc:
|
|
|
38
38
|
super
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
def authorize(money,
|
|
42
|
-
|
|
41
|
+
def authorize(money, payment_source, options = {})
|
|
42
|
+
setup_address_hash(options)
|
|
43
|
+
|
|
44
|
+
if payment_source.respond_to?(:number)
|
|
45
|
+
commit(build_purchase_request('PREAUTH', money, payment_source, options), options)
|
|
46
|
+
else
|
|
47
|
+
commit(build_reference_request('PREAUTH', money, payment_source, options), options)
|
|
48
|
+
end
|
|
43
49
|
end
|
|
44
50
|
|
|
45
51
|
def purchase(money, payment_source, options = {})
|