activemerchant 1.25.0 → 1.26.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,213 @@
1
+ module ActiveMerchant
2
+ module Billing
3
+ class PaywayGateway < Gateway
4
+ URL = 'https://ccapi.client.qvalent.com/payway/ccapi'
5
+
6
+ self.supported_countries = [ 'AU' ]
7
+ self.supported_cardtypes = [ :visa, :master, :diners_club, :american_express, :bankcard ]
8
+ self.display_name = 'Pay Way'
9
+ self.homepage_url = 'http://www.payway.com.au'
10
+ self.default_currency = 'AUD'
11
+ self.money_format = :cents
12
+
13
+ SUMMARY_CODES = {
14
+ '0' => 'Approved',
15
+ '1' => 'Declined',
16
+ '2' => 'Erred',
17
+ '3' => 'Rejected'
18
+ }
19
+
20
+ RESPONSE_CODES= {
21
+ '00' => 'Completed Successfully',
22
+ '01' => 'Refer to card issuer',
23
+ '03' => 'Invalid merchant',
24
+ '04' => 'Pick-up card',
25
+ '05' => 'Do not honour',
26
+ '08' => 'Honour only with identification',
27
+ '12' => 'Invalid transaction',
28
+ '13' => 'Invalid amount',
29
+ '14' => 'Invalid card number (no such number)',
30
+ '30' => 'Format error',
31
+ '36' => 'Restricted card',
32
+ '41' => 'Lost card',
33
+ '42' => 'No universal card',
34
+ '43' => 'Stolen card',
35
+ '51' => 'Not sufficient funds',
36
+ '54' => 'Expired card',
37
+ '61' => 'Exceeds withdrawal amount limits',
38
+ '62' => 'Restricted card',
39
+ '65' => 'Exceeds withdrawal frequency limit',
40
+ '91' => 'Issuer or switch is inoperative',
41
+ '92' => 'Financial institution or intermediate network facility cannot be found for routing',
42
+ '94' => 'Duplicate transmission',
43
+ 'Q1' => 'Unknown Buyer',
44
+ 'Q2' => 'Transaction Pending',
45
+ 'Q3' => 'Payment Gateway Connection Error',
46
+ 'Q4' => 'Payment Gateway Unavailable',
47
+ 'Q5' => 'Invalid Transaction',
48
+ 'Q6' => 'Duplicate Transaction - requery to determine status',
49
+ 'QA' => 'Invalid parameters or Initialisation failed',
50
+ 'QB' => 'Order type not currently supported',
51
+ 'QC' => 'Invalid Order Type',
52
+ 'QD' => 'Invalid Payment Amount - Payment amount less than minimum/exceeds maximum allowed limit',
53
+ 'QE' => 'Internal Error',
54
+ 'QF' => 'Transaction Failed',
55
+ 'QG' => 'Unknown Customer Order Number',
56
+ 'QH' => 'Unknown Customer Username or Password',
57
+ 'QI' => 'Transaction incomplete - contact Westpac to confirm reconciliation',
58
+ 'QJ' => 'Invalid Client Certificate',
59
+ 'QK' => 'Unknown Customer Merchant',
60
+ 'QL' => 'Business Group not configured for customer',
61
+ 'QM' => 'Payment Instrument not configured for customer',
62
+ 'QN' => 'Configuration Error',
63
+ 'QO' => 'Missing Payment Instrument',
64
+ 'QP' => 'Missing Supplier Account',
65
+ 'QQ' => 'Invalid Credit Card Verification Number',
66
+ 'QR' => 'Transaction Retry',
67
+ 'QS' => 'Transaction Successful',
68
+ 'QT' => 'Invalid currency',
69
+ 'QU' => 'Unknown Customer IP Address',
70
+ 'QV' => 'Invalid Original Order Number specified for Refund, Refund amount exceeds capture amount, or Previous capture was not approved',
71
+ 'QW' => 'Invalid Reference Number',
72
+ 'QX' => 'Network Error has occurred',
73
+ 'QY' => 'Card Type Not Accepted',
74
+ 'QZ' => 'Zero value transaction'
75
+ }
76
+
77
+ TRANSACTIONS = {
78
+ :authorize => 'preauth',
79
+ :purchase => 'capture',
80
+ :capture => 'captureWithoutAuth',
81
+ :status => 'query',
82
+ :refund => 'refund',
83
+ :store => 'registerAccount'
84
+ }
85
+
86
+ def initialize(options={})
87
+ @options = options
88
+
89
+ options[:merchant] ||= 'TEST' if test?
90
+
91
+ requires!(options, :username, :password, :merchant, :pem)
92
+
93
+ @options[:eci] ||= 'SSL'
94
+
95
+ super
96
+ end
97
+
98
+ def authorize(amount, payment_method, options={})
99
+ requires!(options, :order_id)
100
+
101
+ post = {}
102
+ add_payment_method(post, payment_method)
103
+ add_order(post, amount, options)
104
+ commit(:authorize, post)
105
+ end
106
+
107
+ def capture(amount, authorization, options={})
108
+ requires!(options, :order_id)
109
+
110
+ post = {}
111
+ add_reference(post, authorization)
112
+ add_order(post, amount, options)
113
+ commit(:capture, post)
114
+ end
115
+
116
+ def purchase(amount, payment_method, options={})
117
+ requires!(options, :order_id)
118
+
119
+ post = {}
120
+ add_payment_method(post, payment_method)
121
+ add_order(post, amount, options)
122
+ commit(:purchase, post)
123
+ end
124
+
125
+ def refund(amount, authorization, options={})
126
+ requires!(options, :order_id)
127
+
128
+ post = {}
129
+ add_reference(post, authorization)
130
+ add_order(post, amount, options)
131
+ commit(:refund, post)
132
+ end
133
+
134
+ def store(credit_card, options={})
135
+ requires!(options, :billing_id)
136
+
137
+ post = {}
138
+ add_payment_method(post, credit_card)
139
+ commit(:store, post)
140
+ end
141
+
142
+ def status(options={})
143
+ requires!(options, :order_id)
144
+
145
+ commit(:status, 'customer.orderNumber' => options[:order_id])
146
+ end
147
+
148
+ private
149
+
150
+ def add_payment_method(post, payment_method)
151
+ if payment_method.respond_to?(:number)
152
+ post['card.cardHolderName'] = "#{payment_method.first_name} #{payment_method.last_name}"
153
+ post['card.PAN'] = payment_method.number
154
+ post['card.CVN'] = payment_method.verification_value
155
+ post['card.expiryYear'] = payment_method.year.to_s[-2,2]
156
+ post['card.expiryMonth'] = sprintf('%02d', payment_method.month)
157
+ else
158
+ post['customer.customerReferenceNumber'] = payment_method
159
+ end
160
+ end
161
+
162
+ def add_reference(post, reference)
163
+ post['customer.originalOrderNumber'] = reference
164
+ end
165
+
166
+ def add_order(post, amount, options)
167
+ post['order.ECI'] = @options[:eci]
168
+ post['order.amount'] = amount
169
+ post['card.currency'] = (options[:currency] || currency(amount))
170
+ post['customer.orderNumber'] = options[:order_id][0...20]
171
+ end
172
+
173
+ def add_auth(post)
174
+ post['customer.username'] = @options[:username]
175
+ post['customer.password'] = @options[:password]
176
+ post['customer.merchant'] = @options[:merchant]
177
+ end
178
+
179
+ # Creates the request and returns the summarized result
180
+ def commit(action, post)
181
+ add_auth(post)
182
+ post.merge!('order.type' => TRANSACTIONS[action])
183
+
184
+ request = post.map { |k, v| "#{k}=#{CGI.escape(v.to_s)}" }.join("&")
185
+ response = ssl_post(URL, request)
186
+
187
+ params = {}
188
+ CGI.parse(response).each_pair do |key, value|
189
+ actual_key = key.split(".").last
190
+ params[actual_key.underscore.to_sym] = value[0]
191
+ end
192
+
193
+ message = "#{SUMMARY_CODES[params[:summary_code]]} - #{RESPONSE_CODES[params[:response_code]]}"
194
+
195
+ success = (params[:summary_code] ? (params[:summary_code] == "0") : (params[:response_code] == "00"))
196
+
197
+ Response.new(success, message, params,
198
+ :test => (@options[:merchant].to_s == "TEST"),
199
+ :authorization => post[:order_number]
200
+ )
201
+ rescue ActiveMerchant::ResponseError => e
202
+ raise unless e.response.code == '403'
203
+ return Response.new(false, "Invalid credentials", {}, :test => test?)
204
+ rescue ActiveMerchant::ClientCertificateError
205
+ return Response.new(false, "Invalid certificate", {}, :test => test?)
206
+ end
207
+
208
+ def test?
209
+ (@options[:test] || super)
210
+ end
211
+ end
212
+ end
213
+ end
@@ -25,10 +25,10 @@ module ActiveMerchant #:nodoc:
25
25
  end
