activemerchant_paybox_direct_plus 0.2.0 → 1.0.0

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.
@@ -2,220 +2,140 @@ require 'active_merchant'
2
2
 
3
3
  module ActiveMerchant #:nodoc:
4
4
  module Billing #:nodoc:
5
- class PayboxDirectPlusGateway < Gateway
6
- TEST_URL = 'https://preprod-ppps.paybox.com/PPPS.php'
7
- TEST_URL_BACKUP = 'https://preprod-ppps.paybox.com/PPPS.php'
8
- LIVE_URL = 'https://ppps.paybox.com/PPPS.php'
9
- LIVE_URL_BACKUP = 'https://ppps1.paybox.com/PPPS.php'
10
-
5
+ class PayboxDirectPlusGateway < PayboxDirectGateway
11
6
  # Payment API Version
12
7
  API_VERSION = '00104'
13
8
 
14
9
  # Transactions hash
15
10
  TRANSACTIONS = {
16
- :subscriber_authorization => '00051',
17
- :subscriber_capture => '00052',
18
- :subscriber_purchase => '00053',
19
- :subscriber_credit => '00054',
20
- :subscriber_void => '00055',
21
- :subscriber_create => '00056',
22
- :subscriber_update => '00057',
23
- :subscriber_destroy => '00058',
24
- }
25
-
26
- CURRENCY_CODES = {
27
- "AUD"=> '036',
28
- "CAD"=> '124',
29
- "CZK"=> '203',
30
- "DKK"=> '208',
31
- "HKD"=> '344',
32
- "ICK"=> '352',
33
- "JPY"=> '392',
34
- "NOK"=> '578',
35
- "SGD"=> '702',
36
- "SEK"=> '752',
37
- "CHF"=> '756',
38
- "GBP"=> '826',
39
- "USD"=> '840',
40
- "EUR"=> '978'
11
+ authorization: '00001',
12
+ capture: '00002',
13
+ purchase: '00003',
14
+ unreferenced_credit: '00004',
15
+ void: '00005',
16
+ refund: '00014',
17
+ subscriber_authorization: '00051',
18
+ subscriber_capture: '00052',
19
+ subscriber_purchase: '00053',
20
+ subscriber_credit: '00054',
21
+ subscriber_refund: '00014',
22
+ subscriber_void: '00055',
23
+ subscriber_create: '00056',
24
+ subscriber_update: '00057',
25
+ subscriber_destroy: '00058'
41
26
  }
42
27
 
43
28
  ALREADY_EXISTING_PROFILE_CODES = ['00016']
44
29
  UNKNOWN_PROFILE_CODES = ['00017']
45
- SUCCESS_CODES = ['00000']
46
- UNAVAILABILITY_CODES = ['00001', '00097', '00098']
47
- FRAUD_CODES = ['00102','00104','00105','00134','00138','00141','00143','00156','00157','00159']
48
- SUCCESS_MESSAGE = 'The transaction was approved'
49
- FAILURE_MESSAGE = 'The transaction failed'
50
-
51
- # Money is referenced in cents
52
- self.money_format = :cents
53
- self.default_currency = 'EUR'
54
-
55
- # The countries the gateway supports merchants from as 2 digit ISO country codes
56
- self.supported_countries = ['FR']
57
-
58
- # The card types supported by the payment gateway
59
- self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :jcb]
60
-
61
- # The homepage URL of the gateway
62
- self.homepage_url = 'http://www.paybox.com/'
30
+ FRAUD_CODES = %w(00102 00104 00105 00134 00138 00141 00143 00156 00157 00159)
63
31
 
64
32
  # The name of the gateway
65
33
  self.display_name = 'Paybox Direct Plus'
66
34
 
67
- def initialize(options = {})
68
- requires!(options, :login, :password)
69
- @options = options
70
- super
71
- end
72
-
73
35
  def payment_profiles_supported?
74
36
  true
75
37
  end
76
38
 
77
- def authorize(money, creditcard, options = {})
39
+ def subscriber_authorize(money, creditcard, options = {})
78
40
  requires!(options, :user_reference)
79
41
  post = {}
80
42
  add_invoice(post, options)
81
43
  add_creditcard(post, creditcard, options)
82
44
  add_user_reference(post, options)
45
+ add_amount(post, money, options)
83
46
  commit('subscriber_authorization', money, post)
84
47
  end
85
48
 
86
- def purchase(money, creditcard, options = {})
49
+ def subscriber_purchase(money, creditcard, options = {})
87
50
  requires!(options, :credit_card_reference, :user_reference)
88
51
  post = {}
89
52
  add_invoice(post, options)
90
53
  add_creditcard(post, creditcard, options)
91
54
  add_user_reference(post, options)
