activemerchant 1.126.0 → 1.129.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 (71) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +241 -0
  3. data/lib/active_merchant/billing/check.rb +40 -8
  4. data/lib/active_merchant/billing/credit_card.rb +28 -1
  5. data/lib/active_merchant/billing/credit_card_methods.rb +79 -23
  6. data/lib/active_merchant/billing/gateways/adyen.rb +67 -8
  7. data/lib/active_merchant/billing/gateways/airwallex.rb +40 -11
  8. data/lib/active_merchant/billing/gateways/alelo.rb +256 -0
  9. data/lib/active_merchant/billing/gateways/authorize_net.rb +21 -4
  10. data/lib/active_merchant/billing/gateways/beanstream.rb +18 -0
  11. data/lib/active_merchant/billing/gateways/blue_snap.rb +22 -1
  12. data/lib/active_merchant/billing/gateways/bogus.rb +4 -0
  13. data/lib/active_merchant/billing/gateways/borgun.rb +56 -16
  14. data/lib/active_merchant/billing/gateways/braintree_blue.rb +64 -17
  15. data/lib/active_merchant/billing/gateways/card_connect.rb +27 -9
  16. data/lib/active_merchant/billing/gateways/card_stream.rb +23 -0
  17. data/lib/active_merchant/billing/gateways/checkout_v2.rb +228 -57
  18. data/lib/active_merchant/billing/gateways/commerce_hub.rb +361 -0
  19. data/lib/active_merchant/billing/gateways/credorax.rb +47 -27
  20. data/lib/active_merchant/billing/gateways/cyber_source/cyber_source_common.rb +36 -0
  21. data/lib/active_merchant/billing/gateways/cyber_source.rb +100 -26
  22. data/lib/active_merchant/billing/gateways/cyber_source_rest.rb +456 -0
  23. data/lib/active_merchant/billing/gateways/d_local.rb +44 -5
  24. data/lib/active_merchant/billing/gateways/decidir.rb +15 -4
  25. data/lib/active_merchant/billing/gateways/ebanx.rb +36 -24
  26. data/lib/active_merchant/billing/gateways/element.rb +21 -1
  27. data/lib/active_merchant/billing/gateways/global_collect.rb +73 -22
  28. data/lib/active_merchant/billing/gateways/ipg.rb +13 -8
  29. data/lib/active_merchant/billing/gateways/iveri.rb +39 -3
  30. data/lib/active_merchant/billing/gateways/kushki.rb +21 -1
  31. data/lib/active_merchant/billing/gateways/litle.rb +25 -5
  32. data/lib/active_merchant/billing/gateways/mastercard.rb +1 -8
  33. data/lib/active_merchant/billing/gateways/mercado_pago.rb +17 -0
  34. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +44 -10
  35. data/lib/active_merchant/billing/gateways/monei.rb +2 -0
  36. data/lib/active_merchant/billing/gateways/moneris.rb +20 -5
  37. data/lib/active_merchant/billing/gateways/mundipagg.rb +3 -0
  38. data/lib/active_merchant/billing/gateways/ogone.rb +35 -7
  39. data/lib/active_merchant/billing/gateways/openpay.rb +20 -3
  40. data/lib/active_merchant/billing/gateways/orbital.rb +43 -22
  41. data/lib/active_merchant/billing/gateways/pay_trace.rb +64 -18
  42. data/lib/active_merchant/billing/gateways/payeezy.rb +59 -4
  43. data/lib/active_merchant/billing/gateways/paymentez.rb +18 -6
  44. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +4 -0
  45. data/lib/active_merchant/billing/gateways/paysafe.rb +22 -14
  46. data/lib/active_merchant/billing/gateways/payu_latam.rb +3 -0
  47. data/lib/active_merchant/billing/gateways/plexo.rb +308 -0
  48. data/lib/active_merchant/billing/gateways/priority.rb +29 -6
  49. data/lib/active_merchant/billing/gateways/rapyd.rb +110 -49
  50. data/lib/active_merchant/billing/gateways/reach.rb +277 -0
  51. data/lib/active_merchant/billing/gateways/redsys.rb +9 -5
  52. data/lib/active_merchant/billing/gateways/sage_pay.rb +1 -1
  53. data/lib/active_merchant/billing/gateways/securion_pay.rb +40 -0
  54. data/lib/active_merchant/billing/gateways/shift4.rb +342 -0
  55. data/lib/active_merchant/billing/gateways/simetrik.rb +28 -22
  56. data/lib/active_merchant/billing/gateways/stripe.rb +21 -1
  57. data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +62 -22
  58. data/lib/active_merchant/billing/gateways/tns.rb +2 -5
  59. data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +1 -1
  60. data/lib/active_merchant/billing/gateways/trust_commerce.rb +14 -3
  61. data/lib/active_merchant/billing/gateways/vanco.rb +12 -3
  62. data/lib/active_merchant/billing/gateways/visanet_peru.rb +1 -1
  63. data/lib/active_merchant/billing/gateways/vpos.rb +7 -4
  64. data/lib/active_merchant/billing/gateways/wompi.rb +8 -4
  65. data/lib/active_merchant/billing/gateways/worldpay.rb +117 -9
  66. data/lib/active_merchant/billing/response.rb +15 -1
  67. data/lib/active_merchant/connection.rb +0 -2
  68. data/lib/active_merchant/country.rb +1 -0
  69. data/lib/active_merchant/errors.rb +4 -1
  70. data/lib/active_merchant/version.rb +1 -1
  71. metadata +24 -3
