tlconnor-activemerchant 1.20.4

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 (195) hide show
  1. data/CHANGELOG +805 -0
  2. data/CONTRIBUTORS +274 -0
  3. data/MIT-LICENSE +20 -0
  4. data/gem-public_cert.pem +20 -0
  5. data/lib/active_merchant.rb +63 -0
  6. data/lib/active_merchant/billing.rb +9 -0
  7. data/lib/active_merchant/billing/avs_result.rb +98 -0
  8. data/lib/active_merchant/billing/base.rb +57 -0
  9. data/lib/active_merchant/billing/check.rb +68 -0
  10. data/lib/active_merchant/billing/credit_card.rb +264 -0
  11. data/lib/active_merchant/billing/credit_card_formatting.rb +21 -0
  12. data/lib/active_merchant/billing/credit_card_methods.rb +129 -0
  13. data/lib/active_merchant/billing/cvv_result.rb +38 -0
  14. data/lib/active_merchant/billing/expiry_date.rb +34 -0
  15. data/lib/active_merchant/billing/gateway.rb +170 -0
  16. data/lib/active_merchant/billing/gateways.rb +18 -0
  17. data/lib/active_merchant/billing/gateways/authorize_net.rb +694 -0
  18. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +944 -0
  19. data/lib/active_merchant/billing/gateways/barclays_epdq.rb +308 -0
  20. data/lib/active_merchant/billing/gateways/beanstream.rb +167 -0
  21. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +388 -0
  22. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
  23. data/lib/active_merchant/billing/gateways/blue_pay.rb +11 -0
  24. data/lib/active_merchant/billing/gateways/bogus.rb +142 -0
  25. data/lib/active_merchant/billing/gateways/braintree.rb +17 -0
  26. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
  27. data/lib/active_merchant/billing/gateways/braintree_blue.rb +308 -0
  28. data/lib/active_merchant/billing/gateways/braintree_orange.rb +21 -0
  29. data/lib/active_merchant/billing/gateways/card_save.rb +23 -0
  30. data/lib/active_merchant/billing/gateways/card_stream.rb +230 -0
  31. data/lib/active_merchant/billing/gateways/certo_direct.rb +279 -0
  32. data/lib/active_merchant/billing/gateways/cyber_source.rb +430 -0
  33. data/lib/active_merchant/billing/gateways/data_cash.rb +597 -0
  34. data/lib/active_merchant/billing/gateways/efsnet.rb +235 -0
  35. data/lib/active_merchant/billing/gateways/elavon.rb +135 -0
  36. data/lib/active_merchant/billing/gateways/epay.rb +274 -0
  37. data/lib/active_merchant/billing/gateways/eway.rb +277 -0
  38. data/lib/active_merchant/billing/gateways/eway_managed.rb +265 -0
  39. data/lib/active_merchant/billing/gateways/exact.rb +227 -0
  40. data/lib/active_merchant/billing/gateways/federated_canada.rb +168 -0
  41. data/lib/active_merchant/billing/gateways/first_pay.rb +177 -0
  42. data/lib/active_merchant/billing/gateways/garanti.rb +262 -0
  43. data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +250 -0
  44. data/lib/active_merchant/billing/gateways/ideal/ideal_rabobank.pem +13 -0
  45. data/lib/active_merchant/billing/gateways/ideal/ideal_response.rb +29 -0
  46. data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +55 -0
  47. data/lib/active_merchant/billing/gateways/inspire.rb +221 -0
  48. data/lib/active_merchant/billing/gateways/instapay.rb +164 -0
  49. data/lib/active_merchant/billing/gateways/iridium.rb +258 -0
  50. data/lib/active_merchant/billing/gateways/jetpay.rb +276 -0
  51. data/lib/active_merchant/billing/gateways/linkpoint.rb +454 -0
  52. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +157 -0
  53. data/lib/active_merchant/billing/gateways/merchant_ware.rb +289 -0
  54. data/lib/active_merchant/billing/gateways/modern_payments.rb +36 -0
  55. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +220 -0
  56. data/lib/active_merchant/billing/gateways/moneris.rb +239 -0
  57. data/lib/active_merchant/billing/gateways/nab_transact.rb +244 -0
  58. data/lib/active_merchant/billing/gateways/net_registry.rb +189 -0
  59. data/lib/active_merchant/billing/gateways/netaxept.rb +239 -0
  60. data/lib/active_merchant/billing/gateways/netbilling.rb +168 -0
  61. data/lib/active_merchant/billing/gateways/nmi.rb +13 -0
  62. data/lib/active_merchant/billing/gateways/ogone.rb +330 -0
  63. data/lib/active_merchant/billing/gateways/optimal_payment.rb +277 -0
  64. data/lib/active_merchant/billing/gateways/orbital.rb +344 -0
  65. data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +46 -0
  66. data/lib/active_merchant/billing/gateways/pay_junction.rb +397 -0
  67. data/lib/active_merchant/billing/gateways/pay_secure.rb +120 -0
  68. data/lib/active_merchant/billing/gateways/paybox_direct.rb +207 -0
  69. data/lib/active_merchant/billing/gateways/payflow.rb +261 -0
  70. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +208 -0
  71. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
  72. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  73. data/lib/active_merchant/billing/gateways/payflow_express.rb +222 -0
  74. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
  75. data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
  76. data/lib/active_merchant/billing/gateways/payment_express.rb +235 -0
  77. data/lib/active_merchant/billing/gateways/paypal.rb +121 -0
  78. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +354 -0
  79. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +49 -0
  80. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  81. data/lib/active_merchant/billing/gateways/paypal_express.rb +229 -0
  82. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +25 -0
  83. data/lib/active_merchant/billing/gateways/paystation.rb +201 -0
  84. data/lib/active_merchant/billing/gateways/plugnpay.rb +298 -0
  85. data/lib/active_merchant/billing/gateways/psigate.rb +219 -0
  86. data/lib/active_merchant/billing/gateways/psl_card.rb +304 -0
  87. data/lib/active_merchant/billing/gateways/qbms.rb +297 -0
  88. data/lib/active_merchant/billing/gateways/quantum.rb +282 -0
  89. data/lib/active_merchant/billing/gateways/quickpay.rb +298 -0
  90. data/lib/active_merchant/billing/gateways/realex.rb +315 -0
  91. data/lib/active_merchant/billing/gateways/sage.rb +146 -0
  92. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +88 -0
  93. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +116 -0
  94. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +97 -0
  95. data/lib/active_merchant/billing/gateways/sage_pay.rb +320 -0
  96. data/lib/active_merchant/billing/gateways/sallie_mae.rb +144 -0
  97. data/lib/active_merchant/billing/gateways/samurai.rb +121 -0
  98. data/lib/active_merchant/billing/gateways/secure_net.rb +330 -0
  99. data/lib/active_merchant/billing/gateways/secure_pay.rb +31 -0
  100. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +280 -0
  101. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +113 -0
  102. data/lib/active_merchant/billing/gateways/skip_jack.rb +458 -0
  103. data/lib/active_merchant/billing/gateways/smart_ps.rb +271 -0
  104. data/lib/active_merchant/billing/gateways/stripe.rb +244 -0
  105. data/lib/active_merchant/billing/gateways/trans_first.rb +127 -0
  106. data/lib/active_merchant/billing/gateways/transax.rb +25 -0
  107. data/lib/active_merchant/billing/gateways/trust_commerce.rb +423 -0
  108. data/lib/active_merchant/billing/gateways/usa_epay.rb +23 -0
  109. data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +1496 -0
  110. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +206 -0
  111. data/lib/active_merchant/billing/gateways/verifi.rb +233 -0
  112. data/lib/active_merchant/billing/gateways/viaklix.rb +189 -0
  113. data/lib/active_merchant/billing/gateways/wirecard.rb +318 -0
  114. data/lib/active_merchant/billing/gateways/worldpay.rb +280 -0
  115. data/lib/active_merchant/billing/integrations.rb +17 -0
  116. data/lib/active_merchant/billing/integrations/action_view_helper.rb +72 -0
  117. data/lib/active_merchant/billing/integrations/authorize_net_sim.rb +38 -0
  118. data/lib/active_merchant/billing/integrations/authorize_net_sim/helper.rb +228 -0
  119. data/lib/active_merchant/billing/integrations/authorize_net_sim/notification.rb +340 -0
  120. data/lib/active_merchant/billing/integrations/bogus.rb +23 -0
  121. data/lib/active_merchant/billing/integrations/bogus/helper.rb +17 -0
  122. data/lib/active_merchant/billing/integrations/bogus/notification.rb +11 -0
  123. data/lib/active_merchant/billing/integrations/bogus/return.rb +10 -0
  124. data/lib/active_merchant/billing/integrations/chronopay.rb +23 -0
  125. data/lib/active_merchant/billing/integrations/chronopay/helper.rb +120 -0
  126. data/lib/active_merchant/billing/integrations/chronopay/notification.rb +158 -0
  127. data/lib/active_merchant/billing/integrations/chronopay/return.rb +10 -0
  128. data/lib/active_merchant/billing/integrations/direc_pay.rb +41 -0
  129. data/lib/active_merchant/billing/integrations/direc_pay/helper.rb +200 -0
  130. data/lib/active_merchant/billing/integrations/direc_pay/notification.rb +76 -0
  131. data/lib/active_merchant/billing/integrations/direc_pay/return.rb +32 -0
  132. data/lib/active_merchant/billing/integrations/direc_pay/status.rb +37 -0
  133. data/lib/active_merchant/billing/integrations/directebanking.rb +47 -0
  134. data/lib/active_merchant/billing/integrations/directebanking/helper.rb +90 -0
  135. data/lib/active_merchant/billing/integrations/directebanking/notification.rb +120 -0
  136. data/lib/active_merchant/billing/integrations/directebanking/return.rb +11 -0
  137. data/lib/active_merchant/billing/integrations/dwolla.rb +30 -0
  138. data/lib/active_merchant/billing/integrations/dwolla/helper.rb +31 -0
  139. data/lib/active_merchant/billing/integrations/dwolla/notification.rb +55 -0
  140. data/lib/active_merchant/billing/integrations/dwolla/return.rb +38 -0
  141. data/lib/active_merchant/billing/integrations/e_payment_plans.rb +48 -0
  142. data/lib/active_merchant/billing/integrations/e_payment_plans/helper.rb +34 -0
  143. data/lib/active_merchant/billing/integrations/e_payment_plans/notification.rb +84 -0
  144. data/lib/active_merchant/billing/integrations/gestpay.rb +25 -0
  145. data/lib/active_merchant/billing/integrations/gestpay/common.rb +42 -0
  146. data/lib/active_merchant/billing/integrations/gestpay/helper.rb +70 -0
  147. data/lib/active_merchant/billing/integrations/gestpay/notification.rb +85 -0
  148. data/lib/active_merchant/billing/integrations/gestpay/return.rb +10 -0
  149. data/lib/active_merchant/billing/integrations/helper.rb +113 -0
  150. data/lib/active_merchant/billing/integrations/hi_trust.rb +27 -0
  151. data/lib/active_merchant/billing/integrations/hi_trust/helper.rb +58 -0
  152. data/lib/active_merchant/billing/integrations/hi_trust/notification.rb +59 -0
  153. data/lib/active_merchant/billing/integrations/hi_trust/return.rb +67 -0
  154. data/lib/active_merchant/billing/integrations/moneybookers.rb +26 -0
  155. data/lib/active_merchant/billing/integrations/moneybookers/helper.rb +59 -0
  156. data/lib/active_merchant/billing/integrations/moneybookers/notification.rb +129 -0
  157. data/lib/active_merchant/billing/integrations/nochex.rb +88 -0
  158. data/lib/active_merchant/billing/integrations/nochex/helper.rb +68 -0
  159. data/lib/active_merchant/billing/integrations/nochex/notification.rb +94 -0
  160. data/lib/active_merchant/billing/integrations/nochex/return.rb +10 -0
  161. data/lib/active_merchant/billing/integrations/notification.rb +62 -0
  162. data/lib/active_merchant/billing/integrations/payflow_link.rb +21 -0
  163. data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +100 -0
  164. data/lib/active_merchant/billing/integrations/payflow_link/notification.rb +78 -0
  165. data/lib/active_merchant/billing/integrations/paypal.rb +39 -0
  166. data/lib/active_merchant/billing/integrations/paypal/helper.rb +119 -0
  167. data/lib/active_merchant/billing/integrations/paypal/notification.rb +154 -0
  168. data/lib/active_merchant/billing/integrations/paypal/return.rb +10 -0
  169. data/lib/active_merchant/billing/integrations/quickpay.rb +21 -0
  170. data/lib/active_merchant/billing/integrations/quickpay/helper.rb +72 -0
  171. data/lib/active_merchant/billing/integrations/quickpay/notification.rb +74 -0
  172. data/lib/active_merchant/billing/integrations/return.rb +42 -0
  173. data/lib/active_merchant/billing/integrations/sage_pay_form.rb +37 -0
  174. data/lib/active_merchant/billing/integrations/sage_pay_form/encryption.rb +33 -0
  175. data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +127 -0
  176. data/lib/active_merchant/billing/integrations/sage_pay_form/notification.rb +210 -0
  177. data/lib/active_merchant/billing/integrations/sage_pay_form/return.rb +31 -0
  178. data/lib/active_merchant/billing/integrations/two_checkout.rb +22 -0
  179. data/lib/active_merchant/billing/integrations/two_checkout/helper.rb +59 -0
  180. data/lib/active_merchant/billing/integrations/two_checkout/notification.rb +114 -0
  181. data/lib/active_merchant/billing/integrations/two_checkout/return.rb +17 -0
  182. data/lib/active_merchant/billing/integrations/valitor.rb +33 -0
  183. data/lib/active_merchant/billing/integrations/valitor/helper.rb +86 -0
  184. data/lib/active_merchant/billing/integrations/valitor/notification.rb +13 -0
  185. data/lib/active_merchant/billing/integrations/valitor/response_fields.rb +97 -0
  186. data/lib/active_merchant/billing/integrations/valitor/return.rb +13 -0
  187. data/lib/active_merchant/billing/integrations/world_pay.rb +27 -0
  188. data/lib/active_merchant/billing/integrations/world_pay/helper.rb +100 -0
  189. data/lib/active_merchant/billing/integrations/world_pay/notification.rb +160 -0
  190. data/lib/active_merchant/billing/response.rb +32 -0
  191. data/lib/active_merchant/version.rb +3 -0
  192. data/lib/activemerchant.rb +1 -0
  193. data/lib/support/gateway_support.rb +58 -0
  194. data/lib/support/outbound_hosts.rb +25 -0
  195. metadata +411 -0