26
26
 
27
27
  def purchase(money, payment_method, options = {})
28
- response = MultiResponse.new
29
- response << authorize(money, payment_method, options)
30
- response << capture(money, response.authorization, options.merge(:authorization_validated => true)) if response.success?
31
- response
28
+ MultiResponse.new.tap do |r|
29
+ r.process{authorize(money, payment_method, options)}
30
+ r.process{capture(money, r.authorization, options.merge(:authorization_validated => true))}
31
+ end
32
32
  end
33
33
 
34
34
  def authorize(money, payment_method, options = {})
@@ -37,30 +37,30 @@ module ActiveMerchant #:nodoc:
37
37
  end
38
38
 
39
39
  def capture(money, authorization, options = {})
40
- response = MultiResponse.new
41
- response << inquire(authorization, options) unless options[:authorization_validated]
42
- response << commit('capture', build_capture_request(money, authorization, options)) if response.success?
43
- response
40
+ MultiResponse.new.tap do |r|
41
+ r.process{inquire(authorization, options)} unless options[:authorization_validated]
42
+ r.process{commit('capture', build_capture_request(money, authorization, options))}
43
+ end
44
44
  end
45
45
 
46
46
  def void(authorization, options = {})
47
- response = MultiResponse.new
48
- response << inquire(authorization, options)
49
- response << commit('cancel', build_void_request(authorization, options)) if response.success?
50
- response
47
+ MultiResponse.new.tap do |r|
48
+ r.process{inquire(authorization, options)}
49
+ r.process{commit('cancel', build_void_request(authorization, options))}
50
+ end
51
51
  end