@@ -23,18 +23,34 @@ module ActiveMerchant #:nodoc:
23
23
 
24
24
  def purchase(money, payment, options = {})
25
25
  post = {}
26
- post[:TransType] = '1'
26
+ action = ''
27
+ if options[:apply_3d_secure] == '1'
28
+ add_3ds_preauth_fields(post, options)
29
+ action = '3ds_preauth'
30
+ else
31
+ post[:TransType] = '1'
32
+ add_3ds_fields(post, options)
33
+ action = 'sale'
34
+ end
27
35
  add_invoice(post, money, options)
28
36
  add_payment_method(post, payment)
29
- commit('sale', post)
37
+ commit(action, post, options)
30
38
  end
31
39
 
32
40
  def authorize(money, payment, options = {})
33
41
  post = {}
34
- post[:TransType] = '5'
42
+ action = ''
43
+ if options[:apply_3d_secure] == '1'
44
+ add_3ds_preauth_fields(post, options)
45
+ action = '3ds_preauth'
46
+ else
47
+ post[:TransType] = '5'
48
+ add_3ds_fields(post, options)
49
+ action = 'authonly'
50
+ end
35
51
  add_invoice(post, money, options)
36
52
  add_payment_method(post, payment)
37
- commit('authonly', post, options)
53
+ commit(action, post, options)
38
54
  end
39
55
 
40
56
  def capture(money, authorization, options = {})
@@ -81,9 +97,26 @@ module ActiveMerchant #:nodoc:
81
97
  CURRENCY_CODES['EUR'] = '978'
82
98
  CURRENCY_CODES['USD'] = '840'
83
99
 
100
+ def add_3ds_fields(post, options)
101
+ post[:ThreeDSMessageId] = options[:three_ds_message_id] if options[:three_ds_message_id]
102
+ post[:ThreeDS_PARes] = options[:three_ds_pares] if options[:three_ds_pares]
103
+ post[:ThreeDS_CRes] = options[:three_ds_cres] if options[:three_ds_cres]
104
+ end
105
+
106
+ def add_3ds_preauth_fields(post, options)
107
+ post[:SaleDescription] = options[:sale_description] || ''
108
+ post[:MerchantReturnURL] = options[:merchant_return_url] if options[:merchant_return_url]
109
+ end
110
+
84
111
  def add_invoice(post, money, options)
85
112
  post[:TrAmount] = amount(money)
86
113
  post[:TrCurrency] = CURRENCY_CODES[options[:currency] || currency(money)]
114
+ # The ISK currency must have a currency exponent of 2 on the 3DS request but not on the auth request
115
+ if post[:TrCurrency] == '352' && options[:apply_3d_secure] == '1'
116
+ post[:TrCurrencyExponent] = 2
117
+ else
118
+ post[:TrCurrencyExponent] = 0
119
+ end
87
120
  post[:TerminalID] = options[:terminal_id] || '1'
88
121
  end
89
122
 
