activemerchant 1.32.0 → 1.33.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.
Files changed (52) hide show
  1. data/CHANGELOG +50 -0
  2. data/CONTRIBUTORS +8 -0
  3. data/README.md +6 -4
  4. data/lib/active_merchant/billing/check.rb +4 -3
  5. data/lib/active_merchant/billing/credit_card.rb +7 -3
  6. data/lib/active_merchant/billing/gateways/authorize_net.rb +27 -7
  7. data/lib/active_merchant/billing/gateways/barclays_epdq.rb +8 -1
  8. data/lib/active_merchant/billing/gateways/blue_pay.rb +201 -185
  9. data/lib/active_merchant/billing/gateways/bogus.rb +1 -1
  10. data/lib/active_merchant/billing/gateways/card_stream_modern.rb +155 -0
  11. data/lib/active_merchant/billing/gateways/cc5.rb +0 -4
  12. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +94 -12
  13. data/lib/active_merchant/billing/gateways/garanti.rb +0 -4
  14. data/lib/active_merchant/billing/gateways/litle.rb +41 -11
  15. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +27 -6
  16. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +2 -2
  17. data/lib/active_merchant/billing/gateways/net_registry.rb +8 -3
  18. data/lib/active_merchant/billing/gateways/netaxept.rb +65 -117
  19. data/lib/active_merchant/billing/gateways/orbital.rb +181 -48
  20. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +12 -10
  21. data/lib/active_merchant/billing/gateways/paymill.rb +27 -13
  22. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +11 -6
  23. data/lib/active_merchant/billing/gateways/paypal_express.rb +25 -7
  24. data/lib/active_merchant/billing/gateways/pin.rb +5 -5
  25. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +16 -11
  26. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +1 -1
  27. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +21 -16
  28. data/lib/active_merchant/billing/gateways/sage.rb +10 -5
  29. data/lib/active_merchant/billing/gateways/sage_pay.rb +1 -0
  30. data/lib/active_merchant/billing/gateways/transnational.rb +239 -0
  31. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +9 -4
  32. data/lib/active_merchant/billing/integrations/direc_pay/status.rb +1 -1
  33. data/lib/active_merchant/billing/integrations/direc_pay.rb +1 -1
  34. data/lib/active_merchant/billing/integrations/dwolla/common.rb +21 -0
  35. data/lib/active_merchant/billing/integrations/dwolla/helper.rb +15 -6
  36. data/lib/active_merchant/billing/integrations/dwolla/notification.rb +11 -6
  37. data/lib/active_merchant/billing/integrations/dwolla/return.rb +12 -4
  38. data/lib/active_merchant/billing/integrations/dwolla.rb +5 -12
  39. data/lib/active_merchant/billing/integrations/notification.rb +13 -8
  40. data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +13 -1
  41. data/lib/active_merchant/billing/integrations/payu_in/helper.rb +74 -0
  42. data/lib/active_merchant/billing/integrations/payu_in/notification.rb +167 -0
  43. data/lib/active_merchant/billing/integrations/payu_in/return.rb +53 -0
  44. data/lib/active_merchant/billing/integrations/payu_in.rb +43 -0
  45. data/lib/active_merchant/billing/integrations/quickpay/notification.rb +68 -5
  46. data/lib/active_merchant/billing/integrations/rbkmoney/helper.rb +23 -0
  47. data/lib/active_merchant/billing/integrations/rbkmoney/notification.rb +91 -0
  48. data/lib/active_merchant/billing/integrations/rbkmoney.rb +17 -0
  49. data/lib/active_merchant/version.rb +1 -1
  50. data.tar.gz.sig +0 -0
  51. metadata +72 -62
  52. metadata.gz.sig +0 -0
@@ -1,3 +1,4 @@
1
+ require 'nokogiri'
1
2
  module ActiveMerchant #:nodoc:
2
3
  module Billing #:nodoc:
3
4
  module PayflowCommonAPI
@@ -140,17 +141,18 @@ module ActiveMerchant #:nodoc:
140
141
 
141
142
  def parse(data)
142
143
  response = {}
143
- xml = REXML::Document.new(data)
144
- root = REXML::XPath.first(xml, "//ResponseData")
144
+ xml = Nokogiri::XML(data)
145
+ xml.remove_namespaces!
146
+ root = xml.xpath("//ResponseData")
145
147
 