52
52
 
53
53
  def refund(money, authorization, options = {})
54
- response = MultiResponse.new
55
- response << inquire(authorization, options)
56
- response << commit('refund', build_refund_request(money, authorization, options)) if response.success?
57
- response
54
+ MultiResponse.new.tap do |r|
55
+ r.process{inquire(authorization, options)}
56
+ r.process{commit('refund', build_refund_request(money, authorization, options))}
57
+ end
58
58
  end
59
59
 
60
60
  private
61
61
 
62
62
  def inquire(authorization, options={})
63
- commit 'inquiry', build_order_inquiry_request(authorization, options)
63
+ commit('inquiry', build_order_inquiry_request(authorization, options))
64
64
  end
65
65
 
66
66
  def build_request
@@ -247,34 +247,6 @@ module ActiveMerchant #:nodoc:
247
247
  credentials = "#{@options[:login]}:#{@options[:password]}"
248
248
  "Basic #{[credentials].pack('m').strip}"
249
249
  end
250
-
251
- class MultiResponse < Response
252
- attr_reader :responses
253
-
254
- def initialize
255
- @responses = []
256
- end
257
-
258
- def <<(response)
259
- if response.is_a?(MultiResponse)
260
- response.responses.each{|r| @responses << r}
261
- else
262
- @responses << response
263
- end
264
- end
265
-
266
- def success?
267
- @responses.all?{|r| r.success?}
268
- end
269
-
270
- %w(params message test authorization avs_result cvv_result test? fraud_review?).each do |m|
271
- class_eval %(
272
- def #{m}
273
- @responses.last.#{m}
274
- end
275
- )
276
- end
277
- end
278
250
  end
279
251
  end
280
252
  end
@@ -1,12 +1,12 @@
1
1
  module ActiveMerchant #:nodoc:
2
2
  module Billing #:nodoc:
3
-
3
+
4
4
  class Error < ActiveMerchantError #:nodoc:
5
5
  end
6
-
6
+
7
7
  class Response
8
8
  attr_reader :params, :message, :test, :authorization, :avs_result, :cvv_result
9
-
9
+
10
10
  def success?
11
11
  @success
12
12
  end
@@ -14,19 +14,51 @@ module ActiveMerchant #:nodoc:
14
14
  def test?
15
15
  @test
16
16
  end
17
-
17
+
18
18
  def fraud_review?
19
19
  @fraud_review
20
20
  end
21
-
21
+
22
22
  def initialize(success, message, params = {}, options = {})
23
23
  @success, @message, @params = success, message, params.stringify_keys
24
- @test = options[:test] || false
24
+ @test = options[:test] || false
25
25
  @authorization = options[:authorization]
26
26
  @fraud_review = options[:fraud_review]
27
27
  @avs_result = AVSResult.new(options[:avs_result]).to_hash
28
28
  @cvv_result = CVVResult.new(options[:cvv_result]).to_hash
29
29
  end
30
30
  end