@@ -103,11 +136,11 @@ module ActiveMerchant #:nodoc:
103
136
  post[:AuthCode] = authcode
104
137
  end
105
138
 
106
- def parse(xml)
139
+ def parse(xml, options = nil)
107
140
  response = {}
108
141
 
109
142
  doc = Nokogiri::XML(CGI.unescapeHTML(xml))
110
- body = doc.xpath('//getAuthorizationReply')
143
+ body = options[:apply_3d_secure] == '1' ? doc.xpath('//get3DSAuthenticationReply') : doc.xpath('//getAuthorizationReply')
111
144
  body = doc.xpath('//cancelAuthorizationReply') if body.length == 0
112
145
  body.children.each do |node|
113
146
  if node.text?
@@ -121,7 +154,6 @@ module ActiveMerchant #:nodoc:
121
154
  end
122
155
  end
123
156
  end
124
-
125
157
  response
126
158
  end
127
159
 
@@ -132,7 +164,7 @@ module ActiveMerchant #:nodoc:
132
164
 
133
165
  request = build_request(action, post, options)
134
166
  raw = ssl_post(url(action), request, headers)
135
- pairs = parse(raw)
167
+ pairs = parse(raw, options)
136
168
  success = success_from(pairs)
137
169
 
138
170
  Response.new(
@@ -145,7 +177,7 @@ module ActiveMerchant #:nodoc:
145
177
  end
146
178
 
147
179
  def success_from(response)
148
- (response[:actioncode] == '000')
180
+ (response[:actioncode] == '000') || (response[:status_resultcode] == '0')
149
181
  end
150
182
 
151
183
  def message_from(succeeded, response)
@@ -182,16 +214,17 @@ module ActiveMerchant #:nodoc:
182
214
 
183
215
  def build_request(action, post, options = {})
184
216
  mode = action == 'void' ? 'cancel' : 'get'
217
+ transaction_type = action == '3ds_preauth' ? '3DSAuthentication' : 'Authorization'
185
218
  xml = Builder::XmlMarkup.new indent: 18
186
219
  xml.instruct!(:xml, version: '1.0', encoding: 'utf-8')
187
- xml.tag!("#{mode}Authorization") do
220
+ xml.tag!("#{mode}#{transaction_type}") do
188
221
  post.each do |field, value|
189
222
  xml.tag!(field, value)
190
223
  end
191
224
  build_airline_xml(xml, options[:passenger_itinerary_data]) if options[:passenger_itinerary_data]
192
225
  end
193
226
  inner = CGI.escapeHTML(xml.target!)
194
- envelope(mode).sub(/{{ :body }}/, inner)
227
+ envelope(mode, action).sub(/{{ :body }}/, inner)
195
228
  end
196
229
 
197
230
  def build_airline_xml(xml, airline_data)
@@ -204,16 +237,23 @@ module ActiveMerchant #:nodoc:
204
237
  end
205
238
  end
206
239
 
207
- def envelope(mode)
240
+ def envelope(mode, action)
241
+ if action == '3ds_preauth'
242
+ transaction_action = "#{mode}3DSAuthentication"
243
+ request_action = "#{mode}Auth3DSReqXml"
244
+ else
245
+ transaction_action = "#{mode}AuthorizationInput"
246
+ request_action = "#{mode}AuthReqXml"
247
+ end
208
248
  <<-XML
209
249
  <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:aut="http://Borgun/Heimir/pub/ws/Authorization">
210
250
  <soapenv:Header/>
211
251
  <soapenv:Body>
212
- <aut:#{mode}AuthorizationInput>
213
- <#{mode}AuthReqXml>
252
+ <aut:#{transaction_action}>
253
+ <#{request_action}>
214
254
  {{ :body }}
215
- </#{mode}AuthReqXml>
216
- </aut:#{mode}AuthorizationInput>
255
+ </#{request_action}>
256
+ </aut:#{transaction_action}>
217
257
  </soapenv:Body>
218
258
  </soapenv:Envelope>
219
259
  XML
@@ -75,6 +75,12 @@ module ActiveMerchant #:nodoc:
75
75
  @braintree_gateway = Braintree::Gateway.new(@configuration)
76
76
  end
77
77
 
78
+ def setup_purchase
79
+ commit do
80
+ Response.new(true, 'Client token created', { client_token: @braintree_gateway.client_token.generate })
81
+ end
82
+ end
83
+
78
84
  def authorize(money, credit_card_or_vault_id, options = {})
79
85
  return Response.new(false, DIRECT_BANK_ERROR) if credit_card_or_vault_id.is_a? Check
80
86
 
@@ -82,9 +88,16 @@ module ActiveMerchant #:nodoc:
82
88
  end
83
89
 
84
90
  def capture(money, authorization, options = {})
85
- commit do
86
- result = @braintree_gateway.transaction.submit_for_settlement(authorization, localized_amount(money, options[:currency] || default_currency).to_s)
87
- response_from_result(result)
91
+ if options[:partial_capture] == true
92
+ commit do
93
+ result = @braintree_gateway.transaction.submit_for_partial_settlement(authorization, localized_amount(money, options[:currency] || default_currency).to_s)
94
+ response_from_result(result)
95
+ end
96
+ else
97
+ commit do
98
+ result = @braintree_gateway.transaction.submit_for_settlement(authorization, localized_amount(money, options[:currency] || default_currency).to_s)
99
+ response_from_result(result)
100
+ end
88
101
  end
89
102
  end
90
103
 
@@ -467,16 +480,28 @@ module ActiveMerchant #:nodoc:
467
480
  end
468
481
  end
469
482
 
483
+ def additional_processor_response_from_result(result)
484
+ result.transaction&.additional_processor_response
485
+ end
486
+
470
487
  def create_transaction(transaction_type, money, credit_card_or_vault_id, options)
471
488
  transaction_params = create_transaction_parameters(money, credit_card_or_vault_id, options)
472
489
  commit do
473
490
  result = @braintree_gateway.transaction.send(transaction_type, transaction_params)
491
+ make_default_payment_method_token(result) if options.dig(:paypal, :paypal_flow_type) == 'checkout_with_vault' && result.success?
474
492
  response = Response.new(result.success?, message_from_transaction_result(result), response_params(result), response_options(result))
475
493
  response.cvv_result['message'] = ''
476
494
  response
477
495
  end
478
496
  end
479
497
 
498
+ def make_default_payment_method_token(result)
499
+ @braintree_gateway.customer.update(
500
+ result.transaction.customer_details.id,
501
+ default_payment_method_token: result.transaction.paypal_details.implicitly_vaulted_payment_method_token
502
+ )
503
+ end
504
+
480
505
  def extract_refund_args(args)
481
506
  options = args.extract_options!
482
507
 
@@ -516,7 +541,10 @@ module ActiveMerchant #:nodoc:
516
541
  end
517
542
 
518
543
  def transaction_hash(result)
519
- return { 'processor_response_code' => response_code_from_result(result) } unless result.success?
544
+ unless result.success?
545
+ return { 'processor_response_code' => response_code_from_result(result),
546
+ 'additional_processor_response' => additional_processor_response_from_result(result) }
547
+ end
520
548
 
521
549
  transaction = result.transaction
522
550
  if transaction.vault_customer
@@ -576,19 +604,20 @@ module ActiveMerchant #:nodoc:
576
604
  end
577
605
 
578
606
  {
579
- 'order_id' => transaction.order_id,
580
- 'amount' => transaction.amount.to_s,
581
- 'status' => transaction.status,
582
- 'credit_card_details' => credit_card_details,
583
- 'customer_details' => customer_details,
584
- 'billing_details' => billing_details,
585
- 'shipping_details' => shipping_details,
586
- 'vault_customer' => vault_customer,
587
- 'merchant_account_id' => transaction.merchant_account_id,
588
- 'risk_data' => risk_data,
589
- 'network_transaction_id' => transaction.network_transaction_id || nil,
590
- 'processor_response_code' => response_code_from_result(result),
591
- 'recurring' => transaction.recurring
607
+ 'order_id' => transaction.order_id,
608
+ 'amount' => transaction.amount.to_s,
609
+ 'status' => transaction.status,
610
+ 'credit_card_details' => credit_card_details,
611
+ 'customer_details' => customer_details,
612
+ 'billing_details' => billing_details,
613
+ 'shipping_details' => shipping_details,
614
+ 'vault_customer' => vault_customer,
615
+ 'merchant_account_id' => transaction.merchant_account_id,
616
+ 'risk_data' => risk_data,
617
+ 'network_transaction_id' => transaction.network_transaction_id || nil,
618
+ 'processor_response_code' => response_code_from_result(result),
619
+ 'processor_authorization_code' => transaction.processor_authorization_code,
620
+ 'recurring' => transaction.recurring
592
621
  }
593
622
  end
594
623
 
@@ -616,6 +645,7 @@ module ActiveMerchant #:nodoc:
616
645
  add_account_type(parameters, options) if options[:account_type]
617
646
  add_skip_options(parameters, options)
618
647
  add_merchant_account_id(parameters, options)
648
+ add_profile_id(parameters, options)
619
649
 
620
650
  add_payment_method(parameters, credit_card_or_vault_id, options)
621
651
  add_stored_credential_data(parameters, credit_card_or_vault_id, options)
@@ -623,6 +653,7 @@ module ActiveMerchant #:nodoc:
623
653
 
624
654
  add_descriptor(parameters, options)
625
655
  add_risk_data(parameters, options)
656
+ add_paypal_options(parameters, options)
626
657
  add_travel_data(parameters, options) if options[:travel_data]
627
658
  add_lodging_data(parameters, options) if options[:lodging_data]
628
659
  add_channel(parameters, options)
@@ -658,6 +689,13 @@ module ActiveMerchant #:nodoc:
658
689
  parameters[:merchant_account_id] = merchant_account_id
659
690
  end
660
691
 
692
+ def add_profile_id(parameters, options)
693
+ return unless profile_id = options[:venmo_profile_id]
694
+
695
+ parameters[:options][:venmo] = {}
696
+ parameters[:options][:venmo][:profile_id] = profile_id
697
+ end
698
+
661
699
  def add_transaction_source(parameters, options)
662
700
  parameters[:transaction_source] = options[:transaction_source] if options[:transaction_source]
663
701
  parameters[:transaction_source] = 'recurring' if options[:recurring]
@@ -692,6 +730,15 @@ module ActiveMerchant #:nodoc:
692
730
  }
