activemerchant 1.62.0 → 1.79.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +420 -2
  3. data/README.md +1 -2
  4. data/lib/active_merchant/billing/credit_card.rb +13 -14
  5. data/lib/active_merchant/billing/credit_card_methods.rb +3 -1
  6. data/lib/active_merchant/billing/gateway.rb +25 -9
  7. data/lib/active_merchant/billing/gateways/adyen.rb +299 -0
  8. data/lib/active_merchant/billing/gateways/authorize_net.rb +168 -56
  9. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +4 -2
  10. data/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb +65 -22
  11. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +87 -7
  12. data/lib/active_merchant/billing/gateways/beanstream.rb +2 -0
  13. data/lib/active_merchant/billing/gateways/blue_snap.rb +3 -8
  14. data/lib/active_merchant/billing/gateways/borgun.rb +10 -10
  15. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +1 -0
  16. data/lib/active_merchant/billing/gateways/braintree_blue.rb +49 -15
  17. data/lib/active_merchant/billing/gateways/card_connect.rb +286 -0
  18. data/lib/active_merchant/billing/gateways/card_stream.rb +97 -2
  19. data/lib/active_merchant/billing/gateways/cardprocess.rb +254 -0
  20. data/lib/active_merchant/billing/gateways/cashnet.rb +14 -2
  21. data/lib/active_merchant/billing/gateways/cenpos.rb +1 -1
  22. data/lib/active_merchant/billing/gateways/checkout.rb +1 -1
  23. data/lib/active_merchant/billing/gateways/checkout_v2.rb +44 -14
  24. data/lib/active_merchant/billing/gateways/citrus_pay.rb +0 -1
  25. data/lib/active_merchant/billing/gateways/clearhaus.rb +0 -2
  26. data/lib/active_merchant/billing/gateways/conekta.rb +4 -4
  27. data/lib/active_merchant/billing/gateways/creditcall.rb +71 -9
  28. data/lib/active_merchant/billing/gateways/credorax.rb +117 -5
  29. data/lib/active_merchant/billing/gateways/culqi.rb +279 -0
  30. data/lib/active_merchant/billing/gateways/cyber_source.rb +54 -15
  31. data/lib/active_merchant/billing/gateways/data_cash.rb +12 -0
  32. data/lib/active_merchant/billing/gateways/dibs.rb +0 -1
  33. data/lib/active_merchant/billing/gateways/digitzs.rb +292 -0
  34. data/lib/active_merchant/billing/gateways/ebanx.rb +296 -0
  35. data/lib/active_merchant/billing/gateways/elavon.rb +37 -95
  36. data/lib/active_merchant/billing/gateways/element.rb +11 -1
  37. data/lib/active_merchant/billing/gateways/fat_zebra.rb +3 -29
  38. data/lib/active_merchant/billing/gateways/first_pay.rb +12 -10
  39. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +37 -20
  40. data/lib/active_merchant/billing/gateways/forte.rb +0 -1
  41. data/lib/active_merchant/billing/gateways/global_collect.rb +55 -16
  42. data/lib/active_merchant/billing/gateways/global_transport.rb +16 -2
  43. data/lib/active_merchant/billing/gateways/hps.rb +12 -1
  44. data/lib/active_merchant/billing/gateways/iats_payments.rb +2 -2
  45. data/lib/active_merchant/billing/gateways/iveri.rb +251 -0
  46. data/lib/active_merchant/billing/gateways/jetpay.rb +12 -9
  47. data/lib/active_merchant/billing/gateways/jetpay_v2.rb +437 -0
  48. data/lib/active_merchant/billing/gateways/kushki.rb +227 -0
  49. data/lib/active_merchant/billing/gateways/linkpoint.rb +2 -2
  50. data/lib/active_merchant/billing/gateways/litle.rb +107 -30
  51. data/lib/active_merchant/billing/gateways/mercado_pago.rb +262 -0
  52. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +11 -0
  53. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +16 -4
  54. data/lib/active_merchant/billing/gateways/mercury.rb +14 -1
  55. data/lib/active_merchant/billing/gateways/migs.rb +28 -6
  56. data/lib/active_merchant/billing/gateways/moneris.rb +20 -12
  57. data/lib/active_merchant/billing/gateways/moneris_us.rb +11 -0
  58. data/lib/active_merchant/billing/gateways/mundipagg.rb +292 -0
  59. data/lib/active_merchant/billing/gateways/nab_transact.rb +4 -4
  60. data/lib/active_merchant/billing/gateways/netbanx.rb +60 -16
  61. data/lib/active_merchant/billing/gateways/netbilling.rb +0 -1
  62. data/lib/active_merchant/billing/gateways/nmi.rb +12 -1
  63. data/lib/active_merchant/billing/gateways/ogone.rb +1 -1
  64. data/lib/active_merchant/billing/gateways/omise.rb +9 -5
  65. data/lib/active_merchant/billing/gateways/openpay.rb +13 -0
  66. data/lib/active_merchant/billing/gateways/opp.rb +124 -114
  67. data/lib/active_merchant/billing/gateways/optimal_payment.rb +14 -1
  68. data/lib/active_merchant/billing/gateways/orbital.rb +83 -14
  69. data/lib/active_merchant/billing/gateways/pay_hub.rb +2 -2
  70. data/lib/active_merchant/billing/gateways/payeezy.rb +152 -46
  71. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +12 -2
  72. data/lib/active_merchant/billing/gateways/payflow.rb +24 -2
  73. data/lib/active_merchant/billing/gateways/payment_express.rb +3 -2
  74. data/lib/active_merchant/billing/gateways/paymentez.rb +276 -0
  75. data/lib/active_merchant/billing/gateways/paymill.rb +18 -10
  76. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +14 -0
  77. data/lib/active_merchant/billing/gateways/paypal.rb +0 -12
  78. data/lib/active_merchant/billing/gateways/paystation.rb +14 -1
  79. data/lib/active_merchant/billing/gateways/payu_latam.rb +102 -62
  80. data/lib/active_merchant/billing/gateways/pin.rb +5 -0
  81. data/lib/active_merchant/billing/gateways/pro_pay.rb +326 -0
  82. data/lib/active_merchant/billing/gateways/psigate.rb +12 -1
  83. data/lib/active_merchant/billing/gateways/qbms.rb +11 -0
  84. data/lib/active_merchant/billing/gateways/quickbooks.rb +10 -0
  85. data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +21 -17
  86. data/lib/active_merchant/billing/gateways/quickpay.rb +3 -3
  87. data/lib/active_merchant/billing/gateways/qvalent.rb +60 -3
  88. data/lib/active_merchant/billing/gateways/realex.rb +16 -6
  89. data/lib/active_merchant/billing/gateways/redsys.rb +8 -2
  90. data/lib/active_merchant/billing/gateways/safe_charge.rb +262 -0
  91. data/lib/active_merchant/billing/gateways/sage.rb +8 -3
  92. data/lib/active_merchant/billing/gateways/sage_pay.rb +29 -13
  93. data/lib/active_merchant/billing/gateways/secure_net.rb +11 -1
  94. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +12 -0
  95. data/lib/active_merchant/billing/gateways/smart_ps.rb +1 -1
  96. data/lib/active_merchant/billing/gateways/spreedly_core.rb +53 -7
  97. data/lib/active_merchant/billing/gateways/stripe.rb +84 -26
  98. data/lib/active_merchant/billing/gateways/tns.rb +0 -1
  99. data/lib/active_merchant/billing/gateways/trans_first.rb +3 -2
  100. data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +61 -26
  101. data/lib/active_merchant/billing/gateways/trexle.rb +217 -0
  102. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +114 -9
  103. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +45 -22
  104. data/lib/active_merchant/billing/gateways/vanco.rb +1 -1
  105. data/lib/active_merchant/billing/gateways/wepay.rb +79 -46
  106. data/lib/active_merchant/billing/gateways/wirecard.rb +5 -4
  107. data/lib/active_merchant/billing/gateways/worldpay.rb +85 -20
  108. data/lib/active_merchant/billing/gateways/worldpay_us.rb +27 -8
  109. data/lib/active_merchant/billing/network_tokenization_credit_card.rb +1 -1
  110. data/lib/active_merchant/connection.rb +48 -12
  111. data/lib/active_merchant/net_http_ssl_connection.rb +9 -0
  112. data/lib/active_merchant/network_connection_retries.rb +6 -4
  113. data/lib/active_merchant/posts_data.rb +11 -1
  114. data/lib/active_merchant/version.rb +1 -1
  115. data/lib/active_merchant.rb +2 -5
  116. data/lib/certs/cacert.pem +85 -0
  117. data/lib/support/ssl_version.rb +87 -0
  118. metadata +25 -9
  119. data/lib/active_merchant/billing/gateways/barclays_epdq.rb +0 -314
