johnreitano-activemerchant 1.5.2

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 (131) hide show
  1. data/CHANGELOG +508 -0
  2. data/CONTRIBUTORS +134 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +136 -0
  5. data/gem-public_cert.pem +20 -0
  6. data/lib/active_merchant/billing/avs_result.rb +98 -0
  7. data/lib/active_merchant/billing/base.rb +57 -0
  8. data/lib/active_merchant/billing/check.rb +68 -0
  9. data/lib/active_merchant/billing/credit_card.rb +159 -0
  10. data/lib/active_merchant/billing/credit_card_formatting.rb +21 -0
  11. data/lib/active_merchant/billing/credit_card_methods.rb +125 -0
  12. data/lib/active_merchant/billing/cvv_result.rb +38 -0
  13. data/lib/active_merchant/billing/expiry_date.rb +34 -0
  14. data/lib/active_merchant/billing/gateway.rb +163 -0
  15. data/lib/active_merchant/billing/gateways/authorize_net.rb +654 -0
  16. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +736 -0
  17. data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +244 -0
  18. data/lib/active_merchant/billing/gateways/beanstream.rb +102 -0
  19. data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
  20. data/lib/active_merchant/billing/gateways/bogus.rb +98 -0
  21. data/lib/active_merchant/billing/gateways/braintree.rb +17 -0
  22. data/lib/active_merchant/billing/gateways/card_stream.rb +230 -0
  23. data/lib/active_merchant/billing/gateways/cyber_source.rb +594 -0
  24. data/lib/active_merchant/billing/gateways/data_cash.rb +593 -0
  25. data/lib/active_merchant/billing/gateways/efsnet.rb +229 -0
  26. data/lib/active_merchant/billing/gateways/elavon.rb +134 -0
  27. data/lib/active_merchant/billing/gateways/eway.rb +277 -0
  28. data/lib/active_merchant/billing/gateways/exact.rb +222 -0
  29. data/lib/active_merchant/billing/gateways/first_pay.rb +172 -0
  30. data/lib/active_merchant/billing/gateways/instapay.rb +164 -0
  31. data/lib/active_merchant/billing/gateways/jetpay.rb +270 -0
  32. data/lib/active_merchant/billing/gateways/linkpoint.rb +449 -0
  33. data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +154 -0
  34. data/lib/active_merchant/billing/gateways/merchant_ware.rb +283 -0
  35. data/lib/active_merchant/billing/gateways/modern_payments.rb +36 -0
  36. data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +220 -0
  37. data/lib/active_merchant/billing/gateways/moneris.rb +205 -0
  38. data/lib/active_merchant/billing/gateways/net_registry.rb +189 -0
  39. data/lib/active_merchant/billing/gateways/netbilling.rb +168 -0
  40. data/lib/active_merchant/billing/gateways/ogone.rb +279 -0
  41. data/lib/active_merchant/billing/gateways/pay_junction.rb +392 -0
  42. data/lib/active_merchant/billing/gateways/pay_secure.rb +120 -0
  43. data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +207 -0
  44. data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
  45. data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
  46. data/lib/active_merchant/billing/gateways/payflow.rb +236 -0
  47. data/lib/active_merchant/billing/gateways/payflow_express.rb +138 -0
  48. data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
  49. data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
  50. data/lib/active_merchant/billing/gateways/payment_express.rb +230 -0
  51. data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +326 -0
  52. data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +38 -0
  53. data/lib/active_merchant/billing/gateways/paypal.rb +121 -0
  54. data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
  55. data/lib/active_merchant/billing/gateways/paypal_express.rb +130 -0
  56. data/lib/active_merchant/billing/gateways/paypal_express_common.rb +20 -0
  57. data/lib/active_merchant/billing/gateways/plugnpay.rb +292 -0
  58. data/lib/active_merchant/billing/gateways/psigate.rb +214 -0
  59. data/lib/active_merchant/billing/gateways/psl_card.rb +304 -0
  60. data/lib/active_merchant/billing/gateways/quickpay.rb +213 -0
  61. data/lib/active_merchant/billing/gateways/realex.rb +200 -0
  62. data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +88 -0
  63. data/lib/active_merchant/billing/gateways/sage/sage_core.rb +116 -0
  64. data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +97 -0
  65. data/lib/active_merchant/billing/gateways/sage.rb +146 -0
  66. data/lib/active_merchant/billing/gateways/sage_pay.rb +309 -0
  67. data/lib/active_merchant/billing/gateways/sallie_mae.rb +144 -0
  68. data/lib/active_merchant/billing/gateways/secure_pay.rb +31 -0
  69. data/lib/active_merchant/billing/gateways/secure_pay_au.rb +157 -0
  70. data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +113 -0
  71. data/lib/active_merchant/billing/gateways/skip_jack.rb +453 -0
  72. data/lib/active_merchant/billing/gateways/smart_ps.rb +265 -0
  73. data/lib/active_merchant/billing/gateways/trans_first.rb +127 -0
  74. data/lib/active_merchant/billing/gateways/transax.rb +25 -0
  75. data/lib/active_merchant/billing/gateways/trust_commerce.rb +418 -0
  76. data/lib/active_merchant/billing/gateways/usa_epay.rb +194 -0
  77. data/lib/active_merchant/billing/gateways/verifi.rb +228 -0
  78. data/lib/active_merchant/billing/gateways/viaklix.rb +189 -0
  79. data/lib/active_merchant/billing/gateways/wirecard.rb +318 -0
  80. data/lib/active_merchant/billing/gateways.rb +18 -0
  81. data/lib/active_merchant/billing/integrations/action_view_helper.rb +79 -0
  82. data/lib/active_merchant/billing/integrations/bogus/helper.rb +17 -0
  83. data/lib/active_merchant/billing/integrations/bogus/notification.rb +11 -0
  84. data/lib/active_merchant/billing/integrations/bogus/return.rb +10 -0
  85. data/lib/active_merchant/billing/integrations/bogus.rb +23 -0
  86. data/lib/active_merchant/billing/integrations/chronopay/helper.rb +120 -0
  87. data/lib/active_merchant/billing/integrations/chronopay/notification.rb +158 -0
  88. data/lib/active_merchant/billing/integrations/chronopay/return.rb +10 -0
  89. data/lib/active_merchant/billing/integrations/chronopay.rb +23 -0
  90. data/lib/active_merchant/billing/integrations/gestpay/common.rb +42 -0
  91. data/lib/active_merchant/billing/integrations/gestpay/helper.rb +70 -0
  92. data/lib/active_merchant/billing/integrations/gestpay/notification.rb +85 -0
  93. data/lib/active_merchant/billing/integrations/gestpay/return.rb +10 -0
  94. data/lib/active_merchant/billing/integrations/gestpay.rb +25 -0
  95. data/lib/active_merchant/billing/integrations/helper.rb +93 -0
  96. data/lib/active_merchant/billing/integrations/hi_trust/helper.rb +58 -0
  97. data/lib/active_merchant/billing/integrations/hi_trust/notification.rb +59 -0
  98. data/lib/active_merchant/billing/integrations/hi_trust/return.rb +67 -0
  99. data/lib/active_merchant/billing/integrations/hi_trust.rb +27 -0
  100. data/lib/active_merchant/billing/integrations/nochex/helper.rb +68 -0
  101. data/lib/active_merchant/billing/integrations/nochex/notification.rb +94 -0
  102. data/lib/active_merchant/billing/integrations/nochex/return.rb +10 -0
  103. data/lib/active_merchant/billing/integrations/nochex.rb +88 -0
  104. data/lib/active_merchant/billing/integrations/notification.rb +62 -0
  105. data/lib/active_merchant/billing/integrations/paypal/helper.rb +119 -0
  106. data/lib/active_merchant/billing/integrations/paypal/notification.rb +154 -0
  107. data/lib/active_merchant/billing/integrations/paypal/return.rb +10 -0
  108. data/lib/active_merchant/billing/integrations/paypal.rb +39 -0
  109. data/lib/active_merchant/billing/integrations/quickpay/helper.rb +72 -0
  110. data/lib/active_merchant/billing/integrations/quickpay/notification.rb +74 -0
  111. data/lib/active_merchant/billing/integrations/quickpay.rb +17 -0
  112. data/lib/active_merchant/billing/integrations/return.rb +35 -0
  113. data/lib/active_merchant/billing/integrations/two_checkout/helper.rb +59 -0
  114. data/lib/active_merchant/billing/integrations/two_checkout/notification.rb +114 -0
  115. data/lib/active_merchant/billing/integrations/two_checkout/return.rb +17 -0
  116. data/lib/active_merchant/billing/integrations/two_checkout.rb +23 -0
  117. data/lib/active_merchant/billing/integrations.rb +29 -0
  118. data/lib/active_merchant/billing/response.rb +32 -0
  119. data/lib/active_merchant/billing.rb +9 -0
  120. data/lib/active_merchant/lib/connection.rb +170 -0
  121. data/lib/active_merchant/lib/country.rb +319 -0
  122. data/lib/active_merchant/lib/error.rb +4 -0
  123. data/lib/active_merchant/lib/post_data.rb +22 -0
  124. data/lib/active_merchant/lib/posts_data.rb +47 -0
  125. data/lib/active_merchant/lib/requires_parameters.rb +16 -0
  126. data/lib/active_merchant/lib/utils.rb +18 -0
  127. data/lib/active_merchant/lib/validateable.rb +76 -0
  128. data/lib/active_merchant.rb +46 -0
  129. data/lib/certs/cacert.pem +7815 -0
  130. data/lib/support/gateway_support.rb +58 -0
  131. metadata +218 -0