693
731
  end
694
732
 
733
+ def add_paypal_options(parameters, options)
734
+ return unless options[:paypal_custom_field] || options[:paypal_description]
735
+
736
+ parameters[:options][:paypal] = {
737
+ custom_field: options[:paypal_custom_field],
738
+ description: options[:paypal_description]
739
+ }
740
+ end
741
+
695
742
  def add_level_2_data(parameters, options)
696
743
  parameters[:tax_amount] = options[:tax_amount] if options[:tax_amount]
697
744
  parameters[:tax_exempt] = options[:tax_exempt] if options[:tax_exempt]
@@ -1,8 +1,8 @@
1
1
  module ActiveMerchant #:nodoc:
2
2
  module Billing #:nodoc:
3
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/'
4
+ self.test_url = 'https://fts-uat.cardconnect.com/cardconnect/rest/'
5
+ self.live_url = 'https://fts.cardconnect.com/cardconnect/rest/'
6
6
 
7
7
  self.supported_countries = ['US']
8
8
  self.default_currency = 'USD'
@@ -61,6 +61,8 @@ module ActiveMerchant #:nodoc:
61
61
  '60' => STANDARD_ERROR_CODE[:pickup_card]
62
62
  }
63
63
 
64
+ SCHEDULED_PAYMENT_TYPES = %w(recurring installment)
65
+
64
66
  def initialize(options = {})