55
+ add_amount(post, money, options)
92
56
  commit('subscriber_purchase', money, post)
93
57
  end
94
58
 
95
- def capture(money, authorization, options = {})
59
+ def subscriber_capture(money, authorization, options = {})
96
60
  requires!(options, :order_id, :user_reference)
97
61
  post = {}
98
62
  add_invoice(post, options)
99
63
  add_reference(post, authorization)
100
64
  add_user_reference(post, options)
65
+ add_amount(post, money, options)
101
66
  commit('subscriber_capture', money, post)
102
67
  end
103
68
 
104
- def void(money, authorization, options = {})
69
+ def subscriber_void(money, authorization, options = {})
105
70
  requires!(options, :order_id, :user_reference)
106
71
  post = {}
107
72
  add_invoice(post, options)
108
73
  add_reference(post, authorization)
109
74
  add_user_reference(post, options)
75
+ add_amount(post, money, options)
110
76
  post[:porteur] = '000000000000000'
111
77
  post[:dateval] = '0000'
112
78
  commit('subscriber_void', money, post)
113
79
  end
114
80
 
115
- def credit(money, identification, options = {})
81
+ def subscriber_credit(money, identification, options = {})
116
82
  post = {}
117
83
  add_invoice(post, options)
118
84
  add_reference(post, identification)
119
85
  add_user_reference(post, options)
86
+ add_amount(post, money, options)
120
87
  commit('subscriber_credit', money, post)
121
88
  end
122
89
 
123
- def create_payment_profile(money, creditcard, options = {})
90
+ def subscriber_refund(money, authorization, options = {})
91
+ post = {}
92
+ add_invoice(post, options)
93
+ add_reference(post, authorization)
94
+ add_user_reference(post, options)
95
+ add_amount(post, money, options)
96
+ commit('subscriber_refund', money, post)
97
+ end
98
+
99
+ def subscriber_create(money, creditcard, options = {})
124
100
  requires!(options, :user_reference)
125
101
  post = {}
126
102
  add_creditcard(post, creditcard, options)
127
103
  add_user_reference(post, options)
104
+ add_amount(post, money, options)
128
105
  commit('subscriber_create', money, post)
129
106
  end
130
107
 
131
- def update_payment_profile(money, creditcard, options = {})
108
+ def subscriber_update(money, creditcard, options = {})
132
109
  post = {}
133
110
  add_creditcard(post, creditcard, options)
134
111
  add_user_reference(post, options)
112
+ add_amount(post, money, options)
135
113
  commit('subscriber_update', money, post)
136
114
  end
137
115
 
138
- def destroy_payment_profile(money, options)
116
+ def subscriber_destroy(money, options)
139
117
  post = {}
140
118
  add_user_reference(post, options)
119
+ add_amount(post, money, options)
141
120
  commit('subscriber_destroy', money, post)
142
121
  end
143
122
 
144
- def test?
145
- @options[:test] || Base.gateway_mode == :test
146
- end
147
-
148
123
  private
149
124
 
150
- def add_invoice(post, options)
151
- post[:reference] = options[:order_id]
152
- end
153
-
154
125
  def add_creditcard(post, creditcard, options = {})
155
- post[:porteur] = options[:credit_card_reference] ? options[:credit_card_reference] : creditcard.number
126
+ post[:porteur] = options[:credit_card_reference] || creditcard.number
156
127
  post[:dateval] = expdate(creditcard)
157
128
  post[:cvv] = creditcard.verification_value if creditcard.verification_value?
158
129
  end
159
-
130
+
160
131
  def add_user_reference(post, options)
161
132
  post[:refabonne] = options[:user_reference]
162
133
  end
163
-
164
- def add_reference(post, identification)
165
- post[:numappel] = identification[0,10]
166
- post[:numtrans] = identification[10,10]
167
- end
168
-
169
- def parse(body)
170
- if RUBY_VERSION < "1.9"
171
- require 'iconv'
172
- body = Iconv.iconv("UTF-8","LATIN1", body.to_s).join
173
- else
174
- body.encode!('UTF-8', Encoding::ISO_8859_1)
175
- end
176
- results = {}
177
- body.split(/&/).each do |pair|
178
- key,val = pair.split(/=/)
179
- results[key.downcase.to_sym] = CGI.unescape(val) if val
180
- end
181
- #Rails.logger.info results.inspect
182
- results
183
- end
184
-
185
- def commit(action, money = nil, parameters = nil)
186
- parameters[:montant] = ('0000000000' + (money ? amount(money) : ''))[-10..-1]
187
- parameters[:devise] = CURRENCY_CODES[options[:currency] || currency(money)]
188
- request_data = post_data(action,parameters)
189
- #debugger
190
- response = parse(ssl_post(test? ? TEST_URL : LIVE_URL, request_data))
191
- response = parse(ssl_post(test? ? TEST_URL_BACKUP : LIVE_URL_BACKUP, request_data)) if service_unavailable?(response)
192
- Response.new(success?(response), message_from(response), response.merge({
193
- :timestamp => parameters[:dateq],
194
- :test => test?,
195
- :authorization => response[:numappel].to_s + response[:numtrans].to_s,
196
- :cvv_result => '',
197
- :avs_result => '',
198
- :fraud_review => fraud_review?(response),
199
- :unknown_customer_profile => unknown_customer_profile?(response),
200
- :already_existing_customer_profile => already_existing_customer_profile?(response),
201
- :credit_card_reference => response[:porteur],
202
- :sent_params => parameters.delete_if{|key,value| ['porteur','dateval','cvv'].include?(key.to_s)}
203
- })
204
- )
205
- end
206
-
207
- def success?(response)
208
- SUCCESS_CODES.include?(response[:codereponse])
209
- end
210
134
 
