aktivemerchant 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (193) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +1596 -0
  3. data/CONTRIBUTORS +511 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +18 -0
  6. data/lib/active_merchant.rb +108 -0
  7. data/lib/active_merchant/billing.rb +13 -0
  8. data/lib/active_merchant/billing/apple_pay_payment_token.rb +22 -0
  9. data/lib/active_merchant/billing/avs_result.rb +98 -0
  10. data/lib/active_merchant/billing/base.rb +72 -0
  11. data/lib/active_merchant/billing/check.rb +76 -0
  12. data/lib/active_merchant/billing/compatibility.rb +120 -0
  13. data/lib/active_merchant/billing/credit_card.rb +352 -0
  14. data/lib/active_merchant/billing/credit_card_formatting.rb +24 -0
  15. data/lib/active_merchant/billing/credit_card_methods.rb +160 -0
  16. data/lib/active_merchant/billing/cvv_result.rb +38 -0
  17. data/lib/active_merchant/billing/gateway.rb +268 -0
  18. data/lib/active_merchant/billing/gateways.rb +17 -0
  19. data/lib/active_merchant/billing/gateways/adyen.rb +209 -0
  20. data/lib/active_merchant/billing/gateways/alfabank.rb +117 -0
  21. data/lib/active_merchant/billing/gateways/app55.rb +176 -0
  22. data/lib/active_merchant/billing/gateways/authorize_net.rb +419 -0
  23. data/lib/active_merchant/billing/gateways/authorize_net_arb.rb +417 -0
  24. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +976 -0
  25. data/lib/active_merchant/billing/gateways/balanced.rb +256 -0
  26. data/lib/active_merchant/billing/gateways/bank_frick.rb +225 -0
  27. data/lib/active_merchant/billing/gateways/banwire.rb +105 -0
  28. data/lib/active_merchant/billing/gateways/barclays_epdq.rb +314 -0
  29. data/lib/active_merchant/billing/gateways/barclays_epdq_extra_plus.rb +15 -0
  30. data/lib/active_merchant/billing/gateways/be2bill.rb +131 -0
  31. data/lib/active_merchant/billing/gateways/beanstream.rb +188 -0
  32. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +393 -0
  33. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
  34. data/lib/active_merchant/billing/gateways/blue_pay.rb +506 -0
  35. data/lib/active_merchant/billing/gateways/bogus.rb +140 -0
  36. data/lib/active_merchant/billing/gateways/borgun.rb +210 -0
  37. data/lib/active_merchant/billing/gateways/braintree.rb +19 -0
  38. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
  39. data/lib/active_merchant/billing/gateways/braintree_blue.rb +515 -0
  40. data/lib/active_merchant/billing/gateways/braintree_orange.rb +20 -0
  41. data/lib/active_merchant/billing/gateways/bridge_pay.rb +189 -0
  42. data/lib/active_merchant/billing/gateways/card_save.rb +23 -0
  43. data/lib/active_merchant/billing/gateways/card_stream.rb +220 -0
  44. data/lib/active_merchant/billing/gateways/cashnet.rb +191 -0
  45. data/lib/active_merchant/billing/gateways/cc5.rb +201 -0
  46. data/lib/active_merchant/billing/gateways/cecabank.rb +229 -0
  47. data/lib/active_merchant/billing/gateways/certo_direct.rb +278 -0
  48. data/lib/active_merchant/billing/gateways/checkout.rb +213 -0
  49. data/lib/active_merchant/billing/gateways/commercegate.rb +143 -0
  50. data/lib/active_merchant/billing/gateways/conekta.rb +209 -0
  51. data/lib/active_merchant/billing/gateways/cyber_source.rb +709 -0
  52. data/lib/active_merchant/billing/gateways/data_cash.rb +600 -0
  53. data/lib/active_merchant/billing/gateways/efsnet.rb +219 -0
  54. data/lib/active_merchant/billing/gateways/elavon.rb +348 -0
  55. data/lib/active_merchant/billing/gateways/epay.rb +275 -0
  56. data/lib/active_merchant/billing/gateways/evo_ca.rb +308 -0
  57. data/lib/active_merchant/billing/gateways/eway.rb +214 -0
  58. data/lib/active_merchant/billing/gateways/eway_managed.rb +291 -0
  59. data/lib/active_merchant/billing/gateways/eway_rapid.rb +524 -0
  60. data/lib/active_merchant/billing/gateways/exact.rb +218 -0
  61. data/lib/active_merchant/billing/gateways/fat_zebra.rb +173 -0
  62. data/lib/active_merchant/billing/gateways/federated_canada.rb +160 -0
  63. data/lib/active_merchant/billing/gateways/finansbank.rb +23 -0
  64. data/lib/active_merchant/billing/gateways/first_giving.rb +143 -0
  65. data/lib/active_merchant/billing/gateways/first_pay.rb +160 -0
  66. data/lib/active_merchant/billing/gateways/firstdata_e4.rb +355 -0
  67. data/lib/active_merchant/billing/gateways/garanti.rb +257 -0
  68. data/lib/active_merchant/billing/gateways/global_transport.rb +183 -0
  69. data/lib/active_merchant/billing/gateways/hdfc.rb +207 -0
  70. data/lib/active_merchant/billing/gateways/hps.rb +288 -0
  71. data/lib/active_merchant/billing/gateways/iats_payments.rb +251 -0
  72. data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +246 -0
  73. data/lib/active_merchant/billing/gateways/ideal/ideal_rabobank.pem +13 -0
  74. data/lib/active_merchant/billing/gateways/ideal/ideal_response.rb +29 -0
  75. data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +66 -0
  76. data/lib/active_merchant/billing/gateways/inspire.rb +213 -0
  77. data/lib/active_merchant/billing/gateways/instapay.rb +163 -0
  78. data/lib/active_merchant/billing/gateways/iridium.rb +457 -0
  79. data/lib/active_merchant/billing/gateways/itransact.rb +448 -0
  80. data/lib/active_merchant/billing/gateways/jetpay.rb +275 -0
  81. data/lib/active_merchant/billing/gateways/linkpoint.rb +438 -0
  82. data/lib/active_merchant/billing/gateways/litle.rb +346 -0
  83. data/lib/active_merchant/billing/gateways/maxipago.rb +197 -0
  84. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +170 -0
  85. data/lib/active_merchant/billing/gateways/merchant_one.rb +114 -0
  86. data/lib/active_merchant/billing/gateways/merchant_ware.rb +319 -0
  87. data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +268 -0
  88. data/lib/active_merchant/billing/gateways/merchant_warrior.rb +195 -0
  89. data/lib/active_merchant/billing/gateways/mercury.rb +333 -0
  90. data/lib/active_merchant/billing/gateways/metrics_global.rb +303 -0
  91. data/lib/active_merchant/billing/gateways/migs.rb +265 -0
  92. data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +100 -0
  93. data/lib/active_merchant/billing/gateways/modern_payments.rb +37 -0
  94. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +219 -0
  95. data/lib/active_merchant/billing/gateways/moneris.rb +309 -0
  96. data/lib/active_merchant/billing/gateways/moneris_us.rb +291 -0
  97. data/lib/active_merchant/billing/gateways/money_movers.rb +152 -0
  98. data/lib/active_merchant/billing/gateways/nab_transact.rb +280 -0
  99. data/lib/active_merchant/billing/gateways/net_registry.rb +198 -0
  100. data/lib/active_merchant/billing/gateways/netaxept.rb +181 -0
  101. data/lib/active_merchant/billing/gateways/netbilling.rb +190 -0
  102. data/lib/active_merchant/billing/gateways/netpay.rb +223 -0
  103. data/lib/active_merchant/billing/gateways/network_merchants.rb +242 -0
  104. data/lib/active_merchant/billing/gateways/nmi.rb +256 -0
  105. data/lib/active_merchant/billing/gateways/ogone.rb +435 -0
  106. data/lib/active_merchant/billing/gateways/openpay.rb +194 -0
  107. data/lib/active_merchant/billing/gateways/optimal_payment.rb +313 -0
  108. data/lib/active_merchant/billing/gateways/orbital.rb +803 -0
  109. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +47 -0
  110. data/lib/active_merchant/billing/gateways/pac_net_raven.rb +207 -0
  111. data/lib/active_merchant/billing/gateways/pago_facil.rb +122 -0
  112. data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +261 -0
  113. data/lib/active_merchant/billing/gateways/pay_junction.rb +390 -0
  114. data/lib/active_merchant/billing/gateways/pay_secure.rb +112 -0
  115. data/lib/active_merchant/billing/gateways/pay_u_latam.rb +462 -0
  116. data/lib/active_merchant/billing/gateways/paybox_direct.rb +188 -0
  117. data/lib/active_merchant/billing/gateways/payex.rb +412 -0
  118. data/lib/active_merchant/billing/gateways/payflow.rb +304 -0
  119. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +209 -0
  120. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
  121. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  122. data/lib/active_merchant/billing/gateways/payflow_express.rb +224 -0
  123. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
  124. data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
  125. data/lib/active_merchant/billing/gateways/payment_express.rb +353 -0
  126. data/lib/active_merchant/billing/gateways/paymill.rb +281 -0
  127. data/lib/active_merchant/billing/gateways/paypal.rb +117 -0
  128. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +670 -0
  129. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +65 -0
  130. data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +262 -0
  131. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  132. data/lib/active_merchant/billing/gateways/paypal_digital_goods.rb +44 -0
  133. data/lib/active_merchant/billing/gateways/paypal_express.rb +264 -0
  134. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +30 -0
  135. data/lib/active_merchant/billing/gateways/payscout.rb +162 -0
  136. data/lib/active_merchant/billing/gateways/paystation.rb +199 -0
  137. data/lib/active_merchant/billing/gateways/payway.rb +207 -0
  138. data/lib/active_merchant/billing/gateways/pin.rb +197 -0
  139. data/lib/active_merchant/billing/gateways/plugnpay.rb +283 -0
  140. data/lib/active_merchant/billing/gateways/psigate.rb +216 -0
  141. data/lib/active_merchant/billing/gateways/psl_card.rb +303 -0
  142. data/lib/active_merchant/billing/gateways/qbms.rb +292 -0
  143. data/lib/active_merchant/billing/gateways/quantum.rb +276 -0
  144. data/lib/active_merchant/billing/gateways/quickpay.rb +367 -0
  145. data/lib/active_merchant/billing/gateways/realex.rb +298 -0
  146. data/lib/active_merchant/billing/gateways/redsys.rb +391 -0
  147. data/lib/active_merchant/billing/gateways/sage.rb +175 -0
  148. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +87 -0
  149. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +114 -0
  150. data/lib/active_merchant/billing/gateways/sage/sage_vault.rb +149 -0
  151. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +102 -0
  152. data/lib/active_merchant/billing/gateways/sage_pay.rb +398 -0
  153. data/lib/active_merchant/billing/gateways/sallie_mae.rb +143 -0
  154. data/lib/active_merchant/billing/gateways/secure_net.rb +252 -0
  155. data/lib/active_merchant/billing/gateways/secure_pay.rb +201 -0
  156. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +281 -0
  157. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +105 -0
  158. data/lib/active_merchant/billing/gateways/skip_jack.rb +452 -0
  159. data/lib/active_merchant/billing/gateways/smart_ps.rb +283 -0
  160. data/lib/active_merchant/billing/gateways/so_easy_pay.rb +194 -0
  161. data/lib/active_merchant/billing/gateways/spreedly_core.rb +247 -0
  162. data/lib/active_merchant/billing/gateways/stripe.rb +411 -0
  163. data/lib/active_merchant/billing/gateways/swipe_checkout.rb +157 -0
  164. data/lib/active_merchant/billing/gateways/tns.rb +227 -0
  165. data/lib/active_merchant/billing/gateways/trans_first.rb +126 -0
  166. data/lib/active_merchant/billing/gateways/transax.rb +23 -0
  167. data/lib/active_merchant/billing/gateways/transnational.rb +10 -0
  168. data/lib/active_merchant/billing/gateways/trust_commerce.rb +416 -0
  169. data/lib/active_merchant/billing/gateways/usa_epay.rb +25 -0
  170. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +1516 -0
  171. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +254 -0
  172. data/lib/active_merchant/billing/gateways/verifi.rb +225 -0
  173. data/lib/active_merchant/billing/gateways/viaklix.rb +183 -0
  174. data/lib/active_merchant/billing/gateways/vindicia.rb +385 -0
  175. data/lib/active_merchant/billing/gateways/webpay.rb +97 -0
  176. data/lib/active_merchant/billing/gateways/wepay.rb +189 -0
  177. data/lib/active_merchant/billing/gateways/wirecard.rb +421 -0
  178. data/lib/active_merchant/billing/gateways/worldpay.rb +331 -0
  179. data/lib/active_merchant/billing/gateways/worldpay_us.rb +181 -0
  180. data/lib/active_merchant/billing/model.rb +30 -0
  181. data/lib/active_merchant/billing/payment_token.rb +21 -0
  182. data/lib/active_merchant/billing/rails.rb +3 -0
  183. data/lib/active_merchant/billing/response.rb +91 -0
  184. data/lib/active_merchant/country.rb +332 -0
  185. data/lib/active_merchant/empty.rb +20 -0
  186. data/lib/active_merchant/errors.rb +29 -0
  187. data/lib/active_merchant/offsite_payments_shim.rb +19 -0
  188. data/lib/active_merchant/version.rb +3 -0
  189. data/lib/activemerchant.rb +1 -0
  190. data/lib/support/gateway_support.rb +71 -0
  191. data/lib/support/outbound_hosts.rb +25 -0
  192. data/lib/support/ssl_verify.rb +93 -0
  193. metadata +400 -0