@@ -0,0 +1,286 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class CardConnectGateway < Gateway
4
+ self.test_url = 'https://fts.cardconnect.com:6443/cardconnect/rest/'
5
+ self.live_url = 'https://fts.cardconnect.com:8443/cardconnect/rest/'
6
+
7
+ self.supported_countries = ['US']
8
+ self.default_currency = 'USD'
9
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover]
10
+
11
+ self.homepage_url = 'https://cardconnect.com/'
12
+ self.display_name = 'Card Connect'
13
+
14
+ STANDARD_ERROR_CODE_MAPPING = {
15
+ '11' => STANDARD_ERROR_CODE[:card_declined],
16
+ '12' => STANDARD_ERROR_CODE[:incorrect_number],
17
+ '13' => STANDARD_ERROR_CODE[:incorrect_cvc],
18
+ '14' => STANDARD_ERROR_CODE[:incorrect_cvc],
19
+ '15' => STANDARD_ERROR_CODE[:invalid_expiry_date],
20
+ '16' => STANDARD_ERROR_CODE[:expired_card],
21
+ '17' => STANDARD_ERROR_CODE[:incorrect_zip],
22
+ '21' => STANDARD_ERROR_CODE[:config_error],
23
+ '22' => STANDARD_ERROR_CODE[:config_error],
24
+ '23' => STANDARD_ERROR_CODE[:config_error],
25
+ '24' => STANDARD_ERROR_CODE[:processing_error],
26
+ '25' => STANDARD_ERROR_CODE[:processing_error],
27
+ '27' => STANDARD_ERROR_CODE[:processing_error],
28
+ '28' => STANDARD_ERROR_CODE[:processing_error],
29
+ '29' => STANDARD_ERROR_CODE[:processing_error],
30
+ '31' => STANDARD_ERROR_CODE[:processing_error],
31
+ '32' => STANDARD_ERROR_CODE[:processing_error],
32
+ '33' => STANDARD_ERROR_CODE[:card_declined],
33
+ '34' => STANDARD_ERROR_CODE[:card_declined],
34
+ '35' => STANDARD_ERROR_CODE[:incorrect_zip],
35
+ '36' => STANDARD_ERROR_CODE[:processing_error],
36
+ '37' => STANDARD_ERROR_CODE[:incorrect_cvc],
37
+ '41' => STANDARD_ERROR_CODE[:processing_error],
38
+ '42' => STANDARD_ERROR_CODE[:processing_error],
39
+ '43' => STANDARD_ERROR_CODE[:processing_error],
40
+ '44' => STANDARD_ERROR_CODE[:config_error],
41
+ '61' => STANDARD_ERROR_CODE[:processing_error],
42
+ '62' => STANDARD_ERROR_CODE[:processing_error],
43
+ '63' => STANDARD_ERROR_CODE[:processing_error],
44
+ '64' => STANDARD_ERROR_CODE[:config_error],
45
+ '65' => STANDARD_ERROR_CODE[:processing_error],
46
+ '66' => STANDARD_ERROR_CODE[:processing_error],
47
+ '91' => STANDARD_ERROR_CODE[:processing_error],
48
+ '92' => STANDARD_ERROR_CODE[:processing_error],
49
+ '93' => STANDARD_ERROR_CODE[:processing_error],
50
+ '94' => STANDARD_ERROR_CODE[:processing_error],
51
+ '95' => STANDARD_ERROR_CODE[:config_error],
52
+ '96' => STANDARD_ERROR_CODE[:processing_error],
53
+ 'NU' => STANDARD_ERROR_CODE[:card_declined],
54
+ 'N3' => STANDARD_ERROR_CODE[:card_declined],
55
+ 'NJ' => STANDARD_ERROR_CODE[:card_declined],
56
+ '51' => STANDARD_ERROR_CODE[:card_declined],
57
+ 'C2' => STANDARD_ERROR_CODE[:incorrect_cvc],
58
+ '54' => STANDARD_ERROR_CODE[:expired_card],
59
+ '05' => STANDARD_ERROR_CODE[:card_declined],
60
+ '03' => STANDARD_ERROR_CODE[:config_error],
61
+ '60' => STANDARD_ERROR_CODE[:pickup_card]
62
+ }
63
+
64
+ def initialize(options = {})
65
+ requires!(options, :merchant_id, :username, :password)
66
+ require_valid_domain!(options, :domain)
67
+ super
68
+ end
69
+
70
+ def require_valid_domain!(options, param)
71
+ if options.key?(param)
72
+ raise ArgumentError.new('not a valid cardconnect domain') unless /\Dcardconnect.com:\d{1,}\D/ =~ options[param]
73
+ end
74
+ end
75
+
76
+ def purchase(money, payment, options = {})
77
+ if options[:po_number]
78
+ MultiResponse.run do |r|
79
+ r.process { authorize(money, payment, options) }
80
+ r.process { capture(money, r.authorization, options) }
81
+ end
82
+ else
83
+ post = {}
84
+ add_invoice(post, options)
85
+ add_money(post, money)
86
+ add_payment(post, payment)
87
+ add_currency(post, money, options)
88
+ add_address(post, options)
89
+ add_customer_data(post, options)
90
+ add_3DS(post, options)
91
+ post[:capture] = 'Y'
92
+ commit('auth', post)
93
+ end
94
+ end
95
+
96
+ def authorize(money, payment, options = {})
97
+ post = {}
98
+ add_money(post, money)
99
+ add_currency(post, money, options)
100
+ add_invoice(post, options)
101
+ add_payment(post, payment)
102
+ add_address(post, options)
103
+ add_customer_data(post, options)
104
+ add_3DS(post, options)
105
+ commit('auth', post)
106
+ end
107
+
108
+ def capture(money, authorization, options = {})
109
+ post = {}
110
+ add_money(post, money)
111
+ add_reference(post, authorization)
112
+ add_additional_data(post, options)
113
+ commit('capture', post)
114
+ end
115
+
116
+ def refund(money, authorization, options = {})
117
+ post = {}
118
+ add_money(post, money)
119
+ add_reference(post, authorization)
120
+ commit('refund', post)
121
+ end
122
+
123
+ def void(authorization, options = {})
124
+ post = {}
125
+ add_reference(post, authorization)
126
+ commit('void', post)
127
+ end
128
+
129
+ def verify(credit_card, options = {})
130
+ authorize(0, credit_card, options)
131
+ end
132
+
133
+ def supports_scrubbing?
134
+ true
135
+ end
136
+
137
+ def scrub(transcript)
138
+ transcript
139
+ .gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]')
140
+ .gsub(%r(("cvv2\\":\\")\d*), '\1[FILTERED]')
141
+ .gsub(%r(("merchid\\":\\")\d*), '\1[FILTERED]')
142
+ .gsub(%r((&?"account\\":\\")\d*), '\1[FILTERED]')
143
+ .gsub(%r((&?"token\\":\\")\d*), '\1[FILTERED]')
144
+ end
145
+
146
+ private
147
+
148
+ def add_customer_data(post, options)
149
+ post[:email] = options[:email] if options[:email]
150
+ end
151
+
152
+ def add_address(post, options)
153
+ if address = options[:billing_address] || options[:address]
154
+ post[:address] = address[:address1] if address[:address1]
155
+ post[:address].concat(" #{address[:address2]}") if address[:address2]
156
+ post[:city] = address[:city] if address[:city]
157
+ post[:region] = address[:state] if address[:state]
158
+ post[:country] = address[:country] if address[:country]
159
+ post[:postal] = address[:zip] if address[:zip]
160
+ post[:phone] = address[:phone] if address[:phone]
161
+ end
162
+ end
163
+
164
+ def add_money(post, money)
165
+ post[:amount] = amount(money)
166
+ end
167
+
168
+ def add_currency(post, money, options)
169
+ post[:currency] = (options[:currency] || currency(money))
170
+ end
171
+
172
+ def add_invoice(post, options)
173
+ post[:orderid] = options[:order_id]
174
+ post[:ecomind] = (options[:recurring] ? 'R' : 'E')
175
+ end
176
+
177
+ def add_payment(post, payment)
178
+ post[:name] = payment.name
179
+ if card_brand(payment) == 'check'
180
+ add_echeck(post, payment)
181
+ else
182
+ post[:account] = payment.number
183
+ post[:expiry] = expdate(payment)
184
+ post[:cvv2] = payment.verification_value
185
+ end
186
+ end
187
+
188
+ def add_echeck(post, payment)
189
+ post[:accttype] = 'ECHK'
190
+ post[:account] = payment.account_number
191
+ post[:bankaba] = payment.routing_number
192
+ end
193
+
194
+ def add_reference(post, authorization)
195
+ post[:retref] = authorization
196
+ end
197
+
198
+ def add_additional_data(post, options)
199
+ post[:ponumber] = options[:po_number]
200
+ post[:taxamnt] = options[:tax_amount] if options[:tax_amount]
201
+ post[:frtamnt] = options[:freight_amount] if options[:freight_amount]
202
+ post[:dutyamnt] = options[:duty_amount] if options[:duty_amount]
203
+ post[:orderdate] = options[:order_date] if options[:order_date]
204
+ post[:shipfromzip] = options[:ship_from_zip] if options[:ship_from_zip]
205
+ if (shipping_address = options[:shipping_address])
206
+ post[:shiptozip] = shipping_address[:zip]
207
+ post[:shiptocountry] = shipping_address[:country]
208
+ end
209
+ if options[:items]
210
+ post[:items] = options[:items].map do |item|
211
+ updated = {}
212
+ item.each_pair do |k, v|
213
+ updated.merge!(k.to_s.gsub(/_/, '') => v)
214
+ end
215
+ end
216
+ end
217
+ end
218
+
219
+ def add_3DS(post, options)
220
+ post[:secureflag] = options[:secure_flag] if options[:secure_flag]
221
+ post[:securevalue] = options[:secure_value] if options[:secure_value]
222
+ post[:securexid] = options[:secure_xid] if options[:secure_xid]
223
+ end
224
+
225
+ def headers
226
+ {
227
+ 'Authorization' => 'Basic ' + Base64.strict_encode64("#{@options[:username]}:#{@options[:password]}"),
228
+ 'Content-Type' => 'application/json'
229
+ }
230
+ end
231
+
232
+ def expdate(credit_card)
233
+ "#{format(credit_card.month, :two_digits)}#{format(credit_card.year, :two_digits)}"
234
+ end
235
+
236
+ def parse(body)
237
+ JSON.parse(body)
238
+ end
239
+
240
+ def url(action)
241
+ if test?
242
+ test_url + action
243
+ else
244
+ (@options[:domain] ? @options[:domain] : live_url) + action
245
+ end
246
+ end
247
+
248
+ def commit(action, parameters)
249
+ parameters[:merchid] = @options[:merchant_id]
250
+ url = url(action)
251
+ response = parse(ssl_request(:put, url, post_data(parameters), headers))
252
+
253
+ Response.new(
254
+ success_from(response),
255
+ message_from(response),
256
+ response,
257
+ authorization: authorization_from(response),
258
+ avs_result: AVSResult.new(code: response['avsresp']),
259
+ cvv_result: CVVResult.new(response['cvvresp']),
260
+ test: test?,
261
+ error_code: error_code_from(response)
262
+ )
263
+ end
264
+
265
+ def success_from(response)
266
+ response['respstat'] == 'A'
267
+ end
268
+
269
+ def message_from(response)
270
+ response['setlstat'] ? "#{response['resptext']} #{response['setlstat']}" : response['resptext']
271
+ end
272
+
273
+ def authorization_from(response)
274
+ response['retref']
275
+ end
276
+
277
+ def post_data(parameters = {})
278
+ parameters.to_json
279
+ end
280
+
281
+ def error_code_from(response)
282
+ STANDARD_ERROR_CODE_MAPPING[response['respcode']] unless success_from(response)
283
+ end
284
+ end
285
+ end
286
+ end
@@ -14,23 +14,95 @@ module ActiveMerchant #:nodoc:
14
14
 
15
15
  CURRENCY_CODES = {
16
16
  "AED" => "784",
17
+ "ALL" => "008",
18
+ "AMD" => "051",
19
+ "ANG" => "532",
20
+ "ARS" => "032",
17
21
  "AUD" => "036",
22
+ "AWG" => "533",
23
+ "BAM" => "977",
24
+ "BBD" => "052",
25
+ "BGN" => "975",
26
+ "BMD" => "060",
27
+ "BOB" => "068",
18
28
  "BRL" => "986",
29
+ "BSD" => "044",
30
+ "BWP" => "072",
31
+ "BZD" => "084",
19
32
  "CAD" => "124",
20
33
  "CHF" => "756",
34
+ "CLP" => "152",
35
+ "CNY" => "156",
36
+ "COP" => "170",
37
+ "CRC" => "188",
21
38
  "CZK" => "203",
22
39
  "DKK" => "208",
40
+ "DOP" => "214",
41
+ "EGP" => "818",
23
42
  "EUR" => "978",
24
43
  "GBP" => "826",
44
+ "GEL" => "981",
45
+ "GIP" => "292",
46
+ "GTQ" => "320",
47
+ "GYD" => "328",
25
48
  "HKD" => "344",
26
- "ICK" => "352",
49
+ "HNL" => "340",
50
+ "HRK" => "191",
51
+ "HUF" => "348",
52
+ "ISK" => "352",
53
+ "IDR" => "360",
54
+ "ILS" => "376",
55
+ "INR" => "356",
27
56
  "JPY" => "392",
57
+ "JMD" => "388",
58
+ "KES" => "404",
59
+ "KRW" => "410",
60
+ "KYD" => "136",
61
+ "LBP" => "422",
62
+ "LKR" => "144",
63
+ "MAD" => "504",
64
+ "MVR" => "462",
65
+ "MWK" => "454",
28
66
  "MXN" => "484",
67
+ "MYR" => "458",
68
+ "NAD" => "516",
69
+ "NGN" => "566",
70
+ "NIO" => "558",
29
71
  "NOK" => "578",
72
+ "NPR" => "524",
30
73
  "NZD" => "554",
74
+ "PAB" => "590",
75
+ "PEN" => "604",
76
+ "PGK" => "598",
77
+ "PHP" => "608",
78
+ "PKR" => "586",
79
+ "PLN" => "985",
80
+ "PYG" => "600",
81
+ "QAR" => "634",
82
+ "RON" => "946",
83
+ "RSD" => "941",
84
+ "RUB" => "643",
85
+ "RWF" => "646",
86
+ "SAR" => "682",
31
87
  "SEK" => "752",
32
88
  "SGD" => "702",
89
+ "SRD" => "968",
90
+ "THB" => "764",
91
+ "TND" => "788",
92
+ "TRY" => "949",
93
+ "TTD" => "780",
94
+ "TWD" => "901",
95
+ "TZS" => "834",
96
+ "UAH" => "980",
97
+ "UGX" => "800",
33
98
  "USD" => "840",
99
+ "UYU" => "858",
100
+ "VND" => "704",
101
+ "WST" => "882",
102
+ "XAF" => "950",
103
+ "XCD" => "951",
104
+ "XOF" => "952",
105
+ "ZAR" => "710"
34
106
  }
35
107
 
36
108
  CVV_CODE = {
@@ -83,6 +155,7 @@ module ActiveMerchant #:nodoc:
83
155
  add_invoice(post, credit_card_or_reference, money, options)
84
156
  add_credit_card_or_reference(post, credit_card_or_reference)
85
157
  add_customer_data(post, options)
158
+ add_remote_address(post, options)
86
159
  commit('SALE', post)
87
160
  end
88
161
 
@@ -93,6 +166,7 @@ module ActiveMerchant #:nodoc:
93
166
  add_invoice(post, credit_card_or_reference, money, options)
94
167
  add_credit_card_or_reference(post, credit_card_or_reference)
95
168
  add_customer_data(post, options)
169
+ add_remote_address(post, options)
96
170
  commit('SALE', post)
97
171
  end
98
172
 
@@ -100,6 +174,7 @@ module ActiveMerchant #:nodoc:
100
174
  post = {}
101
175
  add_pair(post, :xref, authorization)
102
176
  add_pair(post, :amount, amount(money), :required => true)
177
+ add_remote_address(post, options)
103
178
 
104
179
  commit('CAPTURE', post)
105
180
  end
@@ -108,12 +183,23 @@ module ActiveMerchant #:nodoc:
108
183
  post = {}
109
184
  add_pair(post, :xref, authorization)
110
185
  add_amount(post, money, options)
111
- commit('REFUND', post)
186
+ add_remote_address(post, options)
187
+ response = commit('REFUND_SALE', post)
188
+
189
+ return response if response.success?
190
+ return response unless options[:force_full_refund_if_unsettled]
191
+
192
+ if response.params["responseCode"] == "65541"
193
+ void(authorization, options)
194
+ else
195
+ response
196
+ end
112
197
  end
113
198
 
114
199
  def void(authorization, options = {})
115
200
  post = {}
116
201
  add_pair(post, :xref, authorization)
202
+ add_remote_address(post, options)
117
203
  commit('CANCEL', post)
118
204
  end
119
205
 
@@ -148,12 +234,17 @@ module ActiveMerchant #:nodoc:
148
234
  add_pair(post, :customerAddress, "#{address[:address1]} #{address[:address2]}".strip)
149
235
  add_pair(post, :customerPostCode, address[:zip])
150
236
  add_pair(post, :customerPhone, options[:phone])
237
+ add_pair(post, :customerCountryCode, address[:country] || 'GB')
238
+ else
239
+ add_pair(post, :customerCountryCode, 'GB')
151
240
  end
152
241
  end
153
242
 
154
243
  def add_invoice(post, credit_card_or_reference, money, options)
155
244
  add_pair(post, :transactionUnique, options[:order_id], :required => true)
156
245
  add_pair(post, :orderRef, options[:description] || options[:order_id], :required => true)
246
+ add_pair(post, :statementNarrative1, options[:merchant_name]) if options[:merchant_name]
247
+ add_pair(post, :statementNarrative2, options[:dynamic_descriptor]) if options[:dynamic_descriptor]
157
248
  if credit_card_or_reference.respond_to?(:number)
158
249
  if ['american_express', 'diners_club'].include?(card_brand(credit_card_or_reference).to_s)
159
250
  add_pair(post, :item1Quantity, 1)
@@ -199,6 +290,10 @@ module ActiveMerchant #:nodoc:
199
290
  add_pair(post, :threeDSRequired, (options[:threeds_required] || @threeds_required) ? 'Y' : 'N')
200
291
  end
201
292
 
293
+ def add_remote_address(post, options={})
294
+ add_pair(post, :remoteAddress, options[:ip] || '1.1.1.1')
295
+ end
296
+
202
297
  def normalize_line_endings(str)
203
298
  str.gsub(/%0D%0A|%0A%0D|%0D/, "%0A")
204
299
  end