211
135
  def fraud_review?(response)
212
136
  FRAUD_CODES.include?(response[:codereponse])
213
137
  end
214
138
 
215
- def service_unavailable?(response)
216
- UNAVAILABILITY_CODES.include?(response[:codereponse])
217
- end
218
-
219
139
  def unknown_customer_profile?(response)
220
140
  UNKNOWN_PROFILE_CODES.include?(response[:codereponse])
221
141
  end
@@ -224,47 +144,21 @@ module ActiveMerchant #:nodoc:
224
144
  ALREADY_EXISTING_PROFILE_CODES.include?(response[:codereponse])
225
145
  end
226
146
 
227
- def message_from(response)
228
- success?(response) ? SUCCESS_MESSAGE : (response[:commentaire] || FAILURE_MESSAGE)
229
- end
230
-
231
147
  def post_data(action, parameters = {})
232
-
233
148
  parameters.update(
234
- :version => API_VERSION,
235
- :type => TRANSACTIONS[action.to_sym],
236
- :dateq => Time.now.strftime('%d%m%Y%H%M%S'),
237
- :numquestion => unique_id(parameters[:reference]),
238
- :site => @options[:login].to_s[0,7],
239
- :rang => @options[:login].to_s[7..-1],
240
- :cle => @options[:password],
241
- :pays => '',
242
- :archivage => parameters[:reference]
149
+ version: API_VERSION,
150
+ type: TRANSACTIONS[action.to_sym],
151
+ dateq: Time.now.strftime('%d%m%Y%H%M%S'),
152
+ numquestion: unique_id(parameters[:order_id]),
153
+ site: @options[:login].to_s[0, 7],
154
+ rang: @options[:rang] || @options[:login].to_s[7..-1],
155
+ cle: @options[:password],
156
+ pays: '',
157
+ archivage: parameters[:reference]
243
158
  )
244
159
 
245
- p = parameters.collect { |key, value| "#{key.to_s.upcase}=#{CGI.escape(value.to_s)}" }.join("&")
246
- #Rails.logger.info "\n***************************"
247
- #Rails.logger.debug "********** POST DATA IN PAYBOX PLUS ***********"
248
- #Rails.logger.debug "*** Parameters for post data:"
249
- #Rails.logger.debug "#{p.inspect}"
250
- #Rails.logger.info "*****************************"
251
- p
252
- end
253
-
254
- def unique_id(seed = 0)
255
- randkey = "#{seed.hash}#{Time.now.usec}".to_i % 2147483647 # Max paybox value for the question number
256
-
257
- "0000000000#{randkey}"[-10..-1]
160
+ parameters.collect { |key, value| "#{key.to_s.upcase}=#{CGI.escape(value.to_s)}" }.join('&')
258
161
  end
259
-
260
- def expdate(credit_card)
261
- year = sprintf("%.4i", credit_card.year)
262
- month = sprintf("%.2i", credit_card.month)
263
-
264
- "#{month}#{year[-2..-1]}"
265
- end
266
-
267
162
  end
268
163
  end
269
164
  end
270
-
@@ -1,59 +1,96 @@
1
1
  require 'test_helper'
2
2
 
3
- class RemotePayboxDirectPlusTest < Test::Unit::TestCase
4
-
3
+ class RemotePayboxDirectTest < Minitest::Test
5
4
  def setup
6
- @gateway = PayboxDirectPlusGateway.new(fixtures(:paybox_direct_plus))
7
-
5
+ @gateway = ActiveMerchant::Billing::PayboxDirectPlusGateway.new(
6
+ login: '199988899',
7
+ password: '1999888I'
8
+ )
9
+
8
10
  @amount = 100
9
11
  @credit_card = credit_card('1111222233334444')