146
148
  # REXML::XPath in Ruby 1.8.6 is now unable to match nodes based on their attributes
147
- tx_result = REXML::XPath.first(root, "//TransactionResult")
149
+ tx_result = root.xpath(".//TransactionResult").first
148
150
 
149
- if tx_result && tx_result.attributes['Duplicate'] == "true"
151
+ if tx_result && tx_result.attributes['Duplicate'].to_s == "true"
150
152
  response[:duplicate] = true
151
153
  end
152
154
 
153
- root.elements.to_a.each do |node|
155
+ root.xpath(".//*").each do |node|
154
156
  parse_element(response, node)
155
157
  end
156
158
 
@@ -166,14 +168,14 @@ module ActiveMerchant #:nodoc:
166
168
  # in an RPPaymentResults element so we'll come here multiple times
167
169
  response[node_name] ||= []
168
170
  response[node_name] << ( payment_result_response = {} )
169
- node.elements.each{ |e| parse_element(payment_result_response, e) }
170
- when node.has_elements?
171
- node.elements.each{|e| parse_element(response, e) }
171
+ node.xpath(".//*").each{ |e| parse_element(payment_result_response, e) }
172
+ when node.xpath(".//*").to_a.any?
173
+ node.xpath(".//*").each{|e| parse_element(response, e) }
172
174
  when node_name.to_s =~ /amt$/
173
175
  # *Amt elements don't put the value in the #text - instead they use a Currency attribute
174
- response[node_name] = node.attributes['Currency']
176
+ response[node_name] = node.attributes['Currency'].to_s
175
177
  when node_name == :ext_data
176
- response[node.attributes['Name'].underscore.to_sym] = node.attributes['Value']
178
+ response[node.attributes['Name'].to_s.underscore.to_sym] = node.attributes['Value'].to_s
177
179
  else
178
180
  response[node_name] = node.text
179
181
  end
@@ -1,13 +1,13 @@
1
1
  module ActiveMerchant #:nodoc:
2
2
  module Billing #:nodoc:
3
3
  class PaymillGateway < Gateway
4
- self.supported_countries = %w(AD AT BE CY CZ DE DK EE ES FI FO FR GB GR
5
- HU IE IL IS IT LI LT LU LV MT NL NO PL PT
6
- SE SI SK TR VA)
4
+ self.supported_countries = %w(AD AT BE CH CY CZ DE DK EE ES FI FO FR GB GR
5
+ HU IE IL IS IT LI LT LU LV MT NL NO PL PT SE
6
+ SI SK TR VA)
7
7
 
8
8
  self.supported_cardtypes = [:visa, :master]
9
9
  self.homepage_url = 'https://paymill.com'
10
- self.display_name = 'Paymill'
10
+ self.display_name = 'PAYMILL'
11
11
  self.money_format = :cents
12
12
  self.default_currency = 'EUR'
13
13
 
@@ -16,17 +16,27 @@ module ActiveMerchant #:nodoc:
16
16
  super
17
17
  end
18
18
 
19
- def purchase(money, credit_card, options = {})
20
- MultiResponse.run do |r|
21
- r.process { save_card(credit_card) }
22
- r.process { purchase_with_token(money, r.authorization, options) }
19
+ def purchase(money, payment_method, options = {})
20
+ case payment_method
21
+ when String
22
+ purchase_with_token(money, payment_method, options)
23
+ else
24
+ MultiResponse.run do |r|
25
+ r.process { save_card(payment_method) }
26
+ r.process { purchase_with_token(money, r.authorization, options) }
27
+ end
23
28
  end
24
29
  end
25
30
 
26
- def authorize(money, credit_card, options = {})
27
- MultiResponse.run do |r|
28
- r.process { save_card(credit_card) }
29
- r.process { authorize_with_token(money, r.authorization, options) }
31
+ def authorize(money, payment_method, options = {})
32
+ case payment_method
33
+ when String
34
+ authorize_with_token(money, payment_method, options)
35
+ else
36
+ MultiResponse.run do |r|
37
+ r.process { save_card(payment_method) }
38
+ r.process { authorize_with_token(money, r.authorization, options) }
39
+ end
30
40
  end