@@ -0,0 +1,168 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class NetbillingGateway < Gateway
4
+ URL = 'https://secure.netbilling.com:1402/gw/sas/direct3.1'
5
+
6
+ TRANSACTIONS = {
7
+ :authorization => 'A',
8
+ :purchase => 'S',
9
+ :referenced_credit => 'R',
10
+ :unreferenced_credit => 'C',
11
+ :capture => 'D'
12
+ }
13
+
14
+ SUCCESS_CODES = [ '1', 'T' ]
15
+ SUCCESS_MESSAGE = 'The transaction was approved'
16
+ FAILURE_MESSAGE = 'The transaction failed'
17
+ TEST_LOGIN = '104901072025'
18
+
19
+ self.display_name = 'NETbilling'
20
+ self.homepage_url = 'http://www.netbilling.com'
21
+ self.supported_countries = ['US']
22
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club]
23
+
24
+ def initialize(options = {})
25
+ requires!(options, :login)
26
+ @options = options
27
+ super
28
+ end
29
+
30
+ def authorize(money, credit_card, options = {})
31
+ post = {}
32
+ add_amount(post, money)
33
+ add_invoice(post, options)
34
+ add_credit_card(post, credit_card)
35
+ add_address(post, credit_card, options)
36
+ add_customer_data(post, options)
37
+
38
+ commit(:authorization, money, post)
39
+ end
40
+
41
+ def purchase(money, credit_card, options = {})
42
+ post = {}
43
+ add_amount(post, money)
44
+ add_invoice(post, options)
45
+ add_credit_card(post, credit_card)
46
+ add_address(post, credit_card, options)
47
+ add_customer_data(post, options)
48
+
49
+ commit(:purchase, money, post)
50
+ end
51
+
52
+ def capture(money, authorization, options = {})
53
+ post = {}
54
+ add_reference(post, authorization)
55
+ commit(:capture, money, post)
56
+ end
57
+
58
+ def test?
59
+ @options[:login] == TEST_LOGIN || super
60
+ end
61
+
62
+ private
63
+ def add_amount(post, money)
64
+ post[:amount] = amount(money)
65
+ end
66
+
67
+ def add_reference(post, reference)
68
+ post[:orig_id] = reference
69
+ end
70
+
71
+ def add_customer_data(post, options)
72
+ post[:cust_email] = options[:email]
73
+ post[:cust_ip] = options[:ip]
74
+ end
75
+
76
+ def add_address(post, credit_card, options)
77
+ if billing_address = options[:billing_address] || options[:address]
78
+ post[:bill_street] = billing_address[:address1]
79
+ post[:cust_phone] = billing_address[:phone]
80
+ post[:bill_zip] = billing_address[:zip]
81
+ post[:bill_city] = billing_address[:city]
82
+ post[:bill_country] = billing_address[:country]
83
+ post[:bill_state] = billing_address[:state]
84
+ end
85
+
86
+ if shipping_address = options[:shipping_address]
87
+ first_name, last_name = parse_first_and_last_name(shipping_address[:name])
88
+
89
+ post[:ship_name1] = first_name
90
+ post[:ship_name2] = last_name
91
+ post[:ship_street] = shipping_address[:address1]
92
+ post[:ship_zip] = shipping_address[:zip]
93
+ post[:ship_city] = shipping_address[:city]
94
+ post[:ship_country] = shipping_address[:country]
95
+ post[:ship_state] = shipping_address[:state]
96
+ end
97
+ end
98
+
99
+ def add_invoice(post, options)
100
+ post[:description] = options[:description]
101
+ end
102
+
103
+ def add_credit_card(post, credit_card)
104
+ post[:bill_name1] = credit_card.first_name
105
+ post[:bill_name2] = credit_card.last_name
106
+ post[:card_number] = credit_card.number
107
+ post[:card_expire] = expdate(credit_card)
108
+ post[:card_cvv2] = credit_card.verification_value
109
+ end
110
+
111
+ def parse(body)
112
+ results = {}
113
+ body.split(/&/).each do |pair|
114
+ key,val = pair.split(/=/)
115
+ results[key.to_sym] = CGI.unescape(val)
116
+ end
117
+ results
118
+ end
119
+
120
+ def commit(action, money, parameters)
121
+ response = parse(ssl_post(URL, post_data(action, parameters)))
122
+
123
+ Response.new(success?(response), message_from(response), response,
124
+ :test => test_response?(response),
125
+ :authorization => response[:trans_id],
126
+ :avs_result => { :code => response[:avs_code]},
127
+ :cvv_result => response[:cvv2_code]
128
+ )
129
+ end
130
+
131
+ def test_response?(response)
132
+ !!(test? || response[:auth_msg] =~ /TEST/)
133
+ end
134
+
135
+ def success?(response)
136
+ SUCCESS_CODES.include?(response[:status_code])
137
+ end
138
+
139
+ def message_from(response)
140
+ success?(response) ? SUCCESS_MESSAGE : (response[:auth_msg] || FAILURE_MESSAGE)
141
+ end
142
+
143
+ def expdate(credit_card)
144
+ year = sprintf("%.4i", credit_card.year)
145
+ month = sprintf("%.2i", credit_card.month)
146
+
147
+ "#{month}#{year[-2..-1]}"
148
+ end
149
+
150
+ def post_data(action, parameters = {})
151
+ parameters[:account_id] = @options[:login]
152
+ parameters[:pay_type] = 'C'
153
+ parameters[:tran_type] = TRANSACTIONS[action]
154
+
155
+ parameters.reject{|k,v| v.blank?}.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
156
+ end
157
+
158
+ def parse_first_and_last_name(value)
159
+ name = value.to_s.split(' ')
160
+
161
+ last_name = name.pop || ''
162
+ first_name = name.join(' ')
163
+ [ first_name, last_name ]
164
+ end
165
+ end
166
+ end
167
+ end
168
+
@@ -0,0 +1,13 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class NmiGateway < AuthorizeNetGateway
4
+ self.test_url = 'https://secure.networkmerchants.com/gateway/transact.dll'
5
+ self.live_url = 'https://secure.networkmerchants.com/gateway/transact.dll'
6
+ self.homepage_url = 'http://nmi.com/'
7
+ self.display_name = 'NMI'
8
+ self.supported_countries = ['US']
9
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover]
10
+ end
11
+ end
12
+ end
13
+
@@ -0,0 +1,330 @@
1
+ # coding: utf-8
2
+ require 'rexml/document'
3
+
4
+ module ActiveMerchant #:nodoc:
5
+ module Billing #:nodoc:
6
+ # = Ogone DirectLink Gateway
7
+ #
8
+ # DirectLink is the API version of the Ogone Payment Platform. It allows server to server
9
+ # communication between Ogone systems and your e-commerce website.
10
+ #
11
+ # This implementation follows the specification provided in the DirectLink integration
12
+ # guide version 4.2.0 (26 October 2011), available here:
13
+ # https://secure.ogone.com/ncol/Ogone_DirectLink_EN.pdf
14
+ #
15
+ # It also features aliases, which allow to store/unstore credit cards, as specified in
16
+ # the Alias Manager Option guide version 3.2.0 (26 October 2011) available here:
17
+ # https://secure.ogone.com/ncol/Ogone_Alias_EN.pdf
18
+ #
19
+ # It was last tested on Release 4.89 of Ogone DirectLink + AliasManager (26 October 2011).
20
+ #
21
+ # For any questions or comments, please contact one of the following:
22
+ # - Nicolas Jacobeus (nj@belighted.com),
23
+ # - Sébastien Grosjean (public@zencocoon.com),
24
+ # - Rémy Coutable (remy@jilion.com).
25
+ #
26
+ # == Usage
27
+ #
28
+ # gateway = ActiveMerchant::Billing::OgoneGateway.new(
29
+ # :login => "my_ogone_psp_id",
30
+ # :user => "my_ogone_user_id",
31
+ # :password => "my_ogone_pswd",
32
+ # :signature => "my_ogone_sha_signature", # Only if you configured your Ogone environment so.
33
+ # :signature_encryptor => "sha512", # Can be "sha1" (default), "sha256" or "sha512".
34
+ # # Must be the same as the one configured in your Ogone account.
35
+ # )
36
+ #
37
+ # # set up credit card object as in main ActiveMerchant example
38
+ # creditcard = ActiveMerchant::Billing::CreditCard.new(
39
+ # :type => 'visa',
40
+ # :number => '4242424242424242',
41
+ # :month => 8,
42
+ # :year => 2009,
43
+ # :first_name => 'Bob',
44
+ # :last_name => 'Bobsen'
45
+ # )
46
+ #
47
+ # # run request
48
+ # response = gateway.purchase(1000, creditcard, :order_id => "1") # charge 10 EUR
49
+ #
50
+ # If you don't provide an :order_id, the gateway will generate a random one for you.
51
+ #
52
+ # puts response.success? # Check whether the transaction was successful
53
+ # puts response.message # Retrieve the message returned by Ogone
54
+ # puts response.authorization # Retrieve the unique transaction ID returned by Ogone
55
+ #
56
+ # == Alias feature
57
+ #
58
+ # To use the alias feature, simply add :store in the options hash:
59
+ #
60
+ # # Associate the alias to that credit card
61
+ # gateway.purchase(1000, creditcard, :order_id => "1", :store => "myawesomecustomer")
62
+ #
63
+ # # You can use the alias instead of the credit card for subsequent orders
64
+ # gateway.purchase(2000, "myawesomecustomer", :order_id => "2")
65
+ #
66
+ class OgoneGateway < Gateway
67
+
68
+ URLS = {
69
+ :order => 'https://secure.ogone.com/ncol/%s/orderdirect.asp',
70
+ :maintenance => 'https://secure.ogone.com/ncol/%s/maintenancedirect.asp'
71
+ }
72
+
73
+ CVV_MAPPING = { 'OK' => 'M',
74
+ 'KO' => 'N',
75
+ 'NO' => 'P' }
76
+
77
+ AVS_MAPPING = { 'OK' => 'M',
78
+ 'KO' => 'N',
79
+ 'NO' => 'R' }
80
+
81
+ SUCCESS_MESSAGE = "The transaction was successful"
82
+
83
+ OGONE_NO_SIGNATURE_DEPRECATION_MESSAGE = "Signature usage will be required from a future release of ActiveMerchant's Ogone Gateway. Please update your Ogone account to use it."
84
+ OGONE_LOW_ENCRYPTION_DEPRECATION_MESSAGE = "SHA512 signature encryptor will be required from a future release of ActiveMerchant's Ogone Gateway. Please update your Ogone account to use it."
85
+
86
+ self.supported_countries = ['BE', 'DE', 'FR', 'NL', 'AT', 'CH']
87
+ # also supports Airplus and UATP
88
+ self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :discover, :jcb, :maestro]
89
+ self.homepage_url = 'http://www.ogone.com/'
90
+ self.display_name = 'Ogone'
91
+ self.default_currency = 'EUR'
92
+ self.money_format = :cents
93
+
94
+ def initialize(options = {})
95
+ requires!(options, :login, :user, :password)
96
+ @options = options
97
+ super
98
+ end
99
+
100
+ # Verify and reserve the specified amount on the account, without actually doing the transaction.
101
+ def authorize(money, payment_source, options = {})
102
+ post = {}
103
+ add_invoice(post, options)
104
+ add_payment_source(post, payment_source, options)
105
+ add_address(post, payment_source, options)
106
+ add_customer_data(post, options)
107
+ add_money(post, money, options)
108
+ commit('RES', post)
109
+ end
110
+
111
+ # Verify and transfer the specified amount.
112
+ def purchase(money, payment_source, options = {})
113
+ post = {}
114
+ add_invoice(post, options)
115
+ add_payment_source(post, payment_source, options)
116
+ add_address(post, payment_source, options)
117
+ add_customer_data(post, options)
118
+ add_money(post, money, options)
119
+ commit('SAL', post)
120
+ end
121
+
122
+ # Complete a previously authorized transaction.
123
+ def capture(money, authorization, options = {})
124
+ post = {}
125
+ add_authorization(post, reference_from(authorization))
126
+ add_invoice(post, options)
127
+ add_customer_data(post, options)
128
+ add_money(post, money, options)
129
+ commit('SAL', post)
130
+ end
131
+
132
+ # Cancels a previously authorized transaction.
133
+ def void(identification, options = {})
134
+ post = {}
135
+ add_authorization(post, reference_from(identification))
136
+ commit('DES', post)
137
+ end
138
+
139
+ # Credit the specified account by a specific amount.
140
+ def credit(money, identification_or_credit_card, options = {})
141
+ if reference_transaction?(identification_or_credit_card)
142
+ deprecated CREDIT_DEPRECATION_MESSAGE
143
+ # Referenced credit: refund of a settled transaction
144
+ refund(money, identification_or_credit_card, options)
145
+ else # must be a credit card or card reference
146
+ perform_non_referenced_credit(money, identification_or_credit_card, options)
147
+ end
148
+ end
149
+
150
+ # Refund of a settled transaction
151
+ def refund(money, reference, options = {})
152
+ perform_reference_credit(money, reference, options)
153
+ end
154
+
155
+ def test?
156
+ @options[:test] || super
157
+ end
158
+
159
+ private
160
+
161
+ def reference_from(authorization)
162
+ authorization.split(";").first
163
+ end
164
+
165
+ def reference_transaction?(identifier)
166
+ return false unless identifier.is_a?(String)
167
+ reference, action = identifier.split(";")
168
+ !action.nil?
169
+ end
170
+
171
+ def perform_reference_credit(money, payment_target, options = {})
172
+ post = {}
173
+ add_authorization(post, reference_from(payment_target))
174
+ add_money(post, money, options)
175
+ commit('RFD', post)
176
+ end
177
+
178
+ def perform_non_referenced_credit(money, payment_target, options = {})
179
+ # Non-referenced credit: acts like a reverse purchase
180
+ post = {}
181
+ add_invoice(post, options)
182
+ add_payment_source(post, payment_target, options)
183
+ add_address(post, payment_target, options)
184
+ add_customer_data(post, options)
185
+ add_money(post, money, options)
186
+ commit('RFD', post)
187
+ end
188
+
189
+ def add_payment_source(post, payment_source, options)
190
+ if payment_source.is_a?(String)
191
+ add_alias(post, payment_source)
192
+ add_eci(post, options[:eci] || '9')
193
+ else
194
+ add_alias(post, options[:store])
195
+ add_eci(post, options[:eci] || '7')
196
+ add_creditcard(post, payment_source)
197
+ end
198
+ end
199
+
200
+ def add_eci(post, eci)
201
+ add_pair post, 'ECI', eci.to_s
202
+ end
203
+
204
+ def add_alias(post, _alias)
205
+ add_pair post, 'ALIAS', _alias
206
+ end
207
+
208
+ def add_authorization(post, authorization)
209
+ add_pair post, 'PAYID', authorization
210
+ end
211
+
212
+ def add_money(post, money, options)
213
+ add_pair post, 'currency', options[:currency] || @options[:currency] || currency(money)
214
+ add_pair post, 'amount', amount(money)
215
+ end
216
+
217
+ def add_customer_data(post, options)
218
+ add_pair post, 'EMAIL', options[:email]
219
+ add_pair post, 'REMOTE_ADDR', options[:ip]
220
+ end
221
+
222
+ def add_address(post, creditcard, options)
223
+ return unless options[:billing_address]
224
+ add_pair post, 'Owneraddress', options[:billing_address][:address1]
225
+ add_pair post, 'OwnerZip', options[:billing_address][:zip]
226
+ add_pair post, 'ownertown', options[:billing_address][:city]
227
+ add_pair post, 'ownercty', options[:billing_address][:country]
228
+ add_pair post, 'ownertelno', options[:billing_address][:phone]
229
+ end
230
+
231
+ def add_invoice(post, options)
232
+ add_pair post, 'orderID', options[:order_id] || generate_unique_id[0...30]
233
+ add_pair post, 'COM', options[:description]
234
+ end
235
+
236
+ def add_creditcard(post, creditcard)
237
+ add_pair post, 'CN', creditcard.name
238
+ add_pair post, 'CARDNO', creditcard.number
239
+ add_pair post, 'ED', "%02d%02s" % [creditcard.month, creditcard.year.to_s[-2..-1]]
240
+ add_pair post, 'CVC', creditcard.verification_value
241
+ end
242
+
243
+ def parse(body)
244
+ xml_root = REXML::Document.new(body).root
245
+ convert_attributes_to_hash(xml_root.attributes)
246
+ end
247
+
248
+ def commit(action, parameters)
249
+ add_pair parameters, 'PSPID', @options[:login]
250
+ add_pair parameters, 'USERID', @options[:user]
251
+ add_pair parameters, 'PSWD', @options[:password]
252
+
253
+ url = URLS[parameters['PAYID'] ? :maintenance : :order] % [test? ? "test" : "prod"]
254
+ response = parse(ssl_post(url, post_data(action, parameters)))
255
+
256
+ options = {
257
+ :authorization => [response["PAYID"], action].join(";"),
258
+ :test => test?,
259
+ :avs_result => { :code => AVS_MAPPING[response["AAVCheck"]] },
260
+ :cvv_result => CVV_MAPPING[response["CVCCheck"]]
261
+ }
262
+ Response.new(successful?(response), message_from(response), response, options)
263
+ end
264
+
265
+ def successful?(response)
266
+ response["NCERROR"] == "0"
267
+ end
268
+
269
+ def message_from(response)
270
+ if successful?(response)
271
+ SUCCESS_MESSAGE
272
+ else
273
+ format_error_message(response["NCERRORPLUS"])
274
+ end
275
+ end
276
+
277
+ def format_error_message(message)
278
+ raw_message = message.to_s.strip
279
+ case raw_message
280
+ when /\|/
281
+ raw_message.split("|").join(", ").capitalize
282
+ when /\//
283
+ raw_message.split("/").first.to_s.capitalize
284
+ else
285
+ raw_message.to_s.capitalize
286
+ end
287
+ end
288
+
289
+ def post_data(action, parameters = {})
290
+ add_pair parameters, 'Operation', action
291
+ @options[:signature] ? add_signature(parameters) : deprecated(OGONE_NO_SIGNATURE_DEPRECATION_MESSAGE)
292
+ parameters.to_query
293
+ end
294
+
295
+ def add_signature(parameters)
296
+ deprecated(OGONE_LOW_ENCRYPTION_DEPRECATION_MESSAGE) unless @options[:signature_encryptor] == 'sha512'
297
+
298
+ sha_encryptor = case @options[:signature_encryptor]
299
+ when 'sha256'
300
+ Digest::SHA256
301
+ when 'sha512'
302
+ Digest::SHA512
303
+ else
304
+ Digest::SHA1
305
+ end
306
+
307
+ string_to_digest = if @options[:signature_encryptor]
308
+ parameters.sort { |a, b| a[0].upcase <=> b[0].upcase }.map { |k, v| "#{k.upcase}=#{v}" }.join(@options[:signature])
309
+ else
310
+ %w[orderID amount currency CARDNO PSPID Operation ALIAS].map { |key| parameters[key] }.join
311
+ end
312
+ string_to_digest << @options[:signature]
313
+
314
+ add_pair parameters, 'SHASign', sha_encryptor.hexdigest(string_to_digest).upcase
315
+ end
316
+
317
+ def add_pair(post, key, value)
318
+ post[key] = value if !value.blank?
319
+ end
320
+
321
+ def convert_attributes_to_hash(rexml_attributes)
322
+ response_hash = {}
323
+ rexml_attributes.each do |key, value|
324
+ response_hash[key] = value
325
+ end
326
+ response_hash
327
+ end
328
+ end
329
+ end
330
+ end