@@ -0,0 +1,140 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ # Bogus Gateway
4
+ class BogusGateway < Gateway
5
+ AUTHORIZATION = '53433'
6
+
7
+ SUCCESS_MESSAGE = "Bogus Gateway: Forced success"
8
+ FAILURE_MESSAGE = "Bogus Gateway: Forced failure"
9
+ ERROR_MESSAGE = "Bogus Gateway: Use CreditCard number ending in 1 for success, 2 for exception and anything else for error"
10
+ UNSTORE_ERROR_MESSAGE = "Bogus Gateway: Use trans_id ending in 1 for success, 2 for exception and anything else for error"
11
+ CAPTURE_ERROR_MESSAGE = "Bogus Gateway: Use authorization number ending in 1 for exception, 2 for error and anything else for success"
12
+ VOID_ERROR_MESSAGE = "Bogus Gateway: Use authorization number ending in 1 for exception, 2 for error and anything else for success"
13
+ REFUND_ERROR_MESSAGE = "Bogus Gateway: Use trans_id number ending in 1 for exception, 2 for error and anything else for success"
14
+ CHECK_ERROR_MESSAGE = "Bogus Gateway: Use bank account number ending in 1 for success, 2 for exception and anything else for error"
15
+
16
+ self.supported_countries = []
17
+ self.supported_cardtypes = [:bogus]
18
+ self.homepage_url = 'http://example.com'
19
+ self.display_name = 'Bogus'
20
+
21
+ def authorize(money, paysource, options = {})
22
+ money = amount(money)
23
+ case normalize(paysource)
24
+ when /1$/
25
+ Response.new(true, SUCCESS_MESSAGE, {:authorized_amount => money}, :test => true, :authorization => AUTHORIZATION )
26
+ when /2$/
27
+ Response.new(false, FAILURE_MESSAGE, {:authorized_amount => money, :error => FAILURE_MESSAGE }, :test => true, :error_code => STANDARD_ERROR_CODE[:processing_error])
28
+ else
29
+ raise Error, error_message(paysource)
30
+ end
31
+ end
32
+
33
+ def purchase(money, paysource, options = {})
34
+ money = amount(money)
35
+ case normalize(paysource)
36
+ when /1$/, AUTHORIZATION
37
+ Response.new(true, SUCCESS_MESSAGE, {:paid_amount => money}, :test => true, :authorization => AUTHORIZATION)
38
+ when /2$/
39
+ Response.new(false, FAILURE_MESSAGE, {:paid_amount => money, :error => FAILURE_MESSAGE }, :test => true, :error_code => STANDARD_ERROR_CODE[:processing_error])
40
+ else
41
+ raise Error, error_message(paysource)
42
+ end
43
+ end
44
+
45
+ def credit(money, paysource, options = {})
46
+ if paysource.is_a?(String)
47
+ ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
48
+ return refund(money, paysource, options)
49
+ end
50
+
51
+ money = amount(money)
52
+ case normalize(paysource)
53
+ when /1$/
54
+ Response.new(true, SUCCESS_MESSAGE, {:paid_amount => money}, :test => true )
55
+ when /2$/
56
+ Response.new(false, FAILURE_MESSAGE, {:paid_amount => money, :error => FAILURE_MESSAGE }, :test => true, :error_code => STANDARD_ERROR_CODE[:processing_error])
57
+ else
58
+ raise Error, error_message(paysource)
59
+ end
60
+ end
61
+
62
+ def refund(money, reference, options = {})
63
+ money = amount(money)
64
+ case reference
65
+ when /1$/
66
+ raise Error, REFUND_ERROR_MESSAGE
67
+ when /2$/
68
+ Response.new(false, FAILURE_MESSAGE, {:paid_amount => money, :error => FAILURE_MESSAGE }, :test => true, :error_code => STANDARD_ERROR_CODE[:processing_error])
69
+ else
70
+ Response.new(true, SUCCESS_MESSAGE, {:paid_amount => money}, :test => true)
71
+ end
72
+ end
73
+
74
+ def capture(money, reference, options = {})
75
+ money = amount(money)
76
+ case reference
77
+ when /1$/
78
+ raise Error, CAPTURE_ERROR_MESSAGE
79
+ when /2$/
80
+ Response.new(false, FAILURE_MESSAGE, {:paid_amount => money, :error => FAILURE_MESSAGE }, :test => true, :error_code => STANDARD_ERROR_CODE[:processing_error])
81
+ else
82
+ Response.new(true, SUCCESS_MESSAGE, {:paid_amount => money}, :test => true)
83
+ end
84
+ end
85
+
86
+ def void(reference, options = {})
87
+ case reference
88
+ when /1$/
89
+ raise Error, VOID_ERROR_MESSAGE
90
+ when /2$/
91
+ Response.new(false, FAILURE_MESSAGE, {:authorization => reference, :error => FAILURE_MESSAGE }, :test => true, :error_code => STANDARD_ERROR_CODE[:processing_error])
92
+ else
93
+ Response.new(true, SUCCESS_MESSAGE, {:authorization => reference}, :test => true)
94
+ end
95
+ end
96
+
97
+ def store(paysource, options = {})
98
+ case normalize(paysource)
99
+ when /1$/
100
+ Response.new(true, SUCCESS_MESSAGE, {:billingid => '1'}, :test => true, :authorization => AUTHORIZATION)
101
+ when /2$/
102
+ Response.new(false, FAILURE_MESSAGE, {:billingid => nil, :error => FAILURE_MESSAGE }, :test => true, :error_code => STANDARD_ERROR_CODE[:processing_error])
103
+ else
104
+ raise Error, error_message(paysource)
105
+ end
106
+ end
107
+
108
+ def unstore(reference, options = {})
109
+ case reference
110
+ when /1$/
111
+ Response.new(true, SUCCESS_MESSAGE, {}, :test => true)
112
+ when /2$/
113
+ Response.new(false, FAILURE_MESSAGE, {:error => FAILURE_MESSAGE },:test => true, :error_code => STANDARD_ERROR_CODE[:processing_error])
114
+ else
115
+ raise Error, UNSTORE_ERROR_MESSAGE
116
+ end
117
+ end
118
+
119
+ private
120
+
121
+ def normalize(paysource)
122
+ if paysource.respond_to?(:account_number) && (paysource.try(:number).blank? || paysource.number.blank?)
123
+ paysource.account_number
124
+ elsif paysource.respond_to?(:number)
125
+ paysource.number
126
+ else
127
+ paysource.to_s
128
+ end
129
+ end
130
+
131
+ def error_message(paysource)
132
+ if paysource.respond_to?(:account_number)
133
+ CHECK_ERROR_MESSAGE
134
+ elsif paysource.respond_to?(:number)
135
+ ERROR_MESSAGE
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,210 @@
1
+ require "nokogiri"
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ class BorgunGateway < Gateway
6
+ self.display_name = "Borgun"
7
+
8
+ self.test_url = 'https://gatewaytest.borgun.is/ws/Heimir.pub.ws:Authorization'
9
+ self.live_url = 'https://gateway01.borgun.is/ws/Heimir.pub.ws:Authorization'
10
+
11
+ self.supported_countries = ['IS']
12
+ self.default_currency = 'ISK'
13
+ self.money_format = :cents
14
+ self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :discover, :jcb]
15
+
16
+ self.homepage_url = 'https://www.borgun.is/'
17
+
18
+ def initialize(options={})
19
+ requires!(options, :processor, :merchant_id, :username, :password)
20
+ super
21
+ end
22
+
23
+ def purchase(money, payment, options={})
24
+ post = {}
25
+ post[:TransType] = '1'
26
+ add_invoice(post, money, options)
27
+ add_payment_method(post, payment)
28
+
29
+ commit('sale', post)
30
+ end
31
+
32
+ def authorize(money, payment, options={})
33
+ post = {}
34
+ post[:TransType] = '5'
35
+ add_invoice(post, money, options)
36
+ add_payment_method(post, payment)
37
+
38
+ commit('authonly', post)
39
+ end
40
+
41
+ def capture(money, authorization, options={})
42
+ post = {}
43
+ post[:TransType] = '1'
44
+ add_invoice(post, money, options)
45
+ add_reference(post, authorization)
46
+ commit('capture', post)
47
+ end
48
+
49
+ def refund(money, authorization, options={})
50
+ post = {}
51
+ post[:TransType] = '3'
52
+ add_invoice(post, money, options)
53
+ add_reference(post, authorization)
54
+ commit('refund', post)
55
+ end
56
+
57
+ def void(authorization, options={})
58
+ post = {}
59
+ # TransType and TrAmount must match original values from auth or purchase.
60
+ _, _, _, _, _, transtype, tramount = split_authorization(authorization)
61
+ post[:TransType] = transtype
62
+ add_invoice(post, tramount.to_i, options)
63
+ add_reference(post, authorization)
64
+ commit('void', post)
65
+ end
66
+
67
+ private
68
+
69
+ CURRENCY_CODES = Hash.new{|h,k| raise ArgumentError.new("Unsupported currency for HDFC: #{k}")}
70
+ CURRENCY_CODES["ISK"] = "352"
71
+ CURRENCY_CODES["EUR"] = "978"
72
+
73
+ def add_invoice(post, money, options)
74
+ post[:TrAmount] = amount(money)
75
+ post[:TrCurrency] = CURRENCY_CODES[options[:currency] || currency(money)]
76
+ end
77
+
78
+ def add_payment_method(post, payment_method)
79
+ post[:PAN] = payment_method.number
80
+ post[:ExpDate] = format(payment_method.year, :two_digits) + format(payment_method.month, :two_digits)
81
+ post[:CVC2] = payment_method.verification_value
82
+ post[:DateAndTime] = Time.now.strftime("%y%m%d%H%M%S")
83
+ post[:RRN] = 'AMRCNT' + six_random_digits
84
+ end
85
+
86
+ def add_reference(post, authorization)
87
+ dateandtime, batch, transaction, rrn, authcode, _, _ = split_authorization(authorization)
88
+ post[:DateAndTime] = dateandtime
89
+ post[:Batch] = batch
90
+ post[:Transaction] = transaction
91
+ post[:RRN] = rrn
92
+ post[:AuthCode] = authcode
93
+ end
94
+
95
+ def parse(xml)
96
+ response = {}
97
+
98
+ doc = Nokogiri::XML(CGI.unescapeHTML(xml))
99
+ body = doc.xpath('//getAuthorizationReply')
100
+ body = doc.xpath('//cancelAuthorizationReply') if body.length == 0
101
+ body.children.each do |node|
102
+ if node.text?
103
+ next
104
+ elsif (node.elements.size == 0)
105
+ response[node.name.downcase.to_sym] = node.text
106
+ else
107
+ node.elements.each do |childnode|
108
+ name = "#{node.name.downcase}_#{childnode.name.downcase}"
109
+ response[name.to_sym] = childnode.text
110
+ end
111
+ end
112
+ end
113
+
114
+ response
115
+ end
116
+
117
+ def commit(action, post)
118
+ post[:Version] = '1000'
119
+ post[:Processor] = @options[:processor]
120
+ post[:MerchantID] = @options[:merchant_id]
121
+ post[:TerminalID] = 1
122
+
123
+ url = (test? ? test_url : live_url)
124
+ request = build_request(action, post)
125
+ raw = ssl_post(url(action), request, headers)
126
+ pairs = parse(raw)
127
+ success = success_from(pairs)
128
+
129
+ Response.new(
130
+ success,
131
+ message_from(success, pairs),
132
+ pairs,
133
+ authorization: authorization_from(pairs),
134
+ test: test?
135
+ )
136
+ end
137
+
138
+ def success_from(response)
139
+ (response[:actioncode] == '000')
140
+ end
141
+
142
+ def message_from(succeeded, response)
143
+ if succeeded
144
+ "Succeeded"
145
+ else
146
+ response[:message] || "Error with ActionCode=#{response[:actioncode]}"
147
+ end
148
+ end
149
+
150
+ def authorization_from(response)
151
+ [
152
+ response[:dateandtime],
153
+ response[:batch],
154
+ response[:transaction],
155
+ response[:rrn],
156
+ response[:authcode],
157
+ response[:transtype],
158
+ response[:tramount]
159
+ ].join("|")
160
+ end
161
+
162
+ def split_authorization(authorization)
163
+ dateandtime, batch, transaction, rrn, authcode, transtype, tramount = authorization.split("|")
164
+ [dateandtime, batch, transaction, rrn, authcode, transtype, tramount]
165
+ end
166
+
167
+ def headers
168
+ {
169
+ 'Authorization' => 'Basic ' + Base64.strict_encode64(@options[:username].to_s + ':' + @options[:password].to_s),
170
+ }
171
+ end
172
+
173
+ def build_request(action, post)
174
+ mode = (action == 'void') ? 'cancel' : 'get'
175
+ xml = Builder::XmlMarkup.new :indent => 18
176
+ xml.instruct!(:xml, :version => '1.0', :encoding => 'utf-8')
177
+ xml.tag!("#{mode}Authorization") do
178
+ post.each do |field, value|
179
+ xml.tag!(field, value)
180
+ end
181
+ end
182
+ inner = CGI.escapeHTML(xml.target!)
183
+ envelope(mode).sub(/{{ :body }}/,inner)
184
+ end
185
+
186
+ def envelope(mode)
187
+ <<-EOS
188
+ <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:aut="http://Borgun/Heimir/pub/ws/Authorization">
189
+ <soapenv:Header/>
190
+ <soapenv:Body>
191
+ <aut:#{mode}AuthorizationInput>
192
+ <#{mode}AuthReqXml>
193
+ {{ :body }}
194
+ </#{mode}AuthReqXml>
195
+ </aut:#{mode}AuthorizationInput>
196
+ </soapenv:Body>
197
+ </soapenv:Envelope>
198
+ EOS
199
+ end
200
+
201
+ def url(action)
202
+ (test? ? test_url : live_url)
203
+ end
204
+
205
+ def six_random_digits
206
+ (0...6).map { (48 + rand(10)).chr }.join
207
+ end
208
+ end
209
+ end
210
+ end
@@ -0,0 +1,19 @@
1
+ require File.dirname(__FILE__) + '/braintree/braintree_common'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ class BraintreeGateway < Gateway
6
+ include BraintreeCommon
7
+
8
+ self.abstract_class = true
9
+
10
+ def self.new(options={})
11
+ if options.has_key?(:login)
12
+ BraintreeOrangeGateway.new(options)
13
+ else
14
+ BraintreeBlueGateway.new(options)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,9 @@
1
+ module BraintreeCommon
2
+ def self.included(base)
3
+ base.supported_countries = %w(US CA AU AD AT BE BG CY CZ DK EE FI FR GI DE GR HU IS IM IE IT LV LI LT LU MT MC NL NO PL PT RO SM SK SI ES SE CH TR GB)
4
+ base.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club]
5
+ base.homepage_url = 'http://www.braintreepaymentsolutions.com'
6
+ base.display_name = 'Braintree'
7
+ base.default_currency = 'USD'
8
+ end
9
+ end
@@ -0,0 +1,515 @@
1
+ require File.dirname(__FILE__) + '/braintree/braintree_common'
2
+
3
+ begin
4
+ require "braintree"
5
+ rescue LoadError
6
+ raise "Could not load the braintree gem. Use `gem install braintree` to install it."
7
+ end
8
+
9
+ raise "Need braintree gem 2.x.y. Run `gem install braintree --version '~>2.0'` to get the correct version." unless Braintree::Version::Major == 2
10
+
11
+ module ActiveMerchant #:nodoc:
12
+ module Billing #:nodoc:
13
+ # For more information on the Braintree Gateway please visit their
14
+ # {Developer Portal}[https://www.braintreepayments.com/developers]
15
+ #
16
+ # ==== About this implementation
17
+ #
18
+ # This implementation leverages the Braintree-authored ruby gem:
19
+ # https://github.com/braintree/braintree_ruby
20
+ #
21
+ # ==== Debugging Information
22
+ #
23
+ # Setting an ActiveMerchant +wiredump_device+ will automatically
24
+ # configure the Braintree logger (via the Braintree gem's
25
+ # configuration) when the BraintreeBlueGateway is instantiated.
26
+ # Additionally, the log level will be set to +DEBUG+. Therefore,
27
+ # all you have to do is set the +wiredump_device+ and you'll get
28
+ # your debug output from your HTTP interactions with the remote
29
+ # gateway. (Don't enable this in production.) The ActiveMerchant
30
+ # implementation doesn't mess with the Braintree::Configuration
31
+ # globals at all, so there won't be any side effects outside
32
+ # Active Merchant.
33
+ #
34
+ # If no +wiredump_device+ is set, the logger in
35
+ # +Braintree::Configuration.logger+ will be cloned and the log
36
+ # level set to +WARN+.
37
+ #
38
+ class BraintreeBlueGateway < Gateway
39
+ include BraintreeCommon
40
+
41
+ self.display_name = 'Braintree (Blue Platform)'
42
+
43
+ def initialize(options = {})
44
+ requires!(options, :merchant_id, :public_key, :private_key)
45
+ @merchant_account_id = options[:merchant_account_id]
46
+
47
+ super
48
+
49
+ if wiredump_device
50
+ logger = ((Logger === wiredump_device) ? wiredump_device : Logger.new(wiredump_device))
51
+ logger.level = Logger::DEBUG
52
+ else
53
+ logger = Braintree::Configuration.logger.clone
54
+ logger.level = Logger::WARN
55
+ end
56
+
57
+ @configuration = Braintree::Configuration.new(
58
+ :merchant_id => options[:merchant_id],
59
+ :public_key => options[:public_key],
60
+ :private_key => options[:private_key],
61
+ :environment => (options[:environment] || (test? ? :sandbox : :production)).to_sym,
62
+ :custom_user_agent => "ActiveMerchant #{ActiveMerchant::VERSION}",
63
+ :logger => logger,
64
+ )
65
+
66
+ @braintree_gateway = Braintree::Gateway.new( @configuration )
67
+ end
68
+
69
+ def authorize(money, credit_card_or_vault_id, options = {})
70
+ create_transaction(:sale, money, credit_card_or_vault_id, options)
71
+ end
72
+
73
+ def capture(money, authorization, options = {})
74
+ commit do
75
+ result = @braintree_gateway.transaction.submit_for_settlement(authorization, amount(money).to_s)
76
+ response_from_result(result)
77
+ end
78
+ end
79
+
80
+ def purchase(money, credit_card_or_vault_id, options = {})
81
+ authorize(money, credit_card_or_vault_id, options.merge(:submit_for_settlement => true))
82
+ end
83
+
84
+ def credit(money, credit_card_or_vault_id, options = {})
85
+ create_transaction(:credit, money, credit_card_or_vault_id, options)
86
+ end
87
+
88
+ def refund(*args)
89
+ # legacy signature: #refund(transaction_id, options = {})
90
+ # new signature: #refund(money, transaction_id, options = {})
91
+ money, transaction_id, _ = extract_refund_args(args)
92
+ money = amount(money).to_s if money
93
+
94
+ commit do
95
+ response_from_result(@braintree_gateway.transaction.refund(transaction_id, money))
96
+ end
97
+ end
98
+
99
+ def void(authorization, options = {})
100
+ commit do
101
+ response_from_result(@braintree_gateway.transaction.void(authorization))
102
+ end
103
+ end
104
+
105
+ def verify(credit_card, options = {})
106
+ MultiResponse.run(:use_first_response) do |r|
107
+ r.process { authorize(100, credit_card, options) }
108
+ r.process(:ignore_result) { void(r.authorization, options) }
109
+ end
110
+ end
111
+
112
+ def store(creditcard, options = {})
113
+ if options[:customer].present?
114
+ MultiResponse.new.tap do |r|
115
+ customer_exists_response = nil
116
+ r.process{customer_exists_response = check_customer_exists(options[:customer])}
117
+ r.process do
118
+ if customer_exists_response.params["exists"]
119
+ add_credit_card_to_customer(creditcard, options)
120
+ else
121
+ add_customer_with_credit_card(creditcard, options)
122
+ end
123
+ end
124
+ end
125
+ else
126
+ add_customer_with_credit_card(creditcard, options)
127
+ end
128
+ end
129
+
130
+ def update(vault_id, creditcard, options = {})
131
+ braintree_credit_card = nil
132
+ commit do
133
+ braintree_credit_card = @braintree_gateway.customer.find(vault_id).credit_cards.detect { |cc| cc.default? }
134
+ return Response.new(false, 'Braintree::NotFoundError') if braintree_credit_card.nil?
135
+
136
+ options.merge!(:update_existing_token => braintree_credit_card.token)
137
+ credit_card_params = merge_credit_card_options({
138
+ :credit_card => {
139
+ :cardholder_name => creditcard.name,
140
+ :number => creditcard.number,
141
+ :cvv => creditcard.verification_value,
142
+ :expiration_month => creditcard.month.to_s.rjust(2, "0"),
143
+ :expiration_year => creditcard.year.to_s
144
+ }
145
+ }, options)[:credit_card]
146
+
147
+ result = @braintree_gateway.customer.update(vault_id,
148
+ :first_name => creditcard.first_name,
149
+ :last_name => creditcard.last_name,
150
+ :email => scrub_email(options[:email]),
151
+ :credit_card => credit_card_params
152
+ )
153
+ Response.new(result.success?, message_from_result(result),
154
+ :braintree_customer => (customer_hash(@braintree_gateway.customer.find(vault_id), :include_credit_cards) if result.success?),
155
+ :customer_vault_id => (result.customer.id if result.success?)
156
+ )
157
+ end
158
+ end
159
+
160
+ def unstore(customer_vault_id, options = {})
161
+ commit do
162
+ if(!customer_vault_id && options[:credit_card_token])
163
+ @braintree_gateway.credit_card.delete(options[:credit_card_token])
164
+ else
165
+ @braintree_gateway.customer.delete(customer_vault_id)
166
+ end
167
+ Response.new(true, "OK")
168
+ end
169
+ end
170
+ alias_method :delete, :unstore
171
+
172
+ private
173
+
174
+ def check_customer_exists(customer_vault_id)
175
+ commit do
176
+ begin
177
+ @braintree_gateway.customer.find(customer_vault_id)
178
+ ActiveMerchant::Billing::Response.new(true, "Customer found", {exists: true}, authorization: customer_vault_id)
179
+ rescue Braintree::NotFoundError
180
+ ActiveMerchant::Billing::Response.new(true, "Customer not found", {exists: false})
181
+ end
182
+ end
183
+ end
184
+
185
+ def add_customer_with_credit_card(creditcard, options)
186
+ commit do
187
+ parameters = {
188
+ :first_name => creditcard.first_name,
189
+ :last_name => creditcard.last_name,
190
+ :email => scrub_email(options[:email]),
191
+ :id => options[:customer],
192
+ :credit_card => {
193
+ :cardholder_name => creditcard.name,
194
+ :number => creditcard.number,
195
+ :cvv => creditcard.verification_value,
196
+ :expiration_month => creditcard.month.to_s.rjust(2, "0"),
197
+ :expiration_year => creditcard.year.to_s,
198
+ :token => options[:credit_card_token]
199
+ }
200
+ }
201
+ result = @braintree_gateway.customer.create(merge_credit_card_options(parameters, options))
202
+ Response.new(result.success?, message_from_result(result),
203
+ {
204
+ :braintree_customer => (customer_hash(result.customer, :include_credit_cards) if result.success?),
205
+ :customer_vault_id => (result.customer.id if result.success?),
206
+ :credit_card_token => (result.customer.credit_cards[0].token if result.success?)
207
+ },
208
+ :authorization => (result.customer.id if result.success?)
209
+ )
210
+ end
211
+ end
212
+
213
+ def add_credit_card_to_customer(credit_card, options)
214
+ commit do
215
+ parameters = {
216
+ customer_id: options[:customer],
217
+ token: options[:credit_card_token],
218
+ cardholder_name: credit_card.name,
219
+ number: credit_card.number,
220
+ cvv: credit_card.verification_value,
221
+ expiration_month: credit_card.month.to_s.rjust(2, "0"),
222
+ expiration_year: credit_card.year.to_s,
223
+ }
224
+ parameters[:billing_address] = map_address(options[:billing_address]) if options[:billing_address]
225
+
226
+ result = @braintree_gateway.credit_card.create(parameters)
227
+ ActiveMerchant::Billing::Response.new(
228
+ result.success?,
229
+ message_from_result(result),
230
+ {
231
+ customer_vault_id: (result.credit_card.customer_id if result.success?),
232
+ credit_card_token: (result.credit_card.token if result.success?)
233
+ },
234
+ authorization: (result.credit_card.customer_id if result.success?)
235
+ )
236
+ end
237
+ end
238
+
239
+ def scrub_email(email)
240
+ return nil unless email.present?
241
+ return nil if (
242
+ email !~ /^.+@[^\.]+(\.[^\.]+)+[a-z]$/i ||
243
+ email =~ /\.(con|met)$/i
244
+ )
245
+ email
246
+ end
247
+
248
+ def scrub_zip(zip)
249
+ return nil unless zip.present?
250
+ return nil if(
251
+ zip.gsub(/[^a-z0-9]/i, '').length > 9 ||
252
+ zip =~ /[^a-z0-9\- ]/i
253
+ )
254
+ zip
255
+ end
256
+
257
+ def merge_credit_card_options(parameters, options)
258
+ valid_options = {}
259
+ options.each do |key, value|
260
+ valid_options[key] = value if [:update_existing_token, :verify_card, :verification_merchant_account_id].include?(key)
261
+ end
262
+
263
+ if valid_options.include?(:verify_card) && @merchant_account_id
264
+ valid_options[:verification_merchant_account_id] ||= @merchant_account_id
265
+ end
266
+
267
+ parameters[:credit_card] ||= {}
268
+ parameters[:credit_card].merge!(:options => valid_options)
269
+ parameters[:credit_card][:billing_address] = map_address(options[:billing_address]) if options[:billing_address]
270
+ parameters
271
+ end
272
+
273
+ def map_address(address)
274
+ return {} if address.nil?
275
+ mapped = {
276
+ :street_address => address[:address1],
277
+ :extended_address => address[:address2],
278
+ :company => address[:company],
279
+ :locality => address[:city],
280
+ :region => address[:state],
281
+ :postal_code => scrub_zip(address[:zip]),
282
+ }
283
+ if(address[:country] || address[:country_code_alpha2])
284
+ mapped[:country_code_alpha2] = (address[:country] || address[:country_code_alpha2])
285
+ elsif address[:country_name]
286
+ mapped[:country_name] = address[:country_name]
287
+ elsif address[:country_code_alpha3]
288
+ mapped[:country_code_alpha3] = address[:country_code_alpha3]
289
+ elsif address[:country_code_numeric]
290
+ mapped[:country_code_numeric] = address[:country_code_numeric]
291
+ end
292
+ mapped
293
+ end
294
+
295
+ def commit(&block)
296
+ yield
297
+ rescue Braintree::BraintreeError => ex
298
+ Response.new(false, ex.class.to_s)
299
+ end
300
+
301
+ def message_from_result(result)
302
+ if result.success?
303
+ "OK"
304
+ elsif result.errors.size == 0 && result.credit_card_verification
305
+ "Processor declined: #{result.credit_card_verification.processor_response_text} (#{result.credit_card_verification.processor_response_code})"
306
+ else
307
+ result.errors.map { |e| "#{e.message} (#{e.code})" }.join(" ")
308
+ end
309
+ end
310
+
311
+ def response_from_result(result)
312
+ Response.new(result.success?, message_from_result(result),
313
+ { braintree_transaction: (transaction_hash(result.transaction) if result.success?) },
314
+ { authorization: (result.transaction.id if result.success?) }
315
+ )
316
+ end
317
+
318
+ def response_params(result)
319
+ params = {}
320
+ if result.success?
321
+ params[:braintree_transaction] = transaction_hash(result.transaction)
322
+ params[:customer_vault_id] = result.transaction.customer_details.id
323
+ end
324
+ params
325
+ end
326
+
327
+ def response_options(result)
328
+ options = {}
329
+ if result.success?
330
+ options[:authorization] = result.transaction.id
331
+ end
332
+ if result.transaction
333
+ options[:avs_result] = {
334
+ :code => nil, :message => nil,
335
+ :street_match => result.transaction.avs_street_address_response_code,
336
+ :postal_match => result.transaction.avs_postal_code_response_code
337
+ }
338
+ options[:cvv_result] = result.transaction.cvv_response_code
339
+ end
340
+ options
341
+ end
342
+
343
+ def message_from_transaction_result(result)
344
+ if result.transaction && result.transaction.status == "gateway_rejected"
345
+ "Transaction declined - gateway rejected"
346
+ elsif result.transaction
347
+ "#{result.transaction.processor_response_code} #{result.transaction.processor_response_text}"
348
+ else
349
+ message_from_result(result)
350
+ end
351
+ end
352
+
353
+ def create_transaction(transaction_type, money, credit_card_or_vault_id, options)
354
+ transaction_params = create_transaction_parameters(money, credit_card_or_vault_id, options)
355
+ commit do
356
+ result = @braintree_gateway.transaction.send(transaction_type, transaction_params)
357
+ response = Response.new(result.success?, message_from_transaction_result(result), response_params(result), response_options(result))
358
+ response.cvv_result['message'] = ''
359
+ response
360
+ end
361
+ end
362
+
363
+ def extract_refund_args(args)
364
+ options = args.extract_options!
365
+
366
+ # money, transaction_id, options
367
+ if args.length == 1 # legacy signature
368
+ return nil, args[0], options
369
+ elsif args.length == 2
370
+ return args[0], args[1], options
371
+ else
372
+ raise ArgumentError, "wrong number of arguments (#{args.length} for 2)"
373
+ end
374
+ end
375
+
376
+ def customer_hash(customer, include_credit_cards=false)
377
+ hash = {
378
+ "email" => customer.email,
379
+ "first_name" => customer.first_name,
380
+ "last_name" => customer.last_name,
381
+ "id" => customer.id
382
+ }
383
+
384
+ if include_credit_cards
385
+ hash["credit_cards"] = customer.credit_cards.map do |cc|
386
+ {
387
+ "bin" => cc.bin,
388
+ "expiration_date" => cc.expiration_date,
389
+ "token" => cc.token,
390
+ "last_4" => cc.last_4,
391
+ "card_type" => cc.card_type,
392
+ "masked_number" => cc.masked_number,
393
+ "token" => cc.token
394
+ }
395
+ end
396
+ end
397
+
398
+ hash
399
+ end
400
+
401
+ def transaction_hash(transaction)
402
+ if transaction.vault_customer
403
+ vault_customer = {
404
+ }
405
+ vault_customer["credit_cards"] = transaction.vault_customer.credit_cards.map do |cc|
406
+ {
407
+ "bin" => cc.bin
408
+ }
409
+ end
410
+ else
411
+ vault_customer = nil
412
+ end
413
+
414
+ customer_details = {
415
+ "id" => transaction.customer_details.id,
416
+ "email" => transaction.customer_details.email
417
+ }
418
+
419
+ billing_details = {
420
+ "street_address" => transaction.billing_details.street_address,
421
+ "extended_address" => transaction.billing_details.extended_address,
422
+ "company" => transaction.billing_details.company,
423
+ "locality" => transaction.billing_details.locality,
424
+ "region" => transaction.billing_details.region,
425
+ "postal_code" => transaction.billing_details.postal_code,
426
+ "country_name" => transaction.billing_details.country_name,
427
+ }
428
+
429
+ shipping_details = {
430
+ "street_address" => transaction.shipping_details.street_address,
431
+ "extended_address" => transaction.shipping_details.extended_address,
432
+ "company" => transaction.shipping_details.company,
433
+ "locality" => transaction.shipping_details.locality,
434
+ "region" => transaction.shipping_details.region,
435
+ "postal_code" => transaction.shipping_details.postal_code,
436
+ "country_name" => transaction.shipping_details.country_name,
437
+ }
438
+ credit_card_details = {
439
+ "masked_number" => transaction.credit_card_details.masked_number,
440
+ "bin" => transaction.credit_card_details.bin,
441
+ "last_4" => transaction.credit_card_details.last_4,
442
+ "card_type" => transaction.credit_card_details.card_type,
443
+ "token" => transaction.credit_card_details.token
444
+ }
445
+
446
+ {
447
+ "order_id" => transaction.order_id,
448
+ "status" => transaction.status,
449
+ "credit_card_details" => credit_card_details,
450
+ "customer_details" => customer_details,
451
+ "billing_details" => billing_details,
452
+ "shipping_details" => shipping_details,
453
+ "vault_customer" => vault_customer,
454
+ "merchant_account_id" => transaction.merchant_account_id
455
+ }
456
+ end
457
+
458
+ def create_transaction_parameters(money, credit_card_or_vault_id, options)
459
+ parameters = {
460
+ :amount => amount(money).to_s,
461
+ :order_id => options[:order_id],
462
+ :customer => {
463
+ :id => options[:store] == true ? "" : options[:store],
464
+ :email => scrub_email(options[:email])
465
+ },
466
+ :options => {
467
+ :store_in_vault => options[:store] ? true : false,
468
+ :submit_for_settlement => options[:submit_for_settlement]
469
+ }
470
+ }
471
+
472
+ parameters[:custom_fields] = options[:custom_fields]
473
+ parameters[:device_data] = options[:device_data] if options[:device_data]
474
+ if merchant_account_id = (options[:merchant_account_id] || @merchant_account_id)
475
+ parameters[:merchant_account_id] = merchant_account_id
476
+ end
477
+
478
+ if options[:recurring]
479
+ parameters[:recurring] = true
480
+ end
481
+
482
+ if credit_card_or_vault_id.is_a?(String) || credit_card_or_vault_id.is_a?(Integer)
483
+ if options[:payment_method_token]
484
+ parameters[:payment_method_token] = credit_card_or_vault_id
485
+ else
486
+ parameters[:customer_id] = credit_card_or_vault_id
487
+ end
488
+ else
489
+ parameters[:customer].merge!(
490
+ :first_name => credit_card_or_vault_id.first_name,
491
+ :last_name => credit_card_or_vault_id.last_name
492
+ )
493
+ parameters[:credit_card] = {
494
+ :number => credit_card_or_vault_id.number,
495
+ :cvv => credit_card_or_vault_id.verification_value,
496
+ :expiration_month => credit_card_or_vault_id.month.to_s.rjust(2, "0"),
497
+ :expiration_year => credit_card_or_vault_id.year.to_s
498
+ }
499
+ end
500
+ parameters[:billing] = map_address(options[:billing_address]) if options[:billing_address] && !options[:payment_method_token]
501
+ parameters[:shipping] = map_address(options[:shipping_address]) if options[:shipping_address]
502
+ parameters[:channel] = application_id if application_id.present? && application_id != "ActiveMerchant"
503
+
504
+ if options[:descriptor_name] || options[:descriptor_phone]
505
+ parameters[:descriptor] = {
506
+ name: options[:descriptor_name],
507
+ phone: options[:descriptor_phone]
508
+ }
509
+ end
510
+
511
+ parameters
512
+ end
513
+ end
514
+ end
515
+ end