activemerchant 1.29.1 → 1.30.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 +48 -0
- data/CONTRIBUTORS +19 -0
- data/README.md +43 -41
- data/lib/active_merchant/billing/check.rb +15 -11
- data/lib/active_merchant/billing/credit_card.rb +5 -1
- data/lib/active_merchant/billing/credit_card_formatting.rb +8 -8
- data/lib/active_merchant/billing/gateway.rb +1 -1
- data/lib/active_merchant/billing/gateways/authorize_net.rb +9 -1
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +15 -4
- 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/beanstream/beanstream_core.rb +6 -2
- data/lib/active_merchant/billing/gateways/beanstream.rb +26 -24
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +5 -2
- data/lib/active_merchant/billing/gateways/cyber_source.rb +55 -22
- 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/firstdata_e4.rb +222 -0
- data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +13 -2
- data/lib/active_merchant/billing/gateways/litle.rb +50 -19
- 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 +3 -5
- 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/netbilling.rb +1 -0
- data/lib/active_merchant/billing/gateways/netpay.rb +223 -0
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +18 -3
- data/lib/active_merchant/billing/gateways/orbital.rb +9 -5
- data/lib/active_merchant/billing/gateways/payment_express.rb +62 -1
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +1 -1
- data/lib/active_merchant/billing/gateways/paypal_express.rb +2 -0
- data/lib/active_merchant/billing/gateways/pin.rb +157 -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_pay.rb +6 -0
- data/lib/active_merchant/billing/gateways/smart_ps.rb +1 -1
- data/lib/active_merchant/billing/gateways/spreedly_core.rb +235 -0
- data/lib/active_merchant/billing/gateways/stripe.rb +1 -0
- data/lib/active_merchant/billing/gateways/wirecard.rb +15 -9
- data/lib/active_merchant/billing/gateways/worldpay.rb +15 -4
- data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +4 -1
- data/lib/active_merchant/billing/integrations/paypal/notification.rb +39 -31
- data/lib/active_merchant/billing/integrations/quickpay/helper.rb +13 -10
- data/lib/active_merchant/billing/integrations/quickpay/notification.rb +14 -14
- data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +2 -2
- data/lib/active_merchant/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +109 -49
- metadata.gz.sig +0 -0
|
@@ -44,22 +44,40 @@ module ActiveMerchant #:nodoc:
|
|
|
44
44
|
fraud_http_accept_encoding fraud_http_accept_charset
|
|
45
45
|
fraud_http_referer fraud_http_user_agent apikey),
|
|
46
46
|
|
|
47
|
-
:capture => %w(protocol msgtype merchant amount transaction
|
|
48
|
-
fraud_remote_addr fraud_http_accept
|
|
49
|
-
fraud_http_accept_language fraud_http_accept_encoding
|
|
50
|
-
fraud_http_accept_charset fraud_http_referer
|
|
51
|
-
fraud_http_user_agent apikey),
|
|
47
|
+
:capture => %w(protocol msgtype merchant amount transaction apikey),
|
|
52
48
|
|
|
53
|
-
:cancel => %w(protocol msgtype merchant transaction
|
|
54
|
-
|
|
49
|
+
:cancel => %w(protocol msgtype merchant transaction apikey),
|
|
50
|
+
|
|
51
|
+
:refund => %w(protocol msgtype merchant amount transaction apikey),
|
|
52
|
+
|
|
53
|
+
:subscribe => %w(protocol msgtype merchant ordernumber cardnumber
|
|
54
|
+
expirationdate cvd cardtypelock description testmode
|
|
55
|
+
fraud_remote_addr fraud_http_accept fraud_http_accept_language
|
|
55
56
|
fraud_http_accept_encoding fraud_http_accept_charset
|
|
56
57
|
fraud_http_referer fraud_http_user_agent apikey),
|
|
57
58
|
|
|
58
|
-
:
|
|
59
|
-
|
|
59
|
+
:recurring => %w(protocol msgtype merchant ordernumber amount currency
|
|
60
|
+
autocapture transaction apikey),
|
|
61
|
+
|
|
62
|
+
:status => %w(protocol msgtype merchant transaction apikey),
|
|
63
|
+
|
|
64
|
+
:chstatus => %w(protocol msgtype merchant apikey)
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
5 => {
|
|
68
|
+
:authorize => %w(protocol msgtype merchant ordernumber amount
|
|
69
|
+
currency autocapture cardnumber expirationdate cvd
|
|
70
|
+
cardtypelock testmode fraud_remote_addr
|
|
71
|
+
fraud_http_accept fraud_http_accept_language
|
|
60
72
|
fraud_http_accept_encoding fraud_http_accept_charset
|
|
61
73
|
fraud_http_referer fraud_http_user_agent apikey),
|
|
62
74
|
|
|
75
|
+
:capture => %w(protocol msgtype merchant amount transaction apikey),
|
|
76
|
+
|
|
77
|
+
:cancel => %w(protocol msgtype merchant transaction apikey),
|
|
78
|
+
|
|
79
|
+
:refund => %w(protocol msgtype merchant amount transaction apikey),
|
|
80
|
+
|
|
63
81
|
:subscribe => %w(protocol msgtype merchant ordernumber cardnumber
|
|
64
82
|
expirationdate cvd cardtypelock description testmode
|
|
65
83
|
fraud_remote_addr fraud_http_accept fraud_http_accept_language
|
|
@@ -67,20 +85,40 @@ module ActiveMerchant #:nodoc:
|
|
|
67
85
|
fraud_http_referer fraud_http_user_agent apikey),
|
|
68
86
|
|
|
69
87
|
:recurring => %w(protocol msgtype merchant ordernumber amount currency
|
|
70
|
-
autocapture transaction
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
fraud_http_user_agent apikey),
|
|
88
|
+
autocapture transaction apikey),
|
|
89
|
+
|
|
90
|
+
:status => %w(protocol msgtype merchant transaction apikey),
|
|
74
91
|
|
|
75
|
-
:
|
|
92
|
+
:chstatus => %w(protocol msgtype merchant apikey)
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
6 => {
|
|
96
|
+
:authorize => %w(protocol msgtype merchant ordernumber amount
|
|
97
|
+
currency autocapture cardnumber expirationdate cvd
|
|
98
|
+
cardtypelock testmode fraud_remote_addr
|
|
76
99
|
fraud_http_accept fraud_http_accept_language
|
|
77
100
|
fraud_http_accept_encoding fraud_http_accept_charset
|
|
78
101
|
fraud_http_referer fraud_http_user_agent apikey),
|
|
79
102
|
|
|
80
|
-
:
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
103
|
+
:capture => %w(protocol msgtype merchant amount transaction
|
|
104
|
+
apikey),
|
|
105
|
+
|
|
106
|
+
:cancel => %w(protocol msgtype merchant transaction apikey),
|
|
107
|
+
|
|
108
|
+
:refund => %w(protocol msgtype merchant amount transaction apikey),
|
|
109
|
+
|
|
110
|
+
:subscribe => %w(protocol msgtype merchant ordernumber cardnumber
|
|
111
|
+
expirationdate cvd cardtypelock description testmode
|
|
112
|
+
fraud_remote_addr fraud_http_accept fraud_http_accept_language
|
|
113
|
+
fraud_http_accept_encoding fraud_http_accept_charset
|
|
114
|
+
fraud_http_referer fraud_http_user_agent apikey),
|
|
115
|
+
|
|
116
|
+
:recurring => %w(protocol msgtype merchant ordernumber amount currency
|
|
117
|
+
autocapture transaction apikey),
|
|
118
|
+
|
|
119
|
+
:status => %w(protocol msgtype merchant transaction apikey),
|
|
120
|
+
|
|
121
|
+
:chstatus => %w(protocol msgtype merchant apikey)
|
|
84
122
|
}
|
|
85
123
|
}
|
|
86
124
|
|
|
@@ -89,7 +127,7 @@ module ActiveMerchant #:nodoc:
|
|
|
89
127
|
# The login is the QuickpayId
|
|
90
128
|
# The password is the md5checkword from the Quickpay manager
|
|
91
129
|
# To use the API-key from the Quickpay manager, specify :api-key
|
|
92
|
-
# Using the API-key, requires that you use version 4
|
|
130
|
+
# Using the API-key, requires that you use version 4+. Specify :version => 4/5/6 in options.
|
|
93
131
|
def initialize(options = {})
|
|
94
132
|
requires!(options, :login, :password)
|
|
95
133
|
@protocol = options.delete(:version) || 3 # default to protocol version 3
|
|
@@ -99,26 +137,30 @@ module ActiveMerchant #:nodoc:
|
|
|
99
137
|
def authorize(money, credit_card_or_reference, options = {})
|
|
100
138
|
post = {}
|
|
101
139
|
|
|
140
|
+
action = recurring_or_authorize(credit_card_or_reference)
|
|
141
|
+
|
|
102
142
|
add_amount(post, money, options)
|
|
103
143
|
add_invoice(post, options)
|
|
104
144
|
add_creditcard_or_reference(post, credit_card_or_reference, options)
|
|
105
145
|
add_autocapture(post, false)
|
|
106
|
-
add_fraud_parameters(post, options)
|
|
146
|
+
add_fraud_parameters(post, options) if action.eql?(:authorize)
|
|
107
147
|
add_testmode(post)
|
|
108
148
|
|
|
109
|
-
commit(
|
|
149
|
+
commit(action, post)
|
|
110
150
|
end
|
|
111
151
|
|
|
112
152
|
def purchase(money, credit_card_or_reference, options = {})
|
|
113
153
|
post = {}
|
|
114
154
|
|
|
155
|
+
action = recurring_or_authorize(credit_card_or_reference)
|
|
156
|
+
|
|
115
157
|
add_amount(post, money, options)
|
|
116
158
|
add_creditcard_or_reference(post, credit_card_or_reference, options)
|
|
117
159
|
add_invoice(post, options)
|
|
118
|
-
add_fraud_parameters(post, options)
|
|
160
|
+
add_fraud_parameters(post, options) if action.eql?(:authorize)
|
|
119
161
|
add_autocapture(post, true)
|
|
120
162
|
|
|
121
|
-
commit(
|
|
163
|
+
commit(action, post)
|
|
122
164
|
end
|
|
123
165
|
|
|
124
166
|
def capture(money, authorization, options = {})
|
|
@@ -126,8 +168,6 @@ module ActiveMerchant #:nodoc:
|
|
|
126
168
|
|
|
127
169
|
add_reference(post, authorization)
|
|
128
170
|
add_amount_without_currency(post, money)
|
|
129
|
-
add_fraud_parameters(post, options)
|
|
130
|
-
|
|
131
171
|
commit(:capture, post)
|
|
132
172
|
end
|
|
133
173
|
|
|
@@ -135,7 +175,6 @@ module ActiveMerchant #:nodoc:
|
|
|
135
175
|
post = {}
|
|
136
176
|
|
|
137
177
|
add_reference(post, identification)
|
|
138
|
-
add_fraud_parameters(post, options)
|
|
139
178
|
|
|
140
179
|
commit(:cancel, post)
|
|
141
180
|
end
|
|
@@ -145,7 +184,6 @@ module ActiveMerchant #:nodoc:
|
|
|
145
184
|
|
|
146
185
|
add_amount_without_currency(post, money)
|
|
147
186
|
add_reference(post, identification)
|
|
148
|
-
add_fraud_parameters(post, options)
|
|
149
187
|
|
|
150
188
|
commit(:refund, post)
|
|
151
189
|
end
|
|
@@ -219,7 +257,7 @@ module ActiveMerchant #:nodoc:
|
|
|
219
257
|
end
|
|
220
258
|
|
|
221
259
|
def add_fraud_parameters(post, options)
|
|
222
|
-
if @protocol
|
|
260
|
+
if @protocol >= 4
|
|
223
261
|
post[:fraud_remote_addr] = options[:fraud_remote_addr] if options[:fraud_remote_addr]
|
|
224
262
|
post[:fraud_http_accept] = options[:fraud_http_accept] if options[:fraud_http_accept]
|
|
225
263
|
post[:fraud_http_accept_language] = options[:fraud_http_accept_language] if options[:fraud_http_accept_language]
|
|
@@ -65,6 +65,7 @@ module ActiveMerchant #:nodoc:
|
|
|
65
65
|
add_credit_card(post, credit_card)
|
|
66
66
|
add_address(post, options)
|
|
67
67
|
add_customer_data(post, options)
|
|
68
|
+
add_optional_data(post, options)
|
|
68
69
|
|
|
69
70
|
commit(:purchase, post)
|
|
70
71
|
end
|
|
@@ -79,6 +80,7 @@ module ActiveMerchant #:nodoc:
|
|
|
79
80
|
add_credit_card(post, credit_card)
|
|
80
81
|
add_address(post, options)
|
|
81
82
|
add_customer_data(post, options)
|
|
83
|
+
add_optional_data(post, options)
|
|
82
84
|
|
|
83
85
|
commit(:authorization, post)
|
|
84
86
|
end
|
|
@@ -156,6 +158,10 @@ module ActiveMerchant #:nodoc:
|
|
|
156
158
|
add_pair(post, :ClientIPAddress, options[:ip])
|
|
157
159
|
end
|
|
158
160
|
|
|
161
|
+
def add_optional_data(post, options)
|
|
162
|
+
add_pair(post, :GiftAidPayment, options[:gift_aid_payment]) unless options[:gift_aid_payment].blank?
|
|
163
|
+
end
|
|
164
|
+
|
|
159
165
|
def add_address(post, options)
|
|
160
166
|
if billing_address = options[:billing_address] || options[:address]
|
|
161
167
|
first_name, last_name = parse_first_and_last_name(billing_address[:name])
|
|
@@ -221,7 +221,7 @@ module ActiveMerchant #:nodoc:
|
|
|
221
221
|
parameters[:amount] = amount(money) if money
|
|
222
222
|
response = parse( ssl_post(self.live_url, post_data(action,parameters)) )
|
|
223
223
|
Response.new(response["response"] == "1", message_from(response), response,
|
|
224
|
-
:authorization => response["transactionid"],
|
|
224
|
+
:authorization => (response["transactionid"] || response["customer_vault_id"]),
|
|
225
225
|
:test => test?,
|
|
226
226
|
:cvv_result => response["cvvresponse"],
|
|
227
227
|
:avs_result => { :code => response["avsresponse"] }
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
require 'nokogiri'
|
|
2
|
+
|
|
3
|
+
module ActiveMerchant #:nodoc:
|
|
4
|
+
module Billing #:nodoc:
|
|
5
|
+
# Public: This gateway allows you to interact with any gateway you've
|
|
6
|
+
# created in Spreedly Core (https://spreedlycore.com). It's an adapter
|
|
7
|
+
# which can be particularly useful if you already have code interacting with
|
|
8
|
+
# ActiveMerchant and want to easily take advantage of Core's vault.
|
|
9
|
+
class SpreedlyCoreGateway < Gateway
|
|
10
|
+
self.live_url = 'https://spreedlycore.com/v1'
|
|
11
|
+
|
|
12
|
+
self.supported_countries = %w(AD AE AT AU BD BE BG BN CA CH CY CZ DE DK EE EG ES FI FR GB
|
|
13
|
+
GI GR HK HU ID IE IL IM IN IS IT JO KW LB LI LK LT LU LV MC
|
|
14
|
+
MT MU MV MX MY NL NO NZ OM PH PL PT QA RO SA SE SG SI SK SM
|
|
15
|
+
TR TT UM US VA VN ZA)
|
|
16
|
+
|
|
17
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
|
18
|
+
self.homepage_url = 'https://spreedlycore.com'
|
|
19
|
+
self.display_name = 'Spreedly Core'
|
|
20
|
+
self.money_format = :cents
|
|
21
|
+
self.default_currency = 'USD'
|
|
22
|
+
|
|
23
|
+
# Public: Create a new Spreedly Core Gateway.
|
|
24
|
+
#
|
|
25
|
+
# options - A hash of options:
|
|
26
|
+
# :login - Your Spreedly Core API login.
|
|
27
|
+
# :password - Your Spreedly Core API secret.
|
|
28
|
+
# :gateway_token - The token of the gateway you've created in
|
|
29
|
+
# Spreedly Core.
|
|
30
|
+
def initialize(options = {})
|
|
31
|
+
requires!(options, :login, :password, :gateway_token)
|
|
32
|
+
super
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Public: Run a purchase transaction.
|
|
36
|
+
#
|
|
37
|
+
# money - The monetary amount of the transaction in cents.
|
|
38
|
+
# payment_method - The CreditCard or the Spreedly Core payment method
|
|
39
|
+
# token.
|
|
40
|
+
# options - A standard ActiveMerchant options hash
|
|
41
|
+
def purchase(money, payment_method, options = {})
|
|
42
|
+
if payment_method.is_a?(String)
|
|
43
|
+
purchase_with_token(money, payment_method, options)
|
|
44
|
+
else
|
|
45
|
+
MultiResponse.run do |r|
|
|
46
|
+
r.process { save_card(false, payment_method, options) }
|
|
47
|
+
r.process { purchase_with_token(money, r.authorization, options) }
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Public: Run an authorize transaction.
|
|
53
|
+
#
|
|
54
|
+
# money - The monetary amount of the transaction in cents.
|
|
55
|
+
# payment_method - The CreditCard or the Spreedly Core payment method
|
|
56
|
+
# token.
|
|
57
|
+
# options - A standard ActiveMerchant options hash
|
|
58
|
+
def authorize(money, payment_method, options = {})
|
|
59
|
+
if payment_method.is_a?(String)
|
|
60
|
+
authorize_with_token(money, payment_method, options)
|
|
61
|
+
else
|
|
62
|
+
MultiResponse.run do |r|
|
|
63
|
+
r.process { save_card(false, payment_method, options) }
|
|
64
|
+
r.process { authorize_with_token(money, r.authorization, options) }
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def capture(money, authorization, options={})
|
|
70
|
+
request = build_xml_request('transaction') do |doc|
|
|
71
|
+
add_invoice(doc, money, options)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
commit("transactions/#{authorization}/capture.xml", request)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def refund(money, authorization, options={})
|
|
78
|
+
request = build_xml_request('transaction') do |doc|
|
|
79
|
+
add_invoice(doc, money, options)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
commit("transactions/#{authorization}/credit.xml", request)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def void(authorization, options={})
|
|
86
|
+
commit("transactions/#{authorization}/void.xml", '')
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Public: Store a credit card in the Spreedly Core vault and retain it.
|
|
90
|
+
#
|
|
91
|
+
# credit_card - The CreditCard to store
|
|
92
|
+
# options - A standard ActiveMerchant options hash
|
|
93
|
+
def store(credit_card, options={})
|
|
94
|
+
save_card(true, credit_card, options)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Public: Redact the CreditCard in Spreedly Core. This wipes the
|
|
98
|
+
# sensitive payment information from the card.
|
|
99
|
+
#
|
|
100
|
+
# credit_card - The CreditCard to store
|
|
101
|
+
# options - A standard ActiveMerchant options hash
|
|
102
|
+
def unstore(authorization, options={})
|
|
103
|
+
commit("payment_methods/#{authorization}/redact.xml", '', :put)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
private
|
|
107
|
+
def save_card(retain, credit_card, options)
|
|
108
|
+
request = build_xml_request('payment_method') do |doc|
|
|
109
|
+
add_credit_card(doc, credit_card, options)
|
|
110
|
+
add_data(doc, options)
|
|
111
|
+
doc.retained(true) if retain
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
commit("payment_methods.xml", request, :post, :payment_method_token)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def purchase_with_token(money, payment_method_token, options)
|
|
118
|
+
request = auth_purchase_request(money, payment_method_token, options)
|
|
119
|
+
commit("gateways/#{@options[:gateway_token]}/purchase.xml", request)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def authorize_with_token(money, payment_method_token, options)
|
|
123
|
+
request = auth_purchase_request(money, payment_method_token, options)
|
|
124
|
+
commit("gateways/#{@options[:gateway_token]}/authorize.xml", request)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def auth_purchase_request(money, payment_method_token, options)
|
|
128
|
+
build_xml_request('transaction') do |doc|
|
|
129
|
+
add_invoice(doc, money, options)
|
|
130
|
+
doc.payment_method_token(payment_method_token)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def add_invoice(doc, money, options)
|
|
135
|
+
doc.amount amount(money)
|
|
136
|
+
doc.currency_code(options[:currency] || currency(money) || default_currency)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def add_credit_card(doc, credit_card, options)
|
|
140
|
+
doc.credit_card do
|
|
141
|
+
doc.number(credit_card.number)
|
|
142
|
+
doc.first_name(credit_card.first_name)
|
|
143
|
+
doc.last_name(credit_card.last_name)
|
|
144
|
+
doc.month(credit_card.month)
|
|
145
|
+
doc.year(credit_card.year)
|
|
146
|
+
doc.email(options[:email])
|
|
147
|
+
doc.address1(options[:billing_address].try(:[], :address1))
|
|
148
|
+
doc.address2(options[:billing_address].try(:[], :address2))
|
|
149
|
+
doc.city(options[:billing_address].try(:[], :city))
|
|
150
|
+
doc.state(options[:billing_address].try(:[], :state))
|
|
151
|
+
doc.zip(options[:billing_address].try(:[], :zip))
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def add_data(doc, options)
|
|
156
|
+
doc.data do
|
|
157
|
+
data_to_doc(doc, options[:data])
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def data_to_doc(doc, value)
|
|
162
|
+
return doc.text value unless value.kind_of? Hash
|
|
163
|
+
value.each do |k, v|
|
|
164
|
+
doc.send(k) do
|
|
165
|
+
data_to_doc(doc, v)
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def parse(xml)
|
|
171
|
+
response = {}
|
|
172
|
+
|
|
173
|
+
doc = Nokogiri::XML(xml)
|
|
174
|
+
doc.root.xpath('*').each do |node|
|
|
175
|
+
if (node.elements.empty?)
|
|
176
|
+
response[node.name.downcase.to_sym] = node.text
|
|
177
|
+
else
|
|
178
|
+
node.elements.each do |childnode|
|
|
179
|
+
childnode_to_response(response, node, childnode)
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
response
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def childnode_to_response(response, node, childnode)
|
|
188
|
+
name = "#{node.name.downcase}_#{childnode.name.downcase}"
|
|
189
|
+
if name == 'payment_method_data' && !childnode.elements.empty?
|
|
190
|
+
response[name.to_sym] = Hash.from_xml(childnode.to_s).values.first
|
|
191
|
+
else
|
|
192
|
+
response[name.to_sym] = childnode.text
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def build_xml_request(root)
|
|
197
|
+
builder = Nokogiri::XML::Builder.new
|
|
198
|
+
builder.__send__(root) do |doc|
|
|
199
|
+
yield(doc)
|
|
200
|
+
end
|
|
201
|
+
builder.to_xml
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def commit(relative_url, request, method = :post, authorization_field = :token)
|
|
205
|
+
begin
|
|
206
|
+
raw_response = ssl_request(method, "#{live_url}/#{relative_url}", request, headers)
|
|
207
|
+
rescue ResponseError => e
|
|
208
|
+
raw_response = e.response.body
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
response_from(raw_response, authorization_field)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def response_from(raw_response, authorization_field)
|
|
215
|
+
parsed = parse(raw_response)
|
|
216
|
+
options = {
|
|
217
|
+
:authorization => parsed[authorization_field],
|
|
218
|
+
:test => (parsed[:on_test_gateway] == 'true'),
|
|
219
|
+
:avs_result => { :code => parsed[:response_avs_code] },
|
|
220
|
+
:cvv_result => parsed[:response_cvv_code]
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
Response.new(parsed[:succeeded] == 'true', parsed[:message] || parsed[:error], parsed, options)
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def headers
|
|
227
|
+
{
|
|
228
|
+
'Authorization' => ('Basic ' + Base64.strict_encode64("#{@options[:login]}:#{@options[:password]}").chomp),
|
|
229
|
+
'Content-Type' => 'text/xml'
|
|
230
|
+
}
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
@@ -50,6 +50,7 @@ module ActiveMerchant #:nodoc:
|
|
|
50
50
|
add_customer(post, options)
|
|
51
51
|
add_customer_data(post,options)
|
|
52
52
|
post[:description] = options[:description] || options[:email]
|
|
53
|
+
post[:application_fee] = options[:application_fee] if options[:application_fee]
|
|
53
54
|
add_flags(post, options)
|
|
54
55
|
|
|
55
56
|
meta = generate_meta(options)
|
|
@@ -16,7 +16,7 @@ module ActiveMerchant #:nodoc:
|
|
|
16
16
|
'xsi:noNamespaceSchemaLocation' => 'wirecard.xsd'
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
PERMITTED_TRANSACTIONS = %w[
|
|
19
|
+
PERMITTED_TRANSACTIONS = %w[ PREAUTHORIZATION CAPTURE PURCHASE ]
|
|
20
20
|
|
|
21
21
|
RETURN_CODES = %w[ ACK NOK ]
|
|
22
22
|
|
|
@@ -63,13 +63,13 @@ module ActiveMerchant #:nodoc:
|
|
|
63
63
|
# Authorization
|
|
64
64
|
def authorize(money, creditcard, options = {})
|
|
65
65
|
options[:credit_card] = creditcard
|
|
66
|
-
commit(:
|
|
66
|
+
commit(:preauthorization, money, options)
|
|
67
67
|
end
|
|
68
68
|
|
|
69
69
|
# Capture Authorization
|
|
70
70
|
def capture(money, authorization, options = {})
|
|
71
|
-
options[:
|
|
72
|
-
commit(:
|
|
71
|
+
options[:preauthorization] = authorization
|
|
72
|
+
commit(:capture, money, options)
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
# Purchase
|
|
@@ -148,16 +148,17 @@ module ActiveMerchant #:nodoc:
|
|
|
148
148
|
options[:order_id] ||= generate_unique_id
|
|
149
149
|
|
|
150
150
|
xml.tag! "FNC_CC_#{options[:action].to_s.upcase}" do
|
|
151
|
-
xml.tag! 'FunctionID', options[:description]
|
|
151
|
+
xml.tag! 'FunctionID', options[:description].to_s.slice(0,32)
|
|
152
152
|
xml.tag! 'CC_TRANSACTION' do
|
|
153
153
|
xml.tag! 'TransactionID', options[:order_id]
|
|
154
154
|
case options[:action]
|
|
155
|
-
when :
|
|
155
|
+
when :preauthorization, :purchase
|
|
156
156
|
add_invoice(xml, money, options)
|
|
157
157
|
add_creditcard(xml, options[:credit_card])
|
|
158
158
|
add_address(xml, options[:billing_address])
|
|
159
|
-
when :
|
|
160
|
-
xml.tag! 'GuWID', options[:
|
|
159
|
+
when :capture
|
|
160
|
+
xml.tag! 'GuWID', options[:preauthorization]
|
|
161
|
+
add_amount(xml, money)
|
|
161
162
|
end
|
|
162
163
|
end
|
|
163
164
|
end
|
|
@@ -165,7 +166,7 @@ module ActiveMerchant #:nodoc:
|
|
|
165
166
|
|
|
166
167
|
# Includes the payment (amount, currency, country) to the transaction-xml
|
|
167
168
|
def add_invoice(xml, money, options)
|
|
168
|
-
xml
|
|
169
|
+
add_amount(xml, money)
|
|
169
170
|
xml.tag! 'Currency', options[:currency] || currency(money)
|
|
170
171
|
xml.tag! 'CountryCode', options[:billing_address][:country]
|
|
171
172
|
xml.tag! 'RECURRING_TRANSACTION' do
|
|
@@ -173,6 +174,11 @@ module ActiveMerchant #:nodoc:
|
|
|
173
174
|
end
|
|
174
175
|
end
|
|
175
176
|
|
|
177
|
+
# Include the amount in the transaction-xml
|
|
178
|
+
def add_amount(xml, money)
|
|
179
|
+
xml.tag! 'Amount', amount(money)
|
|
180
|
+
end
|
|
181
|
+
|
|
176
182
|
# Includes the credit-card data to the transaction-xml
|
|
177
183
|
def add_creditcard(xml, creditcard)
|
|
178
184
|
raise "Creditcard must be supplied!" if creditcard.nil?
|
|
@@ -38,6 +38,10 @@ module ActiveMerchant #:nodoc:
|
|
|
38
38
|
def capture(money, authorization, options = {})
|
|
39
39
|
MultiResponse.run do |r|
|
|
40
40
|
r.process{inquire_request(authorization, options, "AUTHORISED")} unless options[:authorization_validated]
|
|
41
|
+
if r.params
|
|
42
|
+
authorization_currency = r.params['amount_currency_code']
|
|
43
|
+
options = options.merge(:currency => authorization_currency) if authorization_currency.present?
|
|
44
|
+
end
|
|
41
45
|
r.process{capture_request(money, authorization, options)}
|
|
42
46
|
end
|
|
43
47
|
end
|
|
@@ -148,10 +152,10 @@ module ActiveMerchant #:nodoc:
|
|
|
148
152
|
end
|
|
149
153
|
|
|
150
154
|
def add_amount(xml, money, options)
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
+
currency = options[:currency] || currency(money)
|
|
156
|
+
amount = localized_amount(money, currency)
|
|
157
|
+
|
|
158
|
+
xml.tag! 'amount', :value => amount, 'currencyCode' => currency, 'exponent' => 2
|
|
155
159
|
end
|
|
156
160
|
|
|
157
161
|
def add_payment_method(xml, amount, payment_method, options)
|
|
@@ -261,6 +265,13 @@ module ActiveMerchant #:nodoc:
|
|
|
261
265
|
credentials = "#{@options[:login]}:#{@options[:password]}"
|
|
262
266
|
"Basic #{[credentials].pack('m').strip}"
|
|
263
267
|
end
|
|
268
|
+
|
|
269
|
+
def localized_amount(money, currency)
|
|
270
|
+
amount = amount(money)
|
|
271
|
+
return amount unless CURRENCIES_WITHOUT_FRACTIONS.include?(currency.to_s)
|
|
272
|
+
|
|
273
|
+
amount.to_i / 100 * 100
|
|
274
|
+
end
|
|
264
275
|
end
|
|
265
276
|
end
|
|
266
277
|
end
|
|
@@ -20,7 +20,6 @@ module ActiveMerchant #:nodoc:
|
|
|
20
20
|
mapping :credential2, 'pwd'
|
|
21
21
|
mapping :credential3, 'partner'
|
|
22
22
|
mapping :order, 'user1'
|
|
23
|
-
mapping :description, 'description'
|
|
24
23
|
|
|
25
24
|
mapping :amount, 'amt'
|
|
26
25
|
|
|
@@ -35,6 +34,10 @@ module ActiveMerchant #:nodoc:
|
|
|
35
34
|
|
|
36
35
|
mapping :customer, :name => 'name'
|
|
37
36
|
|
|
37
|
+
def description(value)
|
|
38
|
+
add_field('description', "#{value}".delete("#"))
|
|
39
|
+
end
|
|
40
|
+
|
|
38
41
|
def customer(params = {})
|
|
39
42
|
add_field(mappings[:customer][:name], [params.delete(:first_name), params.delete(:last_name)].compact.join(' '))
|
|
40
43
|
end
|