31
41
  end
32
42
 
@@ -47,6 +57,10 @@ module ActiveMerchant #:nodoc:
47
57
  commit(:post, "refunds/#{transaction_id(authorization)}", post)
48
58
  end
49
59
 
60
+ def store(credit_card, options={})
61
+ save_card(credit_card)
62
+ end
63
+
50
64
  private
51
65
 
52
66
  def add_credit_card(post, credit_card)
@@ -140,7 +154,7 @@ module ActiveMerchant #:nodoc:
140
154
  end
141
155
 
142
156
  def save_card_url
143
- (test? ? 'https://test-token.paymill.com' : 'https://token-v2.paymill.com')
157
+ (test? ? 'https://test-token.paymill.com' : 'https://token-v2.paymill.de')
144
158
  end
145
159
 
146
160
  def post_data(params)
@@ -617,11 +617,11 @@ module ActiveMerchant #:nodoc:
617
617
  response = parse(action, ssl_post(endpoint_url, build_request(request), @options[:headers]))
618
618
 
619
619
  build_response(successful?(response), message_from(response), response,
620
- :test => test?,
621
- :authorization => authorization_from(response),
622
- :fraud_review => fraud_review?(response),
623
- :avs_result => { :code => response[:avs_code] },
624
- :cvv_result => response[:cvv2_code]
620
+ :test => test?,
621
+ :authorization => authorization_from(response),
622
+ :fraud_review => fraud_review?(response),
623
+ :avs_result => { :code => response[:avs_code] },
624
+ :cvv_result => response[:cvv2_code]
625
625
  )
626
626
  end
627
627
 
@@ -630,7 +630,12 @@ module ActiveMerchant #:nodoc:
630
630
  end
631
631
 
632
632
  def authorization_from(response)
633
- response[:transaction_id] || response[:authorization_id] || response[:refund_transaction_id] # middle one is from reauthorization
633
+ (
634
+ response[:transaction_id] ||
635
+ response[:authorization_id] ||
636
+ response[:refund_transaction_id] ||
637
+ response[:billing_agreement_id]
638
+ )
634
639
  end
635
640
 
636
641
  def successful?(response)
@@ -59,9 +59,19 @@ module ActiveMerchant #:nodoc:
59
59
  commit 'DoExpressCheckoutPayment', build_sale_or_authorization_request('Sale', money, options)
60
60
  end
61
61
 
62
- def reference_transaction(money, options = {})
62
+ def store(token, options = {})
63
+ commit 'CreateBillingAgreement', build_create_billing_agreement_request(token, options)
64
+ end
65
+
66
+ def authorize_reference_transaction(money, options = {})
63
67
  requires!(options, :reference_id, :payment_type, :invoice_id, :description, :ip)
64
68
 
69
+ commit 'DoReferenceTransaction', build_reference_transaction_request('Authorization', money, options)
70
+ end
71
+
72
+ def reference_transaction(money, options = {})
73
+ requires!(options, :reference_id)
74
+
65
75
  commit 'DoReferenceTransaction', build_reference_transaction_request('Sale', money, options)
66
76
  end
67
77
 
@@ -142,7 +152,7 @@ module ActiveMerchant #:nodoc:
142
152
  end
143
153
  xml.tag! 'n2:CallbackURL', options[:callback_url] unless options[:callback_url].blank?
144
154
 
145
- add_payment_details(xml, with_money_default(money), currency_code, options)
155
+ add_payment_details(xml, money, currency_code, options)
146
156
  if options[:shipping_options]
147
157
  options[:shipping_options].each do |shipping_option|
148
158
  xml.tag! 'n2:FlatRateShippingOptions' do
@@ -166,6 +176,18 @@ module ActiveMerchant #:nodoc:
166
176
  xml.target!
167
177
  end
168
178
 
179
+ def build_create_billing_agreement_request(token, options = {})
180
+ xml = Builder::XmlMarkup.new :indent => 2
181
+ xml.tag! 'CreateBillingAgreementReq', 'xmlns' => PAYPAL_NAMESPACE do
182
+ xml.tag! 'CreateBillingAgreementRequest', 'xmlns:n2' => EBAY_NAMESPACE do
183
+ xml.tag! 'n2:Version', API_VERSION
184
+ xml.tag! 'Token', token
185
+ end
186
+ end
187
+
188
+ xml.target!
189
+ end
190
+
169
191
  def build_reference_transaction_request(action, money, options)
