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.
- checksums.yaml +7 -0
- data/Gemfile +2 -17
- data/Gemfile.lock +39 -82
- data/README.md +106 -0
- data/Rakefile +8 -52
- data/activemerchant_paybox_direct_plus.gemspec +31 -67
- data/lib/activemerchant_paybox_direct_plus.rb +54 -160
- data/test/remote/gateways/remote_paybox_direct_plus_test.rb +77 -40
- data/test/test_helper.rb +7 -196
- metadata +79 -131
- data/README.markdown +0 -45
- data/VERSION +0 -1
- data/test/fixtures.yml +0 -4
@@ -2,220 +2,140 @@ require 'active_merchant'
|
|
2
2
|
|
3
3
|
module ActiveMerchant #:nodoc:
|
4
4
|
module Billing #:nodoc:
|
5
|
-
class PayboxDirectPlusGateway <
|
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
|
-
:
|
17
|
-
:
|
18
|
-
:
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:
|
22
|
-
:
|
23
|
-
:
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
-
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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]
|
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
|
-
:
|
235
|
-
:
|
236
|
-
:
|
237
|
-
:
|
238
|
-
:
|
239
|
-
:rang
|
240
|
-
:
|
241
|
-
:
|
242
|
-
:
|
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
|
-
|
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
|
4
|
-
|
3
|
+
class RemotePayboxDirectTest < Minitest::Test
|
5
4
|
def setup
|
6
|
-
@gateway = PayboxDirectPlusGateway.new(
|
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
|
-
|
11
|
-
|
12
|
-
|
13
|
-
:
|
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.
|
20
|
-
|
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.
|
26
|
-
|
27
|
-
|
28
|
-
credit_card_reference = response.params[
|
29
|
-
|
30
|
-
|
31
|
-
assert capture = @gateway.
|
32
|
-
|
33
|
-
|
34
|
-
assert void = @gateway.
|
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
|
-
|
37
|
+
assert void.success?
|
37
38
|
end
|
38
|
-
|
39
|
+
|
39
40
|
def test_create_profile_and_purchase
|
40
|
-
assert response = @gateway.
|
41
|
-
|
42
|
-
|
43
|
-
credit_card_reference = response.params[
|
44
|
-
|
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
|
-
|
49
|
-
|
50
|
-
|
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.
|
55
|
-
|
56
|
-
assert_equal
|
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
|