@@ -0,0 +1,222 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class ExactGateway < Gateway
4
+ URL = 'https://secure2.e-xact.com/vplug-in/transaction/rpc-enc/service.asmx'
5
+
6
+ API_VERSION = "8.5"
7
+
8
+ TEST_LOGINS = [ {:login => "A00049-01", :password => "test1"},
9
+ {:login => "A00427-01", :password => "testus"} ]
10
+
11
+ TRANSACTIONS = { :sale => "00",
12
+ :authorization => "01",
13
+ :capture => "32",
14
+ :credit => "34" }
15
+
16
+
17
+ ENVELOPE_NAMESPACES = { 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
18
+ 'xmlns:env' => 'http://schemas.xmlsoap.org/soap/envelope/',
19
+ 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
20
+ }
21
+
22
+ SEND_AND_COMMIT_ATTRIBUTES = { 'xmlns:n1' => "http://secure2.e-xact.com/vplug-in/transaction/rpc-enc/Request",
23
+ 'env:encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/'
24
+ }
25
+
26
+ SEND_AND_COMMIT_SOURCE_ATTRIBUTES = { 'xmlns:n2' => 'http://secure2.e-xact.com/vplug-in/transaction/rpc-enc/encodedTypes',
27
+ 'xsi:type' => 'n2:Transaction'
28
+ }
29
+
30
+ POST_HEADERS = { 'soapAction' => "http://secure2.e-xact.com/vplug-in/transaction/rpc-enc/SendAndCommit",
31
+ 'Content-Type' => 'text/xml'
32
+ }
33
+
34
+ SUCCESS = "true"
35
+
36
+ SENSITIVE_FIELDS = [ :verification_str2, :expiry_date, :card_number ]
37
+
38
+ self.supported_cardtypes = [:visa, :master, :american_express, :jcb, :discover]
39
+ self.supported_countries = ['CA', 'US']
40
+ self.homepage_url = 'http://www.e-xact.com'
41
+ self.display_name = 'E-xact'
42
+
43
+ def initialize(options = {})
44
+ requires!(options, :login, :password)
45
+ @options = options
46
+
47
+ if TEST_LOGINS.include?( { :login => options[:login], :password => options[:password] } )
48
+ @test_mode = true
49
+ end
50
+
51
+ super
52
+ end
53
+
54
+ def test?
55
+ @test_mode || Base.gateway_mode == :test
56
+ end
57
+
58
+ def authorize(money, credit_card, options = {})
59
+ commit(:authorization, build_sale_or_authorization_request(money, credit_card, options))
60
+ end
61
+
62
+ def purchase(money, credit_card, options = {})
63
+ commit(:sale, build_sale_or_authorization_request(money, credit_card, options))
64
+ end
65
+
66
+ def capture(money, authorization, options = {})
67
+ commit(:capture, build_capture_or_credit_request(money, authorization, options))
68
+ end
69
+
70
+ def credit(money, authorization, options = {})
71
+ commit(:credit, build_capture_or_credit_request(money, authorization, options))
72
+ end
73
+
74
+ private
75
+ def build_request(action, body)
76
+ xml = Builder::XmlMarkup.new
77
+
78
+ xml.instruct!
79
+ xml.tag! 'env:Envelope', ENVELOPE_NAMESPACES do
80
+ xml.tag! 'env:Body' do
81
+ xml.tag! 'n1:SendAndCommit', SEND_AND_COMMIT_ATTRIBUTES do
82
+ xml.tag! 'SendAndCommitSource', SEND_AND_COMMIT_SOURCE_ATTRIBUTES do
83
+ add_credentials(xml)
84
+ add_transaction_type(xml, action)
85
+ xml << body
86
+ end
87
+ end
88
+ end
89
+ end
90
+ xml.target!
91
+ end
92
+
93
+ def build_sale_or_authorization_request(money, credit_card, options)
94
+ xml = Builder::XmlMarkup.new
95
+
96
+ add_amount(xml, money)
97
+ add_credit_card(xml, credit_card)
98
+ add_customer_data(xml, options)
99
+ add_invoice(xml, options)
100
+
101
+ xml.target!
102
+ end
103
+
104
+ def build_capture_or_credit_request(money, identification, options)
105
+ xml = Builder::XmlMarkup.new
106
+
107
+ add_identification(xml, identification)
108
+ add_amount(xml, money)
109
+ add_customer_data(xml, options)
110
+
111
+ xml.target!
112
+ end
113
+
114
+ def add_credentials(xml)
115
+ xml.tag! 'ExactID', @options[:login]
116
+ xml.tag! 'Password', @options[:password]
117
+ end
118
+
119
+ def add_transaction_type(xml, action)
120
+ xml.tag! 'Transaction_Type', TRANSACTIONS[action]
121
+ end
122
+
123
+ def add_identification(xml, identification)
124
+ authorization_num, transaction_tag = identification.split(';')
125
+
126
+ xml.tag! 'Authorization_Num', authorization_num
127
+ xml.tag! 'Transaction_Tag', transaction_tag
128
+ end
129
+
130
+ def add_amount(xml, money)
131
+ xml.tag! 'DollarAmount', amount(money)
132
+ end
133
+
134
+ def add_credit_card(xml, credit_card)
135
+ xml.tag! 'Card_Number', credit_card.number
136
+ xml.tag! 'Expiry_Date', expdate(credit_card)
137
+ xml.tag! 'CardHoldersName', credit_card.name
138
+
139
+ if credit_card.verification_value?
140
+ xml.tag! 'CVD_Presence_Ind', '1'
141
+ xml.tag! 'VerificationStr2', credit_card.verification_value
142
+ end
143
+ end
144
+
145
+ def add_customer_data(xml, options)
146
+ xml.tag! 'Customer_Ref', options[:customer]
147
+ xml.tag! 'Client_IP', options[:ip]
148
+ xml.tag! 'Client_Email', options[:email]
149
+ end
150
+
151
+ def add_address(xml, options)
152
+ if address = options[:billing_address] || options[:address]
153
+ xml.tag! 'ZipCode', address[:zip]
154
+ end
155
+ end
156
+
157
+ def add_invoice(xml, options)
158
+ xml.tag! 'Reference_No', options[:order_id]
159
+ xml.tag! 'Reference_3', options[:description]
160
+ end
161
+
162
+ def expdate(credit_card)
163
+ "#{format(credit_card.month, :two_digits)}#{format(credit_card.year, :two_digits)}"
164
+ end
165
+
166
+ def commit(action, request)
167
+ response = parse(ssl_post(URL, build_request(action, request), POST_HEADERS))
168
+
169
+ Response.new(successful?(response), message_from(response), response,
170
+ :test => test?,
171
+ :authorization => authorization_from(response),
172
+ :avs_result => { :code => response[:avs] },
173
+ :cvv_result => response[:cvv2]
174
+ )
175
+ end
176
+
177
+ def successful?(response)
178
+ response[:transaction_approved] == SUCCESS
179
+ end
180
+
181
+ def authorization_from(response)
182
+ if response[:authorization_num] && response[:transaction_tag]
183
+ "#{response[:authorization_num]};#{response[:transaction_tag]}"
184
+ else
185
+ ''
186
+ end
187
+ end
188
+
189
+ def message_from(response)
190
+ if response[:faultcode] && response[:faultstring]
191
+ response[:faultstring]
192
+ elsif response[:error_number] != '0'
193
+ response[:error_description]
194
+ else
195
+ result = response[:exact_message] || ''
196
+ result << " - #{response[:bank_message]}" unless response[:bank_message].blank?
197
+ result
198
+ end
199
+ end
200
+
201
+ def parse(xml)
202
+ response = {}
203
+ xml = REXML::Document.new(xml)
204
+
205
+ if root = REXML::XPath.first(xml, "//types:TransactionResult")
206
+ parse_elements(response, root)
207
+ elsif root = REXML::XPath.first(xml, "//soap:Fault")
208
+ parse_elements(response, root)
209
+ end
210
+
211
+ response.delete_if{ |k,v| SENSITIVE_FIELDS.include?(k) }
212
+ end
213
+
214
+ def parse_elements(response, root)
215
+ root.elements.to_a.each do |node|
216
+ response[node.name.gsub(/EXact/, 'Exact').underscore.to_sym] = (node.text || '').strip
217
+ end
218
+ end
219
+ end
220
+ end
221
+ end
222
+
@@ -0,0 +1,172 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class FirstPayGateway < Gateway
4
+ class FirstPayPostData < PostData
5
+ # Fields that will be sent even if they are blank
6
+ self.required_fields = [ :action, :amount, :trackid ]
7
+ end
8
+
9
+ # both URLs are IP restricted
10
+ TEST_URL = 'https://apgcert.first-pay.com/AcqENGIN/SecureCapture'
11
+ LIVE_URL = 'https://acqengin.first-pay.com/AcqENGIN/SecureCapture'
12
+
13
+ # The countries the gateway supports merchants from as 2 digit ISO country codes
14
+ self.supported_countries = ['US']
15
+
16
+ # The card types supported by the payment gateway
17
+ self.supported_cardtypes = [:visa, :master]
18
+
19
+ # The homepage URL of the gateway
20
+ self.homepage_url = 'http://www.first-pay.com'
21
+
22
+ # The name of the gateway
23
+ self.display_name = 'First Pay'
24
+
25
+ # all transactions are in cents
26
+ self.money_format = :cents
27
+
28
+ ACTIONS = {
29
+ 'sale' => 1,
30
+ 'credit' => 2,
31
+ 'void' => 3
32
+ }
33
+
34
+ def initialize(options = {})
35
+ requires!(options, :login, :password)
36
+ @options = options
37
+ super
38
+ end
39
+
40
+ def purchase(money, creditcard, options = {})
41
+ post = FirstPayPostData.new
42
+ add_invoice(post, options)
43
+ add_creditcard(post, creditcard)
44
+ add_address(post, options)
45
+ add_customer_data(post, options)
46
+
47
+ commit('sale', money, post)
48
+ end
49
+
50
+ def credit(money, reference, options = {})
51
+ raise ArgumentError, "Both TransactionID and CreditCard are required" unless reference.is_a?(String) && options[:credit_card]
52
+
53
+ post = FirstPayPostData.new
54
+ add_invoice(post, options)
55
+ add_creditcard(post, options[:credit_card])
56
+ add_address(post, options)
57
+ add_customer_data(post, options)
58
+ add_credit_data(post, reference)
59
+
60
+ commit('credit', money, post)
61
+ end
62
+
63
+ def void(money, creditcard, options = {})
64
+ post = FirstPayPostData.new
65
+ add_creditcard(post, creditcard)
66
+ add_void_data(post, options)
67
+ add_invoice(post, options)
68
+ add_customer_data(post, options)
69
+
70
+ commit('void', money, post)
71
+ end
72
+
73
+
74
+ private
75
+
76
+ def add_customer_data(post, options)
77
+ post[:cardip] = options[:ip]
78
+ post[:email] = options[:email]
79
+ end
80
+
81
+ def add_address(post, options)
82
+ if billing_address = options[:billing_address] || options[:address]
83
+ post[:addr] = billing_address[:address1].to_s + ' ' + billing_address[:address2].to_s
84
+ post[:city] = billing_address[:city]
85
+ post[:state] = billing_address[:state]
86
+ post[:zip] = billing_address[:zip]
87
+ post[:country] = billing_address[:country]
88
+ end
89
+ end
90
+
91
+ def add_invoice(post, options)
92
+ post[:trackid] = rand(Time.now)
93
+ end
94
+
95
+ def add_creditcard(post, creditcard)
96
+ post[:member] = creditcard.first_name.to_s + " " + creditcard.last_name.to_s
97
+ post[:card] = creditcard.number
98
+ post[:exp] = expdate(creditcard)
99
+ end
100
+
101
+ def expdate(credit_card)
102
+ year = sprintf("%.4i", credit_card.year)
103
+ month = sprintf("%.2i", credit_card.month)
104
+
105
+ "#{month}#{year[-2..-1]}"
106
+ end
107
+
108
+ def add_credit_data(post, transaction_id)
109
+ post[:transid] = transaction_id
110
+ end
111
+
112
+ def add_void_data(post, options)
113
+ post[:transid] = options[:transactionid]
114
+ end
115
+
116
+ def commit(action, money, post)
117
+ response = parse( ssl_post(test? ? TEST_URL : LIVE_URL, post_data(action, post, money)) )
118
+
119
+ Response.new(response[:response] == 'CAPTURED', response[:message], response,
120
+ :test => test?,
121
+ :authorization => response[:authorization],
122
+ :avs_result => { :code => response[:avsresponse] },
123
+ :cvv_result => response[:cvvresponse])
124
+ end
125
+
126
+ def parse(body)
127
+ response = {}
128
+
129
+ # check for an error first
130
+ if body.include?('!ERROR!')
131
+ response[:response] = 'ERROR'
132
+ response[:message] = error_message_from(body)
133
+ else
134
+ # a capture / not captured response will be : delimited
135
+ split = body.split(':')
136
+ response[:response] = split[0]
137
+
138
+ # FirstPay docs are worthless. turns out the transactionid is required for credits
139
+ # so we need to store that in authorization, not the actual auth.
140
+ if response[:response] == 'CAPTURED'
141
+ response[:message] = 'CAPTURED'
142
+ response[:authorization] = split[9] # actually the transactionid
143
+ response[:auth] = split[1]
144
+ response[:avsresponse] = split[3]
145
+ response[:cvvresponse] = split[17]
146
+ else
147
+ # NOT CAPTURED response
148
+ response[:message] = split[1]
149
+ response[:transactionid] = split[9]
150
+ end
151
+ end
152
+
153
+ return response
154
+ end
155
+
156
+ def error_message_from(response)
157
+ # error messages use this format - '!ERROR! 704-MISSING BASIC DATA TYPE:card, exp, zip, addr, member, amount\n'
158
+ response.split("! ")[1].chomp
159
+ end
160
+
161
+ def post_data(action, post, money)
162
+ post[:vid] = @options[:login]
163
+ post[:password] = @options[:password]
164
+ post[:action] = ACTIONS[action]
165
+ post[:amount] = amount(money)
166
+
167
+ return post.to_post_data
168
+ end
169
+ end
170
+ end
171
+ end
172
+
@@ -0,0 +1,164 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class InstapayGateway < Gateway
4
+ GATEWAY_URL = 'https://trans.instapaygateway.com/cgi-bin/process.cgi'
5
+
6
+ # The countries the gateway supports merchants from as 2 digit ISO country codes
7
+ self.supported_countries = ['US']
8
+ self.money_format = :dollars
9
+ self.default_currency = 'USD'
10
+ # The card types supported by the payment gateway
11
+ self.supported_cardtypes = [:visa, :master, :american_express, :discover]
12
+
13
+ # The homepage URL of the gateway
14
+ self.homepage_url = 'http://www.instapayllc.com'
15
+
16
+ # The name of the gateway
17
+ self.display_name = 'InstaPay'
18
+
19
+ SUCCESS = "Accepted"
20
+ SUCCESS_MESSAGE = "The transaction has been approved"
21
+
22
+ def initialize(options = {})
23
+ requires!(options, :login)
24
+ @options = options
25
+ super
26
+ end
27
+
28
+ def authorize(money, creditcard, options = {})
29
+ post = {}
30
+ post[:authonly] = 1
31
+ add_amount(post, money)
32
+ add_invoice(post, options)
33
+ add_creditcard(post, creditcard)
34
+ add_address(post, options)
35
+ add_customer_data(post, options)
36
+
37
+ commit('ns_quicksale_cc', post)
38
+ end
39
+
40
+ def purchase(money, creditcard, options = {})
41
+ post = {}
42
+ add_amount(post, money)
43
+ add_invoice(post, options)
44
+ add_creditcard(post, creditcard)
45
+ add_address(post, options)
46
+ add_customer_data(post, options)
47
+
48
+ commit('ns_quicksale_cc', post)
49
+ end
50
+
51
+ def capture(money, authorization, options = {})
52
+ post = {}
53
+ add_amount(post, money)
54
+ add_reference(post, authorization)
55
+ commit('ns_quicksale_cc', post)
56
+ end
57
+
58
+ private
59
+
60
+ def add_amount(post, money)
61
+ post[:amount] = amount(money)
62
+ end
63
+
64
+ def add_reference(post, reference)
65
+ post[:postonly] = reference
66
+ end
67
+
68
+ def add_customer_data(post, options)
69
+ post[:ci_email] = options[:email]
70
+ post["ci_IP Address"] = options[:ip]
71
+ end
72
+
73
+ def add_address(post, options)
74
+ if address = options[:billing_address] || options[:address]
75
+ post[:ci_billaddr1] = address[:address1]
76
+ post[:ci_billaddr2] = address[:address2]
77
+ post[:ci_billcity] = address[:city]
78
+ post[:ci_billstate] = address[:state]
79
+ post[:ci_billzip] = address[:zip]
80
+ post[:ci_billcountry] = address[:country]
81
+ post[:ci_phone] = address[:phone]
82
+ end
83
+
84
+ if address = options[:shipping_address]
85
+ post[:ci_shipaddr1] = address[:address1]
86
+ post[:ci_shipaddr2] = address[:address2]
87
+ post[:ci_shipcity] = address[:city]
88
+ post[:ci_shipstate] = address[:state]
89
+ post[:ci_shipzip] = address[:zip]
90
+ post[:ci_shipcountry] = address[:country]
91
+ end
92
+ end
93
+
94
+ def add_invoice(post, options)
95
+ post[:merchantordernumber] = options[:order_id]
96
+ post[:ci_memo] = options[:description]
97
+ post[:pocustomerrefid] = options[:invoice]
98
+ end
99
+
100
+ def add_creditcard(post, creditcard)
101
+ post[:ccnum] = creditcard.number
102
+ post[:expmon] = format(creditcard.month, :two_digits)
103
+ post[:cvv2] = creditcard.verification_value if creditcard.verification_value?
104
+ post[:expyear] = creditcard.year
105
+ post[:ccname] = creditcard.name
106
+ end
107
+
108
+ def parse(body)
109
+ results = {}
110
+ fields = body.split("\r\n")
111
+
112
+ response = fields[1].split('=')
113
+ response_data = response[1].split(':')
114
+
115
+ if response[0] == SUCCESS
116
+ results[:success] = true
117
+ results[:message] = SUCCESS_MESSAGE
118
+ results[:transaction_type] = response_data[0]
119
+ results[:authorization_code] = response_data[1]
120
+ results[:reference_number] = response_data[2]
121
+ results[:batch_number] = response_data[3]
122
+ results[:transaction_id] = response_data[4]
123
+ results[:avs_result] = response_data[5]
124
+ results[:authorize_net] = response_data[6]
125
+ results[:cvv_result] = response_data[7]
126
+ else
127
+ results[:success] = false
128
+ results[:result] = response_data[0]
129
+ results[:response_code] = response_data[1]
130
+ results[:message] = response_data[2]
131
+ end
132
+
133
+ fields[1..-1].each do |pair|
134
+ key, value = pair.split('=')
135
+ results[key] = value
136
+ end
137
+ results
138
+ end
139
+
140
+ def commit(action, parameters)
141
+ data = ssl_post GATEWAY_URL , post_data(action, parameters)
142
+ response = parse(data)
143
+
144
+ Response.new(response[:success] , response[:message], response,
145
+ :authorization => response[:transaction_id],
146
+ :avs_result => { :code => response[:avs_result] },
147
+ :cvv_result => response[:cvv_result]
148
+ )
149
+ end
150
+
151
+ def post_data(action, parameters = {})
152
+ post = {}
153
+ post[:acctid] = @options[:login]
154
+ if(@options[:password])
155
+ post[:merchantpin] = @options[:password]
156
+ end
157
+ post[:action] = action
158
+ request = post.merge(parameters).collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
159
+ request
160
+ end
161
+ end
162
+ end
163
+ end
164
+