n8_activemerchant 1.9.3

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 (158) hide show
  1. data/CHANGELOG +574 -0
  2. data/CONTRIBUTORS +175 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +151 -0
  5. data/gem-public_cert.pem +20 -0
  6. data/lib/active_merchant.rb +49 -0
  7. data/lib/active_merchant/billing.rb +9 -0
  8. data/lib/active_merchant/billing/avs_result.rb +98 -0
  9. data/lib/active_merchant/billing/base.rb +57 -0
  10. data/lib/active_merchant/billing/check.rb +68 -0
  11. data/lib/active_merchant/billing/credit_card.rb +161 -0
  12. data/lib/active_merchant/billing/credit_card_formatting.rb +21 -0
  13. data/lib/active_merchant/billing/credit_card_methods.rb +125 -0
  14. data/lib/active_merchant/billing/cvv_result.rb +38 -0
  15. data/lib/active_merchant/billing/expiry_date.rb +34 -0
  16. data/lib/active_merchant/billing/gateway.rb +169 -0
  17. data/lib/active_merchant/billing/gateways.rb +18 -0
  18. data/lib/active_merchant/billing/gateways/authorize_net.rb +654 -0
  19. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +736 -0
  20. data/lib/active_merchant/billing/gateways/beanstream.rb +102 -0
  21. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +244 -0
  22. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
  23. data/lib/active_merchant/billing/gateways/bogus.rb +102 -0
  24. data/lib/active_merchant/billing/gateways/braintree.rb +17 -0
  25. data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
  26. data/lib/active_merchant/billing/gateways/braintree_blue.rb +210 -0
  27. data/lib/active_merchant/billing/gateways/braintree_orange.rb +17 -0
  28. data/lib/active_merchant/billing/gateways/card_stream.rb +230 -0
  29. data/lib/active_merchant/billing/gateways/cyber_source.rb +406 -0
  30. data/lib/active_merchant/billing/gateways/data_cash.rb +593 -0
  31. data/lib/active_merchant/billing/gateways/efsnet.rb +229 -0
  32. data/lib/active_merchant/billing/gateways/elavon.rb +134 -0
  33. data/lib/active_merchant/billing/gateways/epay.rb +263 -0
  34. data/lib/active_merchant/billing/gateways/eway.rb +277 -0
  35. data/lib/active_merchant/billing/gateways/exact.rb +222 -0
  36. data/lib/active_merchant/billing/gateways/first_pay.rb +172 -0
  37. data/lib/active_merchant/billing/gateways/garanti.rb +222 -0
  38. data/lib/active_merchant/billing/gateways/inspire.rb +221 -0
  39. data/lib/active_merchant/billing/gateways/instapay.rb +164 -0
  40. data/lib/active_merchant/billing/gateways/iridium.rb +253 -0
  41. data/lib/active_merchant/billing/gateways/jetpay.rb +270 -0
  42. data/lib/active_merchant/billing/gateways/linkpoint.rb +449 -0
  43. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +154 -0
  44. data/lib/active_merchant/billing/gateways/merchant_ware.rb +283 -0
  45. data/lib/active_merchant/billing/gateways/modern_payments.rb +36 -0
  46. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +220 -0
  47. data/lib/active_merchant/billing/gateways/moneris.rb +205 -0
  48. data/lib/active_merchant/billing/gateways/net_registry.rb +189 -0
  49. data/lib/active_merchant/billing/gateways/netaxept.rb +234 -0
  50. data/lib/active_merchant/billing/gateways/netbilling.rb +168 -0
  51. data/lib/active_merchant/billing/gateways/ogone.rb +279 -0
  52. data/lib/active_merchant/billing/gateways/pay_junction.rb +392 -0
  53. data/lib/active_merchant/billing/gateways/pay_secure.rb +120 -0
  54. data/lib/active_merchant/billing/gateways/paybox_direct.rb +203 -0
  55. data/lib/active_merchant/billing/gateways/payflow.rb +236 -0
  56. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +207 -0
  57. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
  58. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  59. data/lib/active_merchant/billing/gateways/payflow_express.rb +138 -0
  60. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
  61. data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
  62. data/lib/active_merchant/billing/gateways/payment_express.rb +230 -0
  63. data/lib/active_merchant/billing/gateways/paypal.rb +121 -0
  64. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +326 -0
  65. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +38 -0
  66. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  67. data/lib/active_merchant/billing/gateways/paypal_express.rb +145 -0
  68. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +20 -0
  69. data/lib/active_merchant/billing/gateways/paysimple/paysimple.rb +333 -0
  70. data/lib/active_merchant/billing/gateways/paysimple/usaepay.wsdl +1596 -0
  71. data/lib/active_merchant/billing/gateways/plugnpay.rb +292 -0
  72. data/lib/active_merchant/billing/gateways/psigate.rb +214 -0
  73. data/lib/active_merchant/billing/gateways/psl_card.rb +304 -0
  74. data/lib/active_merchant/billing/gateways/quickpay.rb +213 -0
  75. data/lib/active_merchant/billing/gateways/realex.rb +200 -0
  76. data/lib/active_merchant/billing/gateways/sage.rb +146 -0
  77. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +88 -0
  78. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +116 -0
  79. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +97 -0
  80. data/lib/active_merchant/billing/gateways/sage_pay.rb +315 -0
  81. data/lib/active_merchant/billing/gateways/sallie_mae.rb +144 -0
  82. data/lib/active_merchant/billing/gateways/secure_net.rb +330 -0
  83. data/lib/active_merchant/billing/gateways/secure_pay.rb +31 -0
  84. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +157 -0
  85. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +113 -0
  86. data/lib/active_merchant/billing/gateways/skip_jack.rb +453 -0
  87. data/lib/active_merchant/billing/gateways/smart_ps.rb +265 -0
  88. data/lib/active_merchant/billing/gateways/trans_first.rb +127 -0
  89. data/lib/active_merchant/billing/gateways/transax.rb +25 -0
  90. data/lib/active_merchant/billing/gateways/trust_commerce.rb +418 -0
  91. data/lib/active_merchant/billing/gateways/usa_epay.rb +194 -0
  92. data/lib/active_merchant/billing/gateways/usa_epay_soap.rb +154 -0
  93. data/lib/active_merchant/billing/gateways/verifi.rb +228 -0
  94. data/lib/active_merchant/billing/gateways/viaklix.rb +189 -0
  95. data/lib/active_merchant/billing/gateways/wirecard.rb +318 -0
  96. data/lib/active_merchant/billing/integrations.rb +17 -0
  97. data/lib/active_merchant/billing/integrations/action_view_helper.rb +68 -0
  98. data/lib/active_merchant/billing/integrations/bogus.rb +23 -0
  99. data/lib/active_merchant/billing/integrations/bogus/helper.rb +17 -0
  100. data/lib/active_merchant/billing/integrations/bogus/notification.rb +11 -0
  101. data/lib/active_merchant/billing/integrations/bogus/return.rb +10 -0
  102. data/lib/active_merchant/billing/integrations/chronopay.rb +23 -0
  103. data/lib/active_merchant/billing/integrations/chronopay/helper.rb +120 -0
  104. data/lib/active_merchant/billing/integrations/chronopay/notification.rb +158 -0
  105. data/lib/active_merchant/billing/integrations/chronopay/return.rb +10 -0
  106. data/lib/active_merchant/billing/integrations/direc_pay.rb +41 -0
  107. data/lib/active_merchant/billing/integrations/direc_pay/helper.rb +188 -0
  108. data/lib/active_merchant/billing/integrations/direc_pay/notification.rb +76 -0
  109. data/lib/active_merchant/billing/integrations/direc_pay/return.rb +32 -0
  110. data/lib/active_merchant/billing/integrations/direc_pay/status.rb +37 -0
  111. data/lib/active_merchant/billing/integrations/gestpay.rb +25 -0
  112. data/lib/active_merchant/billing/integrations/gestpay/common.rb +42 -0
  113. data/lib/active_merchant/billing/integrations/gestpay/helper.rb +70 -0
  114. data/lib/active_merchant/billing/integrations/gestpay/notification.rb +85 -0
  115. data/lib/active_merchant/billing/integrations/gestpay/return.rb +10 -0
  116. data/lib/active_merchant/billing/integrations/helper.rb +96 -0
  117. data/lib/active_merchant/billing/integrations/hi_trust.rb +27 -0
  118. data/lib/active_merchant/billing/integrations/hi_trust/helper.rb +58 -0
  119. data/lib/active_merchant/billing/integrations/hi_trust/notification.rb +59 -0
  120. data/lib/active_merchant/billing/integrations/hi_trust/return.rb +67 -0
  121. data/lib/active_merchant/billing/integrations/nochex.rb +88 -0
  122. data/lib/active_merchant/billing/integrations/nochex/helper.rb +68 -0
  123. data/lib/active_merchant/billing/integrations/nochex/notification.rb +94 -0
  124. data/lib/active_merchant/billing/integrations/nochex/return.rb +10 -0
  125. data/lib/active_merchant/billing/integrations/notification.rb +62 -0
  126. data/lib/active_merchant/billing/integrations/paypal.rb +39 -0
  127. data/lib/active_merchant/billing/integrations/paypal/helper.rb +119 -0
  128. data/lib/active_merchant/billing/integrations/paypal/notification.rb +154 -0
  129. data/lib/active_merchant/billing/integrations/paypal/return.rb +10 -0
  130. data/lib/active_merchant/billing/integrations/quickpay.rb +17 -0
  131. data/lib/active_merchant/billing/integrations/quickpay/helper.rb +72 -0
  132. data/lib/active_merchant/billing/integrations/quickpay/notification.rb +74 -0
  133. data/lib/active_merchant/billing/integrations/return.rb +37 -0
  134. data/lib/active_merchant/billing/integrations/sage_pay_form.rb +37 -0
  135. data/lib/active_merchant/billing/integrations/sage_pay_form/encryption.rb +33 -0
  136. data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +109 -0
  137. data/lib/active_merchant/billing/integrations/sage_pay_form/notification.rb +204 -0
  138. data/lib/active_merchant/billing/integrations/sage_pay_form/return.rb +27 -0
  139. data/lib/active_merchant/billing/integrations/two_checkout.rb +23 -0
  140. data/lib/active_merchant/billing/integrations/two_checkout/helper.rb +59 -0
  141. data/lib/active_merchant/billing/integrations/two_checkout/notification.rb +114 -0
  142. data/lib/active_merchant/billing/integrations/two_checkout/return.rb +17 -0
  143. data/lib/active_merchant/billing/response.rb +32 -0
  144. data/lib/active_merchant/common.rb +14 -0
  145. data/lib/active_merchant/common/connection.rb +162 -0
  146. data/lib/active_merchant/common/country.rb +328 -0
  147. data/lib/active_merchant/common/error.rb +26 -0
  148. data/lib/active_merchant/common/post_data.rb +24 -0
  149. data/lib/active_merchant/common/posts_data.rb +61 -0
  150. data/lib/active_merchant/common/requires_parameters.rb +16 -0
  151. data/lib/active_merchant/common/utils.rb +18 -0
  152. data/lib/active_merchant/common/validateable.rb +76 -0
  153. data/lib/active_merchant/version.rb +3 -0
  154. data/lib/activemerchant.rb +1 -0
  155. data/lib/certs/cacert.pem +7815 -0
  156. data/lib/support/gateway_support.rb +58 -0
  157. data/lib/support/outbound_hosts.rb +25 -0
  158. metadata +270 -0