170
192
  currency_code = options[:currency] || currency(money)
171
193
 
@@ -179,7 +201,7 @@ module ActiveMerchant #:nodoc:
179
201
  xml.tag! 'n2:ReferenceID', options[:reference_id]
180
202
  xml.tag! 'n2:PaymentAction', action
181
203
  xml.tag! 'n2:PaymentType', options[:payment_type] || 'Any'
182
- add_payment_details(xml, with_money_default(money), currency_code, options)
204
+ add_payment_details(xml, money, currency_code, options)
183
205
  xml.tag! 'n2:IPAddress', options[:ip]
184
206
  end
185
207
  end
@@ -192,10 +214,6 @@ module ActiveMerchant #:nodoc:
192
214
  PaypalExpressResponse.new(success, message, response, options)
193
215
  end
194
216
 
195
- def with_money_default(money)
196
- amount(money).to_f.zero? ? 100 : money
197
- end
198
-
199
217
  def locale_code(country_code)
200
218
  NON_STANDARD_LOCALE_CODES[country_code] || country_code
201
219
  end
@@ -29,7 +29,7 @@ module ActiveMerchant #:nodoc:
29
29
  add_creditcard(post, creditcard)
30
30
  add_address(post, creditcard, options)
31
31
 
32
- commit('charges', post)
32
+ commit('charges', post, options)
33
33
  end
34
34
 
35
35
  # Create a customer and associated credit card. The token that is returned
@@ -40,14 +40,14 @@ module ActiveMerchant #:nodoc:
40
40
  add_creditcard(post, creditcard)
41
41
  add_customer_data(post, options)
42
42
  add_address(post, creditcard, options)
43
- commit('customers', post)
43
+ commit('customers', post, options)
44
44
  end
45
45
 
46
46
  # Refund a transaction, note that the money attribute is ignored at the
47
47
  # moment as the API does not support partial refunds. The parameter is
48
48
  # kept for compatibility reasons
49
49
  def refund(money, token, options = {})
50
- commit("charges/#{CGI.escape(token)}/refunds", :amount => amount(money))
50
+ commit("charges/#{CGI.escape(token)}/refunds", { :amount => amount(money) }, options)
51
51
  end
52
52
 
53
53
  private
@@ -112,11 +112,11 @@ module ActiveMerchant #:nodoc:
112
112
  result
113
113
  end
114
114
 
115
- def commit(action, params)
115
+ def commit(action, params, options)
116
116
  url = "#{test? ? test_url : live_url}/#{action}"
117
117
 
118
118
  begin
119
- body = parse(ssl_post(url, post_data(params), headers(params)))
119
+ body = parse(ssl_post(url, post_data(params), headers(options)))
120
120
  rescue ResponseError => e
121
121
  body = parse(e.response.body)
122
122
  end
@@ -6,7 +6,7 @@ module ActiveMerchant #:nodoc:
6
6
  include SageCore
7
7
  self.live_url = 'https://www.sagepayments.net/cgi-bin/eftBankcard.dll?transaction'
8
8
  self.source = 'bankcard'
9
-
9
+
10
10
  # Credit cards supported by Sage
11
11
  # * VISA
12
12
  # * MasterCard
@@ -17,42 +17,47 @@ module ActiveMerchant #:nodoc:
17
17
  # * JCB
18
18
  # * Sears
19
19
  self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club]
20
-
20
+
21
21
  def authorize(money, credit_card, options = {})
22
22
  post = {}
23
23
  add_credit_card(post, credit_card)
24
24
  add_transaction_data(post, money, options)
25
25
  commit(:authorization, post)
26
26
  end
27
-
27
+
28
28
  def purchase(money, credit_card, options = {})
29
29
  post = {}
30
30
  add_credit_card(post, credit_card)
31
31
  add_transaction_data(post, money, options)
32
32
  commit(:purchase, post)
33
- end
34
-
35
- # The +money+ amount is not used. The entire amount of the
33
+ end
34
+
35
+ # The +money+ amount is not used. The entire amount of the
36
36
  # initial authorization will be captured.