31
+
32
+ class MultiResponse < Response
33
+ attr_reader :responses
34
+
35
+ def initialize
36
+ @responses = []
37
+ end
38
+
39
+ def process
40
+ self << yield if(responses.empty? || success?)
41
+ end
42
+
43
+ def <<(response)
44
+ if response.is_a?(MultiResponse)
45
+ response.responses.each{|r| @responses << r}
46
+ else
47
+ @responses << response
48
+ end
49
+ end
50
+
51
+ def success?
52
+ @responses.all?{|r| r.success?}
53
+ end
54
+
55
+ %w(params message test authorization avs_result cvv_result test? fraud_review?).each do |m|
56
+ class_eval %(
57
+ def #{m}
58
+ @responses.last.#{m}
59
+ end
60
+ )
61
+ end
62
+ end
31
63
  end
32
64
  end
@@ -1,3 +1,3 @@
1
1
  module ActiveMerchant
2
- VERSION = "1.25.0"
2
+ VERSION = "1.26.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activemerchant
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.25.0
4
+ version: 1.26.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -50,11 +50,11 @@ cert_chain:
50
50
  -----END CERTIFICATE-----
51
51
 
52
52
  '
53
- date: 2012-07-03 00:00:00.000000000 Z
53
+ date: 2012-07-06 00:00:00.000000000 Z
54
54
  dependencies:
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: activesupport
57
- requirement: &70187328041800 !ruby/object:Gem::Requirement
57
+ requirement: &70187310316020 !ruby/object:Gem::Requirement
58
58
  none: false
59
59
  requirements:
60
60
  - - ! '>='
@@ -62,10 +62,10 @@ dependencies:
62
62
  version: 2.3.11
63
63
  type: :runtime
64
64
  prerelease: false
65
- version_requirements: *70187328041800
65
+ version_requirements: *70187310316020
66
66
  - !ruby/object:Gem::Dependency
67
67
  name: i18n
68
- requirement: &70187328041340 !ruby/object:Gem::Requirement
68
+ requirement: &70187310315600 !ruby/object:Gem::Requirement
69
69
  none: false
70
70
  requirements:
71
71
  - - ! '>='
@@ -73,10 +73,10 @@ dependencies:
73
73
  version: '0'
74
74
  type: :runtime
75
75
  prerelease: false
76
- version_requirements: *70187328041340
76
+ version_requirements: *70187310315600
77
77
  - !ruby/object:Gem::Dependency
78
78
  name: money
79
- requirement: &70187328040860 !ruby/object:Gem::Requirement
79
+ requirement: &70187310315080 !ruby/object:Gem::Requirement
80
80
  none: false
81
81
  requirements:
82
82
  - - ! '>='
@@ -84,10 +84,10 @@ dependencies:
84
84
  version: '0'
85
85
  type: :runtime
86
86
  prerelease: false
87
- version_requirements: *70187328040860
87
+ version_requirements: *70187310315080
88
88
  - !ruby/object:Gem::Dependency
89
89
  name: builder
90
- requirement: &70187328040200 !ruby/object:Gem::Requirement
90
+ requirement: &70187310314540 !ruby/object:Gem::Requirement
91
91
  none: false
92
92
  requirements:
93
93
  - - ! '>='
@@ -95,10 +95,10 @@ dependencies:
95
95
  version: 2.0.0
96
96
  type: :runtime
97
97
  prerelease: false
98
- version_requirements: *70187328040200
98
+ version_requirements: *70187310314540
99
99
  - !ruby/object:Gem::Dependency
100
100
  name: json
101
- requirement: &70187328039620 !ruby/object:Gem::Requirement
101
+ requirement: &70187310314040 !ruby/object:Gem::Requirement
102
102
  none: false
103
103
  requirements:
104
104
  - - ! '>='
@@ -106,10 +106,10 @@ dependencies:
106
106
  version: 1.5.1
107
107
  type: :runtime
108
108
  prerelease: false
109
- version_requirements: *70187328039620
109
+ version_requirements: *70187310314040
110
110
  - !ruby/object:Gem::Dependency
111
111
  name: active_utils
112
- requirement: &70187328039080 !ruby/object:Gem::Requirement
112
+ requirement: &70187310313420 !ruby/object:Gem::Requirement
113
113
  none: false
114
114
  requirements:
115
115
  - - ! '>='
@@ -117,10 +117,10 @@ dependencies:
117
117
  version: 1.0.2
118
118
  type: :runtime
119
119
  prerelease: false
120
- version_requirements: *70187328039080
120
+ version_requirements: *70187310313420
121
121
  - !ruby/object:Gem::Dependency
122
122
  name: nokogiri