@@ -0,0 +1,229 @@
1
+ require 'rexml/document'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+
6
+ class EfsnetGateway < Gateway
7
+ self.supported_countries = ['US']
8
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover]
9
+ self.homepage_url = 'http://www.concordefsnet.com/'
10
+ self.display_name = 'Efsnet'
11
+
12
+ TEST_URL = 'https://testefsnet.concordebiz.com/efsnet.dll'
13
+ LIVE_URL = 'https://efsnet.concordebiz.com/efsnet.dll'
14
+
15
+ # login is your Store ID
16
+ # password is your Store Key
17
+ def initialize(options = {})
18
+ requires!(options, :login, :password)
19
+ @options = options
20
+ super
21
+ end
22
+
23
+ def test?
24
+ @options[:test] || super
25
+ end
26
+
27
+ def authorize(money, creditcard, options = {})
28
+ request = build_credit_card_request(money, creditcard, options)
29
+ commit(:credit_card_authorize, request)
30
+ end
31
+
32
+ def purchase(money, creditcard, options = {})
33
+ request = build_credit_card_request(money, creditcard, options)
34
+ commit(:credit_card_charge, request)
35
+ end
36
+
37
+ def capture(money, identification, options = {})
38
+ request = build_refund_or_settle_request(money, identification, options)
39
+ commit(:credit_card_settle, request)
40
+ end
41
+
42
+ def credit(money, identification_or_credit_card, options = {})
43
+ if identification_or_credit_card.is_a?(String)
44
+ # Perform authorization reversal
45
+ request = build_refund_or_settle_request(money, identification_or_credit_card, options)
46
+ commit(:credit_card_refund, request)
47
+ else
48
+ # Perform credit
49
+ request = build_credit_card_request(money, identification_or_credit_card, options)
50
+ commit(:credit_card_credit, request)
51
+ end
52
+ end
53
+
54
+ def void(identification, options = {})
55
+ requires!(options, :order_id)
56
+ original_transaction_id, original_transaction_amount = identification.split(";")
57
+ commit(:void_transaction, {:reference_number => format_reference_number(options[:order_id]), :transaction_ID => original_transaction_id})
58
+ end
59
+
60
+ def voice_authorize(money, authorization_code, creditcard, options = {})
61
+ options[:authorization_number] = authorization_code
62
+ request = build_credit_card_request(money, creditcard, options)
63
+ commit(:credit_card_voice_authorize, request)
64
+ end
65
+
66
+ def force(money, authorization_code, creditcard, options = {})
67
+ options[:authorization_number] = authorization_code
68
+ request = build_credit_card_request(money, creditcard, options)
69
+ commit(:credit_card_capture, request)
70
+ end
71
+
72
+ def system_check
73
+ commit(:system_check, {})
74
+ end
75
+
76
+ private
77
+
78
+ def build_refund_or_settle_request(money, identification, options = {})
79
+ original_transaction_id, original_transaction_amount = identification.split(";")
80
+
81
+ requires!(options, :order_id)
82
+
83
+ post = {
84
+ :reference_number => format_reference_number(options[:order_id]),
85
+ :transaction_amount => amount(money),
86
+ :original_transaction_amount => original_transaction_amount,
87
+ :original_transaction_ID => original_transaction_id,
88
+ :client_ip_address => options[:ip]
89
+ }
90
+ end
91
+
92
+ def build_credit_card_request(money, creditcard, options = {})
93
+ requires!(options, :order_id)
94
+
95
+ post = {
96
+ :reference_number => format_reference_number(options[:order_id]),
97
+ :authorization_number => options[:authorization_number],
98
+ :transaction_amount => amount(money),
99
+ :client_ip_address => options[:ip]
100
+
101
+ }
102
+ add_creditcard(post,creditcard)
103
+ add_address(post,options)
104
+ post
105
+ end
106
+
107
+ def format_reference_number(number)
108
+ number.to_s.slice(0,12)
109
+ end
110
+
111
+ def add_address(post,options)
112
+ if address = options[:billing_address] || options[:address]
113
+ if address[:address2]
114
+ post[:billing_address] = address[:address1].to_s << ' ' << address[:address2].to_s
115
+ else
116
+ post[:billing_address] = address[:address1].to_s
117
+ end
118
+ post[:billing_city] = address[:city].to_s
119
+ post[:billing_state] = address[:state].blank? ? 'n/a' : address[:state]
120
+ post[:billing_postal_code] = address[:zip].to_s
121
+ post[:billing_country] = address[:country].to_s
122
+ end
123
+
124
+ if address = options[:shipping_address]
125
+ if address[:address2]
126
+ post[:shipping_address] = address[:address1].to_s << ' ' << address[:address2].to_s
127
+ else
128
+ post[:shipping_address] = address[:address1].to_s
129
+ end
130
+ post[:shipping_city] = address[:city].to_s
131
+ post[:shipping_state] = address[:state].blank? ? 'n/a' : address[:state]
132
+ post[:shipping_postal_code] = address[:zip].to_s
133
+ post[:shipping_country] = address[:country].to_s
134
+ end
135
+ end
136
+
137
+ def add_creditcard(post, creditcard)
138
+ post[:billing_name] = creditcard.name if creditcard.name
139
+ post[:account_number] = creditcard.number
140
+ post[:card_verification_value] = creditcard.verification_value if creditcard.verification_value?
141
+ post[:expiration_month] = sprintf("%.2i", creditcard.month)
142
+ post[:expiration_year] = sprintf("%.4i", creditcard.year)[-2..-1]
143
+ end
144
+
145
+
146
+ def commit(action, parameters)
147
+ response = parse(ssl_post(test? ? TEST_URL : LIVE_URL, post_data(action, parameters), 'Content-Type' => 'text/xml'))
148
+
149
+ Response.new(success?(response), message_from(response[:result_message]), response,
150
+ :test => test?,
151
+ :authorization => authorization_from(response, parameters),
152
+ :avs_result => { :code => response[:avs_response_code] },
153
+ :cvv_result => response[:cvv_response_code]
154
+ )
155
+ end
156
+
157
+ def success?(response)
158
+ response[:response_code] == '0'
159
+ end
160
+
161
+ def authorization_from(response, params)
162
+ [ response[:transaction_id], params[:transaction_amount] ].compact.join(';')
163
+ end
164
+
165
+ def parse(xml)
166
+ response = {}
167
+
168
+ xml = REXML::Document.new(xml)
169
+
170
+ xml.elements.each('//Reply//TransactionReply/*') do |node|
171
+
172
+ response[node.name.underscore.to_sym] = normalize(node.text)
173
+
174
+ end unless xml.root.nil?
175
+
176
+ response
177
+ end
178
+
179
+ def post_data(action, parameters = {})
180
+ xml = REXML::Document.new("<?xml version='1.0' encoding='UTF-8'?>")
181
+ root = xml.add_element("Request")
182
+ root.attributes["StoreID"] = options[:login]
183
+ root.attributes["StoreKey"] = options[:password]
184
+ root.attributes["ApplicationID"] = 'ot 1.0'
185
+ transaction = root.add_element(action.to_s.camelize)
186
+
187
+ actions[action].each do |key|
188
+ transaction.add_element(key.to_s.camelize).text = parameters[key] unless parameters[key].blank?
189
+ end
190
+
191
+ xml.to_s
192
+ end
193
+
194
+ def message_from(message)
195
+ return 'Unspecified error' if message.blank?
196
+ message.gsub(/[^\w]/, ' ').split.join(" ").capitalize
197
+ end
198
+
199
+ # Make a ruby type out of the response string
200
+ def normalize(field)
201
+ case field
202
+ when "true" then true
203
+ when "false" then false
204
+ when "" then nil
205
+ when "null" then nil
206
+ else field
207
+ end
208
+ end
209
+
210
+ def actions
211
+ ACTIONS
212
+ end
213
+
214
+ CREDIT_CARD_FIELDS = [:authorization_number, :client_ip_address, :billing_address, :billing_city, :billing_state, :billing_postal_code, :billing_country, :billing_name, :card_verification_value, :expiration_month, :expiration_year, :reference_number, :transaction_amount, :account_number ]
215
+
216
+ ACTIONS = {
217
+ :credit_card_authorize => CREDIT_CARD_FIELDS,
218
+ :credit_card_charge => CREDIT_CARD_FIELDS,
219
+ :credit_card_voice_authorize => CREDIT_CARD_FIELDS,
220
+ :credit_card_capture => CREDIT_CARD_FIELDS,
221
+ :credit_card_credit => CREDIT_CARD_FIELDS << :original_transaction_amount,
222
+ :credit_card_refund => [:reference_number, :transaction_amount, :original_transaction_amount, :original_transaction_ID, :client_ip_address],
223
+ :void_transaction => [:reference_number, :transaction_ID],
224
+ :credit_card_settle => [:reference_number, :transaction_amount, :original_transaction_amount, :original_transaction_ID, :client_ip_address],
225
+ :system_check => [:system_check],
226
+ }
227
+ end
228
+ end
229
+ end
@@ -0,0 +1,134 @@
1
+ require File.dirname(__FILE__) + '/viaklix'
2
+
3
+ module ActiveMerchant #:nodoc:
4
+ module Billing #:nodoc:
5
+ # = Elavon Virtual Merchant Gateway
6
+ #
7
+ # == Example use:
8
+ #
9
+ # gateway = ActiveMerchant::Billing::ElavonGateway.new(
10
+ # :login => "my_virtual_merchant_id",
11
+ # :password => "my_virtual_merchant_pin",
12
+ # :user => "my_virtual_merchant_user_id" # optional
13
+ # )
14
+ #
15
+ # # set up credit card obj as in main ActiveMerchant example
16
+ # creditcard = ActiveMerchant::Billing::CreditCard.new(
17
+ # :type => 'visa',
18
+ # :number => '41111111111111111',
19
+ # :month => 10,
20
+ # :year => 2011,
21
+ # :first_name => 'Bob',
22
+ # :last_name => 'Bobsen'
23
+ # )
24
+ #
25
+ # # run request
26
+ # response = gateway.purchase(1000, creditcard) # authorize and capture 10 USD
27
+ #
28
+ # puts response.success? # Check whether the transaction was successful
29
+ # puts response.message # Retrieve the message returned by Elavon
30
+ # puts response.authorization # Retrieve the unique transaction ID returned by Elavon
31
+ #
32
+ class ElavonGateway < ViaklixGateway
33
+ self.test_url = self.live_url = 'https://www.myvirtualmerchant.com/VirtualMerchant/process.do'
34
+
35
+ self.display_name = 'Elavon MyVirtualMerchant'
36
+ self.supported_countries = ['US', 'CA']
37
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover]
38
+ self.homepage_url = 'http://www.elavon.com/'
39
+
40
+ self.delimiter = "\n"
41
+ self.actions = {
42
+ :purchase => 'CCSALE',
43
+ :credit => 'CCCREDIT',
44
+ :authorize => 'CCAUTHONLY',
45
+ :capture => 'CCFORCE'
46
+ }
47
+
48
+ # Authorize a credit card for a given amount.
49
+ #
50
+ # ==== Parameters
51
+ # * <tt>money</tt> - The amount to be authorized as an Integer value in cents.
52
+ # * <tt>credit_card</tt> - The CreditCard details for the transaction.
53
+ # * <tt>options</tt>
54
+ # * <tt>:billing_address</tt> - The billing address for the cardholder.
55
+ def authorize(money, creditcard, options = {})
56
+ form = {}
57
+ add_invoice(form, options)
58
+ add_creditcard(form, creditcard)
59
+ add_address(form, options)
60
+ add_customer_data(form, options)
61
+ commit(:authorize, money, form)
62
+ end
63
+
64
+ # Capture authorized funds from a credit card.
65
+ #
66
+ # ==== Parameters
67
+ # * <tt>money</tt> - The amount to be captured as an Integer value in cents.
68
+ # * <tt>authorization</tt> - The approval code returned from the initial authorization.
69
+ # * <tt>options</tt>
70
+ # * <tt>:credit_card</tt> - The CreditCard details from the initial transaction (required).
71
+ def capture(money, authorization, options = {})
72
+ requires!(options, :credit_card)
73
+
74
+ form = {}
75
+ add_reference(form, authorization)
76
+ add_invoice(form, options)
77
+ add_creditcard(form, options[:credit_card])
78
+ add_customer_data(form, options)
79
+ commit(:capture, money, form)
80
+ end
81
+
82
+ private
83
+ def add_reference(form, authorization)
84
+ form[:approval_code] = authorization
85
+ end
86
+
87
+ def authorization_from(response)
88
+ response['approval_code']
89
+ end
90
+
91
+ def add_verification_value(form, creditcard)
92
+ form[:cvv2cvc2] = creditcard.verification_value
93
+ form[:cvv2cvc2_indicator] = '1'
94
+ end
95
+
96
+ def add_address(form,options)
97
+ billing_address = options[:billing_address] || options[:address]
98
+
99
+ if billing_address
100
+ form[:avs_address] = billing_address[:address1].to_s.slice(0, 30)
101
+ form[:address2] = billing_address[:address2].to_s.slice(0, 30)
102
+ form[:avs_zip] = billing_address[:zip].to_s.slice(0, 10)
103
+ form[:city] = billing_address[:city].to_s.slice(0, 30)
104
+ form[:state] = billing_address[:state].to_s.slice(0, 10)
105
+ form[:company] = billing_address[:company].to_s.slice(0, 50)
106
+ form[:phone] = billing_address[:phone].to_s.slice(0, 20)
107
+ form[:country] = billing_address[:country].to_s.slice(0, 50)
108
+ end
109
+
110
+ if shipping_address = options[:shipping_address]
111
+ first_name, last_name = parse_first_and_last_name(shipping_address[:name])
112
+ form[:ship_to_first_name] = first_name.to_s.slice(0, 20)
113
+ form[:ship_to_last_name] = last_name.to_s.slice(0, 30)
114
+ form[:ship_to_address1] = shipping_address[:address1].to_s.slice(0, 30)
115
+ form[:ship_to_address2] = shipping_address[:address2].to_s.slice(0, 30)
116
+ form[:ship_to_city] = shipping_address[:city].to_s.slice(0, 30)
117
+ form[:ship_to_state] = shipping_address[:state].to_s.slice(0, 10)
118
+ form[:ship_to_company] = shipping_address[:company].to_s.slice(0, 50)
119
+ form[:ship_to_country] = shipping_address[:country].to_s.slice(0, 50)
120
+ form[:ship_to_zip] = shipping_address[:zip].to_s.slice(0, 10)
121
+ end
122
+ end
123
+
124
+ def message_from(response)
125
+ success?(response) ? response['result_message'] : response['errorMessage']
126
+ end
127
+
128
+ def success?(response)
129
+ !response.has_key?('errorMessage')
130
+ end
131
+ end
132
+ end
133
+ end
134
+
@@ -0,0 +1,263 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class EpayGateway < Gateway
4
+ API_HOST = 'ssl.ditonlinebetalingssystem.dk'
5
+ SOAP_URL = 'https://' + API_HOST + '/remote/payment'
6
+
7
+ self.default_currency = 'DKK'
8
+ self.money_format = :cents
9
+ self.supported_cardtypes = [:dankort, :forbrugsforeningen, :visa, :master,
10
+ :american_express, :diners_club, :jcb, :maestro]
11
+ self.supported_countries = ['DK']
12
+ self.homepage_url = 'http://epay.dk/'
13
+ self.display_name = 'ePay'
14
+
15
+ CURRENCY_CODES = {
16
+ :ADP => '020', :AED => '784', :AFA => '004', :ALL => '008', :AMD => '051',
17
+ :ANG => '532', :AOA => '973', :ARS => '032', :AUD => '036', :AWG => '533',
18
+ :AZM => '031', :BAM => '977', :BBD => '052', :BDT => '050', :BGL => '100',
19
+ :BGN => '975', :BHD => '048', :BIF => '108', :BMD => '060', :BND => '096',
20
+ :BOB => '068', :BOV => '984', :BRL => '986', :BSD => '044', :BTN => '064',
21
+ :BWP => '072', :BYR => '974', :BZD => '084', :CAD => '124', :CDF => '976',
22
+ :CHF => '756', :CLF => '990', :CLP => '152', :CNY => '156', :COP => '170',
23
+ :CRC => '188', :CUP => '192', :CVE => '132', :CYP => '196', :CZK => '203',
24
+ :DJF => '262', :DKK => '208', :DOP => '214', :DZD => '012', :ECS => '218',
25
+ :ECV => '983', :EEK => '233', :EGP => '818', :ERN => '232', :ETB => '230',
26
+ :EUR => '978', :FJD => '242', :FKP => '238', :GBP => '826', :GEL => '981',
27
+ :GHC => '288', :GIP => '292', :GMD => '270', :GNF => '324', :GTQ => '320',
28
+ :GWP => '624', :GYD => '328', :HKD => '344', :HNL => '340', :HRK => '191',
29
+ :HTG => '332', :HUF => '348', :IDR => '360', :ILS => '376', :INR => '356',
30
+ :IQD => '368', :IRR => '364', :ISK => '352', :JMD => '388', :JOD => '400',
31
+ :JPY => '392', :KES => '404', :KGS => '417', :KHR => '116', :KMF => '174',
32
+ :KPW => '408', :KRW => '410', :KWD => '414', :KYD => '136', :KZT => '398',
33
+ :LAK => '418', :LBP => '422', :LKR => '144', :LRD => '430', :LSL => '426',
34
+ :LTL => '440', :LVL => '428', :LYD => '434', :MAD => '504', :MDL => '498',
35
+ :MGF => '450', :MKD => '807', :MMK => '104', :MNT => '496', :MOP => '446',
36
+ :MRO => '478', :MTL => '470', :MUR => '480', :MVR => '462', :MWK => '454',
37
+ :MXN => '484', :MXV => '979', :MYR => '458', :MZM => '508', :NAD => '516',
38
+ :NGN => '566', :NIO => '558', :NOK => '578', :NPR => '524', :NZD => '554',
39
+ :OMR => '512', :PAB => '590', :PEN => '604', :PGK => '598', :PHP => '608',
40
+ :PKR => '586', :PLN => '985', :PYG => '600', :QAR => '634', :ROL => '642',
41
+ :RUB => '643', :RUR => '810', :RWF => '646', :SAR => '682', :SBD => '090',
42
+ :SCR => '690', :SDD => '736', :SEK => '752', :SGD => '702', :SHP => '654',
43
+ :SIT => '705', :SKK => '703', :SLL => '694', :SOS => '706', :SRG => '740',
44
+ :STD => '678', :SVC => '222', :SYP => '760', :SZL => '748', :THB => '764',
45
+ :TJS => '972', :TMM => '795', :TND => '788', :TOP => '776', :TPE => '626',
46
+ :TRL => '792', :TRY => '949', :TTD => '780', :TWD => '901', :TZS => '834',
47
+ :UAH => '980', :UGX => '800', :USD => '840', :UYU => '858', :UZS => '860',
48
+ :VEB => '862', :VND => '704', :VUV => '548', :XAF => '950', :XCD => '951',
49
+ :XOF => '952', :XPF => '953', :YER => '886', :YUM => '891', :ZAR => '710',
50
+ :ZMK => '894', :ZWD => '716'
51
+ }
52
+
53
+ # login: merchant number
54
+ # password: referrer url (for authorize authentication)
55
+ def initialize(options = {})
56
+ requires!(options, :login, :password)
57
+ @options = options
58
+ super
59
+ end
60
+
61
+ def authorize(money, credit_card_or_reference, options = {})
62
+ post = {}
63
+
64
+ add_amount(post, money, options)
65
+ add_invoice(post)
66
+ add_creditcard_or_reference(post, credit_card_or_reference)
67
+ add_instant_capture(post, false)
68
+
69
+ commit(:authorize, post)
70
+ end
71
+
72
+ def purchase(money, credit_card_or_reference, options = {})
73
+ post = {}
74
+
75
+ add_amount(post, money, options)
76
+ add_creditcard_or_reference(post, credit_card_or_reference)
77
+ add_invoice(post)
78
+ add_instant_capture(post, true)
79
+
80
+ commit(:authorize, post)
81
+ end
82
+
83
+ def capture(money, authorization, options = {})
84
+ post = {}
85
+
86
+ add_reference(post, authorization)
87
+ add_amount_without_currency(post, money)
88
+
89
+ commit(:capture, post)
90
+ end
91
+
92
+ def void(identification, options = {})
93
+ post = {}
94
+
95
+ add_reference(post, identification)
96
+
97
+ commit(:void, post)
98
+ end
99
+
100
+ def credit(money, identification, options = {})
101
+ post = {}
102
+
103
+ add_amount_without_currency(post, money)
104
+ add_reference(post, identification)
105
+
106
+ commit(:credit, post)
107
+ end
108
+
109
+
110
+ private
111
+
112
+ def add_amount(post, money, options)
113
+ post[:amount] = amount(money)
114
+ post[:currency] = CURRENCY_CODES[(options[:currency] || currency(money)).to_sym]
115
+ end
116
+
117
+ def add_amount_without_currency(post, money)
118
+ post[:amount] = amount(money)
119
+ end
120
+
121
+ def add_reference(post, identification)
122
+ post[:transaction] = identification
123
+ end
124
+
125
+ def add_invoice(post)
126
+ post[:orderid] = format_order_number(options[:order_id])
127
+ end
128
+
129
+ def add_creditcard(post, credit_card)
130
+ post[:cardno] = credit_card.number
131
+ post[:cvc] = credit_card.verification_value
132
+ post[:expmonth] = credit_card.month
133
+ post[:expyear] = credit_card.year
134
+ end
135
+
136
+ def add_creditcard_or_reference(post, credit_card_or_reference)
137
+ if credit_card_or_reference.is_a?(CreditCard)
138
+ add_creditcard(post, credit_card_or_reference)
139
+ else
140
+ add_reference(post, credit_card_or_reference.to_s)
141
+ end
142
+ end
143
+
144
+ def add_instant_capture(post, option)
145
+ post[:instantcapture] = option ? 1 : 0
146
+ end
147
+
148
+ def commit(action, params)
149
+ response = send("do_#{action}", params)
150
+
151
+ if action == :authorize
152
+ Response.new response['accept'].to_i == 1,
153
+ response['errortext'],
154
+ response,
155
+ :test => test?,
156
+ :authorization => response['tid']
157
+ else
158
+ Response.new response['result'] == 'true',
159
+ messages(response['epay'], response['pbs']),
160
+ response,
161
+ :test => test?,
162
+ :authorization => params[:transaction]
163
+ end
164
+ end
165
+
166
+ def messages(epay, pbs = nil)
167
+ response = "ePay: #{epay}"
168
+ response << " PBS: #{pbs}" if pbs
169
+ return response
170
+ end
171
+
172
+ def soap_post(method, params)
173
+ data = xml_builder(params, method)
174
+ headers = make_headers(data, method)
175
+ REXML::Document.new(ssl_post('https://' + API_HOST + '/remote/payment.asmx', data, headers))
176
+ end
177
+
178
+ def do_authorize(params)
179
+ headers = {
180
+ 'Referer' => options[:password]
181
+ }
182
+
183
+ response = raw_ssl_request(:post, 'https://' + API_HOST + '/auth/default.aspx', authorize_post_data(params), headers)
184
+
185
+ # Authorize gives the response back by redirecting with the values in
186
+ # the URL query
187
+ query = CGI::parse(URI.parse(response['Location'].gsub(' ', '%20')).query)
188
+
189
+ result = {}
190
+ query.each_pair do |k,v|
191
+ result[k] = v.is_a?(Array) && v.size == 1 ? v[0] : v # make values like ['v'] into 'v'
192
+ end
193
+ result
194
+ end
195
+
196
+ def do_capture(params)
197
+ response = soap_post('capture', params)
198
+ {
199
+ 'result' => response.elements['//captureResponse/captureResult'].text,
200
+ 'pbs' => response.elements['//captureResponse/pbsResponse'].text,
201
+ 'epay' => response.elements['//captureResponse/epayresponse'].text
202
+ }
203
+ end
204
+
205
+ def do_credit(params)
206
+ response = soap_post('credit', params)
207
+ {
208
+ 'result' => response.elements['//creditResponse/creditResult'].text,
209
+ 'pbs' => response.elements['//creditResponse/pbsresponse'].text,
210
+ 'epay' => response.elements['//creditResponse/epayresponse'].text
211
+ }
212
+ end
213
+
214
+ def do_void(params)
215
+ response = soap_post('delete', params)
216
+ {
217
+ 'result' => response.elements['//deleteResponse/deleteResult'].text,
218
+ 'epay' => response.elements['//deleteResponse/epayresponse'].text
219
+ }
220
+ end
221
+
222
+ def make_headers(data, soap_call)
223
+ {
224
+ 'Content-Type' => 'text/xml; charset=utf-8',
225
+ 'Host' => API_HOST,
226
+ 'Content-Length' => data.size.to_s,
227
+ 'SOAPAction' => SOAP_URL + '/' + soap_call
228
+ }
229
+ end
230
+
231
+ def xml_builder(params, soap_call)
232
+ xml = Builder::XmlMarkup.new(:indent => 2)
233
+ xml.instruct!
234
+ xml.tag! 'soap:Envelope', { 'xmlns:xsi' => 'http://schemas.xmlsoap.org/soap/envelope/',
235
+ 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
236
+ 'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/' } do
237
+ xml.tag! 'soap:Body' do
238
+ xml.tag! soap_call, { 'xmlns' => SOAP_URL } do
239
+ xml.tag! 'merchantnumber', @options[:login]
240
+ xml.tag! 'transactionid', params[:transaction]
241
+ xml.tag! 'amount', params[:amount].to_s if soap_call != 'delete'
242
+ end
243
+ end
244
+ end
245
+ xml.target!
246
+ end
247
+
248
+ def authorize_post_data(params = {})
249
+ params[:language] = '2'
250
+ params[:accepturl] = 'https://ssl.ditonlinebetalingssystem.dk/auth/default.aspx?accept=1'
251
+ params[:declineurl] = 'https://ssl.ditonlinebetalingssystem.dk/auth/default.aspx?decline=1'
252
+ params[:merchantnumber] = @options[:login]
253
+
254
+ params.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
255
+ end
256
+
257
+ # Limited to 20 digits max
258
+ def format_order_number(number)
259
+ number.to_s.gsub(/[^\w_]/, '').rjust(4, "0")[0...20]
260
+ end
261
+ end
262
+ end
263
+ end