65
67
  requires!(options, :merchant_id, :username, :password)
66
68
  require_valid_domain!(options, :domain)
@@ -87,8 +89,9 @@ module ActiveMerchant #:nodoc:
87
89
  add_currency(post, money, options)
88
90
  add_address(post, options)
89
91
  add_customer_data(post, options)
90
- add_3DS(post, options)
92
+ add_three_ds_mpi_data(post, options)
91
93
  add_additional_data(post, options)
94
+ add_stored_credential(post, options)
92
95
  post[:capture] = 'Y'
93
96
  commit('auth', post)
94
97
  end
@@ -102,8 +105,9 @@ module ActiveMerchant #:nodoc:
102
105
  add_payment(post, payment)
103
106
  add_address(post, options)
104
107
  add_customer_data(post, options)
105
- add_3DS(post, options)
108
+ add_three_ds_mpi_data(post, options)
106
109
  add_additional_data(post, options)
110
+ add_stored_credential(post, options)
107
111
  commit('auth', post)
108
112
  end
109
113
 
@@ -188,7 +192,11 @@ module ActiveMerchant #:nodoc:
188
192
 
189
193
  def add_invoice(post, options)
190
194
  post[:orderid] = options[:order_id]
191
- post[:ecomind] = (options[:recurring] ? 'R' : 'E')
195
+ post[:ecomind] = if options[:ecomind]
196
+ options[:ecomind].capitalize
197
+ else
198
+ (options[:recurring] ? 'R' : 'E')
199
+ end
192
200
  end