123
- requirement: &70187328038600 !ruby/object:Gem::Requirement
123
+ requirement: &70187310313040 !ruby/object:Gem::Requirement
124
124
  none: false
125
125
  requirements:
126
126
  - - ! '>='
@@ -128,10 +128,10 @@ dependencies:
128
128
  version: '0'
129
129
  type: :runtime
130
130
  prerelease: false
131
- version_requirements: *70187328038600
131
+ version_requirements: *70187310313040
132
132
  - !ruby/object:Gem::Dependency
133
133
  name: rake
134
- requirement: &70187328038140 !ruby/object:Gem::Requirement
134
+ requirement: &70187310312580 !ruby/object:Gem::Requirement
135
135
  none: false
136
136
  requirements:
137
137
  - - ! '>='
@@ -139,10 +139,10 @@ dependencies:
139
139
  version: '0'
140
140
  type: :development
141
141
  prerelease: false
142
- version_requirements: *70187328038140
142
+ version_requirements: *70187310312580
143
143
  - !ruby/object:Gem::Dependency
144
144
  name: mocha
145
- requirement: &70187328037540 !ruby/object:Gem::Requirement
145
+ requirement: &70187310311940 !ruby/object:Gem::Requirement
146
146
  none: false
147
147
  requirements:
148
148
  - - ~>
@@ -150,10 +150,10 @@ dependencies:
150
150
  version: 0.11.3
151
151
  type: :development
152
152
  prerelease: false
153
- version_requirements: *70187328037540
153
+ version_requirements: *70187310311940
154
154
  - !ruby/object:Gem::Dependency
155
155
  name: rails
156
- requirement: &70187328037020 !ruby/object:Gem::Requirement
156
+ requirement: &70187310311420 !ruby/object:Gem::Requirement
157
157
  none: false
158
158
  requirements:
159
159
  - - ! '>='
@@ -161,10 +161,10 @@ dependencies:
161
161
  version: 2.3.11
162
162
  type: :development
163
163
  prerelease: false
164
- version_requirements: *70187328037020
164
+ version_requirements: *70187310311420
165
165
  - !ruby/object:Gem::Dependency
166
166
  name: rubigen
167
- requirement: &70187328052900 !ruby/object:Gem::Requirement
167
+ requirement: &70187310311040 !ruby/object:Gem::Requirement
168
168
  none: false
169
169
  requirements:
170
170
  - - ! '>='
@@ -172,7 +172,7 @@ dependencies:
172
172
  version: '0'
173
173
  type: :development
174
174
  prerelease: false
175
- version_requirements: *70187328052900
175
+ version_requirements: *70187310311040
176
176
  description: Active Merchant is a simple payment abstraction library used in and sponsored
177
177
  by Shopify. It is written by Tobias Luetke, Cody Fauser, and contributors. The aim
178
178
  of the project is to feel natural to Ruby users and to abstract as many parts as
@@ -253,6 +253,7 @@ files:
253
253
  - lib/active_merchant/billing/gateways/optimal_payment.rb
254
254
  - lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb
255
255
  - lib/active_merchant/billing/gateways/orbital.rb
256
+ - lib/active_merchant/billing/gateways/pay_gate_xml.rb
256
257
  - lib/active_merchant/billing/gateways/pay_junction.rb
257
258
  - lib/active_merchant/billing/gateways/pay_secure.rb
258
259
  - lib/active_merchant/billing/gateways/paybox_direct.rb
@@ -273,6 +274,7 @@ files:
273
274
  - lib/active_merchant/billing/gateways/paypal_express.rb
274
275
  - lib/active_merchant/billing/gateways/paypal_express_common.rb
275
276
  - lib/active_merchant/billing/gateways/paystation.rb
277
+ - lib/active_merchant/billing/gateways/payway.rb
276
278
  - lib/active_merchant/billing/gateways/plugnpay.rb
277
279
  - lib/active_merchant/billing/gateways/psigate.rb
278
280
  - lib/active_merchant/billing/gateways/psl_card.rb
@@ -423,7 +425,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
423
425
  version: '0'
424
426
  segments:
425
427
  - 0
426
- hash: 3496413810224124962
428
+ hash: -327085391244042374
427
429
  required_rubygems_version: !ruby/object:Gem::Requirement
428
430
  none: false
429
431
  requirements:
@@ -432,7 +434,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
432
434
  version: '0'
433
435
  segments:
434
436
  - 0
435
- hash: 3496413810224124962
437
+ hash: -327085391244042374
436
438
  requirements: []
437
439
  rubyforge_project: activemerchant
438
440
  rubygems_version: 1.8.11