10
- @declined_card = credit_card('1111222233334445')
11
-
12
- @options = {
13
- :order_id => "REF#{Time.now.usec}",
14
- :user_reference => "USER#{Time.now.usec}"
12
+
13
+ @options = {
14
+ order_id: "REF#{Time.now.usec}",
15
+ user_reference: "USER#{Time.now.usec}"
15
16
  }
16
17
  end
17
-
18
+
18
19
  def test_create_profile
19
- assert response = @gateway.create_payment_profile(@amount, @credit_card, @options)
20
- assert_success response
20
+ assert response = @gateway.subscriber_create(@amount, @credit_card, @options)
21
+ assert response.success?
21
22
  assert_equal 'The transaction was approved', response.message
22
23
  end
23
-
24
+
24
25
  def test_create_profile_capture_and_void
25
- assert response = @gateway.create_payment_profile(@amount, @credit_card, @options)
26
- assert_success response
27
-
28
- credit_card_reference = response.params["credit_card_reference"]
29
- assert_not_nil credit_card_reference
30
-
31
- assert capture = @gateway.capture(@amount, response.params["authorization"], @options)
32
- assert_success capture
33
-
34
- assert void = @gateway.void(@amount, capture.params["authorization"], @options)
26
+ assert response = @gateway.subscriber_create(@amount, @credit_card, @options)
27
+ assert response.success?
28
+
29
+ credit_card_reference = response.params['porteur']
30
+ assert !credit_card_reference.nil?
31
+
32
+ assert capture = @gateway.subscriber_capture(@amount, response.authorization, @options)
33
+ assert capture.success?
34
+
35
+ assert void = @gateway.subscriber_void(@amount, capture.authorization, @options)
35
36
  assert_equal 'The transaction was approved', void.message
36
- assert_success void
37
+ assert void.success?
37
38
  end
38
-
39
+
39
40
  def test_create_profile_and_purchase
40
- assert response = @gateway.create_payment_profile(@amount, @credit_card, @options)
41
- assert_success response
42
-
43
- credit_card_reference = response.params["credit_card_reference"]
44
- assert_not_nil credit_card_reference
45
-
41
+ assert response = @gateway.subscriber_create(@amount, @credit_card, @options)
42
+ assert response.success?
43
+
44
+ credit_card_reference = response.params['porteur']
45
+ assert !credit_card_reference.nil?
46
+
46
47
  @credit_card.number = nil
47
-
48
- assert_response = @gateway.purchase(@amount, @credit_card, @options.merge({ :credit_card_reference => credit_card_reference }))
49
- assert_success response
50
- assert_equal 'The transaction was approved', response.message
48
+ @credit_card.first_name = nil
49
+ @credit_card.last_name = nil
50
+
51
+ assert success = @gateway.subscriber_purchase(@amount, @credit_card, @options.merge(credit_card_reference: credit_card_reference))
52
+ assert success.success?
53
+ assert_equal 'The transaction was approved', success.message
51
54
  end
52
-
55
+
56
+ def test_create_profile_capture_and_refund
57
+ assert response = @gateway.subscriber_create(@amount, @credit_card, @options)
58
+ assert response.success?
59
+
60
+ credit_card_reference = response.params['porteur']
61
+ assert !credit_card_reference.nil?
62
+
63
+ assert capture = @gateway.subscriber_capture(@amount, response.authorization, @options)
64
+ assert capture.success?
65
+
66
+ assert refund = @gateway.subscriber_refund(@amount, capture.authorization, @options)
67
+ assert_equal 'The transaction was approved', refund.message
68
+ assert refund.success?
69
+ end
70
+
53
71
  def test_failed_capture
54
- assert response = @gateway.capture(@amount, '', :order_id => '1', :user_reference => 'pipomolo')
55
- assert_failure response
56
- assert_equal "Mandatory values missing keyword:13 Type:19", response.message
72
+ assert response = @gateway.subscriber_capture(@amount, '', order_id: '1', user_reference: 'pipomolo')
73
+ assert !response.success?
74
+ assert_equal 'Invalid data', response.message
57
75
  end
58
- end
59
76
 
77
+ private
78
+
79
+ def default_expiration_date
80
+ @default_expiration_date ||= Date.new((Time.now.year + 1), 9, 30)
81
+ end
82
+
83
+ def credit_card(number = '4242424242424242', options = {})
84
+ defaults = {
85
+ number: number,
86
+ month: default_expiration_date.month,
87
+ year: default_expiration_date.year,
88
+ first_name: 'Longbob',
89
+ last_name: 'Longsen',
90
+ verification_value: options[:verification_value] || '123',
91
+ brand: 'visa'
92
+ }.update(options)
93
+
94
+ ActiveMerchant::Billing::CreditCard.new(defaults)
95
+ end
96
+ end