193
201
 
194
202
  def add_payment(post, payment)
@@ -241,10 +249,20 @@ module ActiveMerchant #:nodoc:
241
249
  post[:userfields] = options[:user_fields] if options[:user_fields]
242
250
  end
243
251
 
244
- def add_3DS(post, options)
245
- post[:secureflag] = options[:secure_flag] if options[:secure_flag]
246
- post[:securevalue] = options[:secure_value] if options[:secure_value]
247
- post[:securexid] = options[:secure_xid] if options[:secure_xid]
252
+ def add_three_ds_mpi_data(post, options)
253
+ return unless three_d_secure = options[:three_d_secure]
254
+
255
+ post[:secureflag] = three_d_secure[:eci]
256
+ post[:securevalue] = three_d_secure[:cavv]
257
+ post[:securedstid] = three_d_secure[:ds_transaction_id]
258
+ end
259
+
260
+ def add_stored_credential(post, options)
261
+ return unless stored_credential = options[:stored_credential]
262
+
263
+ post[:cof] = stored_credential[:initiator] == 'merchant' ? 'M' : 'C'
264
+ post[:cofscheduled] = SCHEDULED_PAYMENT_TYPES.include?(stored_credential[:reason_type]) ? 'Y' : 'N'
265
+ post[:cofpermission] = stored_credential[:initial_transaction] ? 'Y' : 'N'
248
266
  end
249
267
 
250
268
  def headers
@@ -222,6 +222,7 @@ module ActiveMerchant #:nodoc:
222
222
  add_customer_data(post, options)
223
223
  add_remote_address(post, options)
224
224
  add_country_code(post, options)
225
+ add_threeds_fields(post, options)
225
226
  end
226
227
 
227
228
  def add_amount(post, money, options)
@@ -283,6 +284,20 @@ module ActiveMerchant #:nodoc:
283
284
  add_pair(post, :threeDSRequired, options[:threeds_required] || @threeds_required ? 'Y' : 'N')
284
285
  end
285
286
 
287
+ def add_threeds_fields(post, options)
288
+ return unless three_d_secure = options[:three_d_secure]
289
+
290
+ add_pair(post, :threeDSEnrolled, formatted_enrollment(three_d_secure[:enrolled]))
291
+ if three_d_secure[:enrolled] == 'true'
292
+ add_pair(post, :threeDSAuthenticated, three_d_secure[:authentication_response_status])
293
+ if three_d_secure[:authentication_response_status] == 'Y'
294
+ post[:threeDSECI] = three_d_secure[:eci]
295
+ post[:threeDSCAVV] = three_d_secure[:cavv]
296
+ post[:threeDSXID] = three_d_secure[:xid] || three_d_secure[:ds_transaction_id]
297
+ end
298
+ end
299
+ end
300
+
286
301
  def add_remote_address(post, options = {})
287
302
  add_pair(post, :remoteAddress, options[:ip] || '1.1.1.1')
288
303
  end
@@ -366,6 +381,14 @@ module ActiveMerchant #:nodoc:
366
381
  def add_pair(post, key, value, options = {})
367
382
  post[key] = value if !value.blank? || options[:required]
368
383
  end
384
+
385
+ def formatted_enrollment(val)
386
+ case val
387
+ when 'Y', 'N', 'U' then val
388
+ when true, 'true' then 'Y'
389
+ when false, 'false' then 'N'
390
+ end
391
+ end
369
392
  end
370
393
  end
371
394
  end