37
37
  def capture(money, reference, options = {})
38
38
  post = {}
39
39
  add_reference(post, reference)
40
40
  commit(:capture, post)
41
41
  end
42
-
42
+
43
43
  def void(reference, options = {})
44
44
  post = {}
45
45
  add_reference(post, reference)
46
46
  commit(:void, post)
47
47
  end
48
-
48
+
49
49
  def credit(money, credit_card, options = {})
50
+ deprecated CREDIT_DEPRECATION_MESSAGE
51
+ refund(money, credit_card, options)
52
+ end
53
+
54
+ def refund(money, credit_card, options = {})
50
55
  post = {}
51
56
  add_credit_card(post, credit_card)
52
57
  add_transaction_data(post, money, options)
53
58
  commit(:credit, post)
54
59
  end
55
-
60
+
56
61
  private
57
62
  def exp_date(credit_card)
58
63
  year = sprintf("%.4i", credit_card.year)
@@ -67,7 +72,7 @@ module ActiveMerchant #:nodoc:
67
72
  post[:C_exp] = exp_date(credit_card)
68
73
  post[:C_cvv] = credit_card.verification_value if credit_card.verification_value?
69
74
  end
70
-
75
+
71
76
  def parse(data)
72
77
  response = {}
73
78
  response[:success] = data[1,1]
@@ -78,7 +83,7 @@ module ActiveMerchant #:nodoc:
78
83
  response[:avs_result] = data[43, 1].strip
79
84
  response[:risk] = data[44, 2]
80
85
  response[:reference] = data[46, 10]
81
-
86
+
82
87
  response[:order_number], response[:recurring] = data[57...-1].split("\034")
83
88
  response
84
89
  end
@@ -45,7 +45,7 @@ module ActiveMerchant #:nodoc:
45
45
  end
46
46
 
47
47
  def add_customer_data(post, options)
48
- post[:T_customer_number] = options[:customer]
48
+ post[:T_customer_number] = options[:customer] if Float(options[:customer]) rescue nil
49
49
  end
50
50
 
51
51
  def add_addresses(post, options)
@@ -6,7 +6,7 @@ module ActiveMerchant #:nodoc:
6
6
  include SageCore
7
7
  self.live_url = 'https://www.sagepayments.net/cgi-bin/eftVirtualCheck.dll?transaction'
8
8
  self.source = 'virtual_check'
9
-
9
+
10
10
  def purchase(money, credit_card, options = {})
11
11
  post = {}
12
12
  add_check(post, credit_card)
@@ -14,21 +14,26 @@ module ActiveMerchant #:nodoc:
14
14
  add_transaction_data(post, money, options)
15
15
  commit(:purchase, post)
16
16
  end
17
-
17
+
18
18
  def void(reference, options = {})
19
19
  post = {}
20
20
  add_reference(post, reference)
21
21
  commit(:void, post)
22
22
  end
23
-
23
+
24
24
  def credit(money, credit_card, options = {})
25
+ deprecated CREDIT_DEPRECATION_MESSAGE
26
+ refund(money, source, options)
27
+ end
28
+
29
+ def refund(money, credit_card, options = {})
25
30
  post = {}
26
31
  add_check(post, credit_card)
27
32
  add_check_customer_data(post, options)
28
33
  add_transaction_data(post, money, options)
29
34
  commit(:credit, post)
30
35
  end
31
-
36
+
32
37
  private
33
38
  def add_check(post, check)
34
39
  post[:C_first_name] = check.first_name
@@ -38,37 +43,37 @@ module ActiveMerchant #:nodoc:
38
43
  post[:C_check_number] = check.number
39
44
  post[:C_acct_type] = account_type(check)
40
45
  end
41
-
46
+
42
47
  def add_check_customer_data(post, options)
43
48
  # Required  Customer Type – (NACHA Transaction Class)
44
- # CCD for Commercial, Merchant Initiated
49
+ # CCD for Commercial, Merchant Initiated
45
50
  # PPD for Personal, Merchant Initiated
46
- # WEB for Internet, Consumer Initiated
47
- # RCK for Returned Checks
48
- # ARC for Account Receivable Entry
51
+ # WEB for Internet, Consumer Initiated
52
+ # RCK for Returned Checks
53
+ # ARC for Account Receivable Entry
49
54
  # TEL for TelephoneInitiated
50
55
  post[:C_customer_type] = "WEB"
51
56
 
52
- # Optional  10  Digit Originator  ID – Assigned  By for  each transaction  class  or  business  purpose. If  not provided, the default Originator ID for the specific  Customer Type will be applied. 
57
+ # Optional  10  Digit Originator  ID – Assigned  By for  each transaction  class  or  business  purpose. If  not provided, the default Originator ID for the specific  Customer Type will be applied. 
53
58
  post[:C_originator_id] = options[:originator_id]
54
59
 
55
60
  # Optional  Transaction Addenda
56
61
  post[:T_addenda] = options[:addenda]
57
62
 
58
- # Required  Check  Writer  Social  Security  Number  (  Numbers Only, No Dashes ) 
63
+ # Required  Check  Writer  Social  Security  Number  (  Numbers Only, No Dashes ) 
59
64
  post[:C_ssn] = options[:ssn].to_s.gsub(/[^\d]/, '')
60
65
 
61
66
  post[:C_dl_state_code] = options[:drivers_license_state]
62
67
  post[:C_dl_number] = options[:drivers_license_number]
63
68
  post[:C_dob] = format_birth_date(options[:date_of_birth])
64
69
  end
65
-
70
+
66
71
  def format_birth_date(date)
67
72
  date.respond_to?(:strftime) ? date.strftime("%m/%d/%Y") : date
68
73
  end
69
74
 
70
- # DDA for Checking
71
- # SAV for Savings 
75
+ # DDA for Checking
76
+ # SAV for Savings 
72
77
  def account_type(check)
73
78
  case check.account_type
74
79
  when 'checking' then 'DDA'
@@ -76,7 +81,7 @@ module ActiveMerchant #:nodoc:
76
81
  else raise ArgumentError, "Unknown account type #{check.account_type}"
77
82
  end
78
83
  end
79
-
84
+
80
85
  def parse(data)
81
86
  response = {}
82
87
  response[:success] = data[1,1]
@@ -84,7 +89,7 @@ module ActiveMerchant #:nodoc:
84
89
  response[:message] = data[8,32].strip
85
90
  response[:risk] = data[40, 2]
86
91
  response[:reference] = data[42, 10]
87
-
92
+
88
93
  extra_data = data[53...-1].split("\034")
89
94
  response[:order_number] = extra_data[0]
90
95
  response[:authentication_indicator] = extra_data[1]
@@ -119,17 +119,22 @@ module ActiveMerchant #:nodoc:
119
119
  end
120
120
  end
121
121
 
122
- # Performs a credit transaction. (Sage +Credit+ transaction).
122
+ def credit(money, source, options = {})
123
+ deprecated CREDIT_DEPRECATION_MESSAGE
124
+ refund(money, source, options)
125
+ end
126
+
127
+ # Performs a refund transaction.
123
128
  #
124
129
  # ==== Parameters
125
130
  #
126
131
  # * <tt>money</tt> - The amount to be authorized as an integer value in cents.
127
- # * <tt>source</tt> - The CreditCard or Check object to be used as the target for the credit.
128
- def credit(money, source, options = {})
132
+ # * <tt>source</tt> - The CreditCard or Check object to be used as the target for the refund.
133
+ def refund(money, source, options = {})
129
134
  if card_brand(source) == "check"
130
- virtual_check.credit(money, source, options)
135
+ virtual_check.refund(money, source, options)
131
136
  else
132
- bankcard.credit(money, source, options)
137
+ bankcard.refund(money, source, options)
133
138
  end
134
139
  end
135
140
 
@@ -160,6 +160,7 @@ module ActiveMerchant #:nodoc:
160
160
 
161
161
  def add_optional_data(post, options)
162
162
  add_pair(post, :GiftAidPayment, options[:gift_aid_payment]) unless options[:gift_aid_payment].blank?
163
+ add_pair(post, :Apply3DSecure, options[:apply_3d_secure]) unless options[:apply_3d_secure].blank?
163
164
  end
164
165
 
165
166
  def add_address(post, options)