ogone 0.1.0 → 0.2.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 +5 -5
- data/.rubocop.yml +12 -0
- data/README.md +44 -0
- data/Rakefile +1 -1
- data/lib/ogone.rb +5 -3
- data/lib/ogone/base.rb +98 -0
- data/lib/ogone/ecommerce.rb +58 -103
- data/lib/ogone/flexcheckout.rb +45 -0
- data/lib/ogone/order_direct.rb +27 -0
- data/lib/ogone/status.rb +43 -43
- data/lib/ogone/version.rb +1 -1
- data/ogone.gemspec +16 -15
- data/spec/ogone/ecommerce_spec.rb +56 -58
- data/spec/spec_helper.rb +1 -1
- metadata +46 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 85185bca3d62a4d0a260d9c09ee46faed5ff3d1ca5e87d5ea20eeba08f71e5b7
|
4
|
+
data.tar.gz: f752b6492f9c12a5647379ccad4e2d67a98566e67f0ce21e902ee6deb64daf43
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4c46e65d211f33026882c61807ce45bd69950139778097d7e82f7ecc3465bd10c55633b9d14866e7f19f7327f6f12395ae0a567affcd86ad57d07cad7b307e6d
|
7
|
+
data.tar.gz: e6a008fa16cae177fc94b12b6a41823601a2dda9114bbe9ecbec7056963b9bab610bf62c8c3dd089150e80fc6ddfc70915c41d4696efdea9419663b57d28d89f
|
data/.rubocop.yml
ADDED
data/README.md
CHANGED
@@ -5,6 +5,8 @@ your users to the ogone ecommerce form where they can pay. This gem is flexible
|
|
5
5
|
as it does not rely on a hard-coded configuration to be used. Therefore you can
|
6
6
|
dynamically handle several PSPIDs.
|
7
7
|
|
8
|
+
You can also use Flexcheckout combined with direct order (see Flexcheckout and direct order).
|
9
|
+
|
8
10
|
## Usage
|
9
11
|
|
10
12
|
In your controller,
|
@@ -84,6 +86,48 @@ class PaymentController
|
|
84
86
|
end
|
85
87
|
```
|
86
88
|
|
89
|
+
## Flexcheckout and direct order
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
@ogone = Ogone::Flexcheckout.new opts # same options than Ogone::Ecommerce
|
93
|
+
|
94
|
+
@ogone.add_parameters(
|
95
|
+
'CARD.PAYMENTMETHOD' => 'CreditCard',
|
96
|
+
'PARAMETERS.ACCEPTURL' => 'http://my_app/ogone_flexcheckout_success',
|
97
|
+
'PARAMETERS.EXCEPTIONURL' => 'http://my_app/ogone_flexcheckout_failure',
|
98
|
+
'LANGUAGE' => 'en_US',
|
99
|
+
)
|
100
|
+
|
101
|
+
@ogone.form_url # this is the URL with the Flexcheckout form, you shoudl redirect_to it
|
102
|
+
```
|
103
|
+
|
104
|
+
Once you fill the form, Ogone will redirect to the `ACCEPTURL` or `EXCEPTIONURL`. If you go to the `ACCEPTURL`,
|
105
|
+
you can proceed with the order :
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
# first ensure sha_out matches
|
109
|
+
@ogone = Ogone::Flexcheckout.new opts # same options than Ogone::Ecommerce
|
110
|
+
@ogone.check_shasign_out!(params)
|
111
|
+
|
112
|
+
# ok sha_out matches proceed to the order
|
113
|
+
@ogone = Ogone::OrderDirect.new opts # same options than Ogone::Ecommerce
|
114
|
+
|
115
|
+
@ogone.add_parameters(
|
116
|
+
'ORDERID' => params['Alias.OrderId'],
|
117
|
+
'AMOUNT' => 10 * 100,
|
118
|
+
'CURRENCY' => 'EUR',
|
119
|
+
'ALIAS' => params['Alias.AliasId'], # comes from the HTTP params set in the flexcheckout redirect
|
120
|
+
'USERID' => 'my_api_user', # you need to have an API user https://payment-services.ingenico.com/int/en/ogone/support/guides/integration%20guides/directlink
|
121
|
+
'PSWD' => 'super_secret@',
|
122
|
+
'OPERATION' => 'RES'
|
123
|
+
# extra parameters may be set for 3D Secure : https://payment-services.ingenico.com/int/en/ogone/support/guides/integration%20guides/directlink-3-d/3-d-transaction-flow-via-directlink#comments
|
124
|
+
)
|
125
|
+
|
126
|
+
result = @ogone.perform_order
|
127
|
+
|
128
|
+
# handle result
|
129
|
+
```
|
130
|
+
|
87
131
|
## Contributing
|
88
132
|
|
89
133
|
1. Fork it
|
data/Rakefile
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
data/lib/ogone.rb
CHANGED
data/lib/ogone/base.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'digest'
|
2
|
+
|
3
|
+
module Ogone
|
4
|
+
class Base
|
5
|
+
VALID_ENVIRONMENTS = %w[test prod].freeze unless const_defined? :VALID_ENVIRONMENTS
|
6
|
+
SIGNING_ALGORITHMS = %w[SHA1 SHA256 SHA512].freeze unless const_defined? :SIGNING_ALGORITHMS
|
7
|
+
|
8
|
+
class ConfigurationError < StandardError; end
|
9
|
+
class MandatoryParameterMissing < StandardError; end
|
10
|
+
class OutboundSignatureMismatch < StandardError; end
|
11
|
+
|
12
|
+
attr_accessor :sha_in, :sha_out
|
13
|
+
|
14
|
+
def initialize(options = {})
|
15
|
+
@parameters = {}
|
16
|
+
%i[sha_algo environment pspid sha_in sha_out].each do |config|
|
17
|
+
send :"#{config}=", options[config] unless options[config].nil?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def sha_algo=(sha_algo)
|
22
|
+
raise ArgumentError, "Unsupported signature algorithm: #{sha_algo}" unless SIGNING_ALGORITHMS.include?(sha_algo)
|
23
|
+
@sha_algo = sha_algo
|
24
|
+
end
|
25
|
+
|
26
|
+
def environment=(environment)
|
27
|
+
unless VALID_ENVIRONMENTS.include? environment.to_s
|
28
|
+
raise ArgumentError, "Unsupported Ogone environment: #{environment}"
|
29
|
+
end
|
30
|
+
@environment = environment
|
31
|
+
end
|
32
|
+
|
33
|
+
def pspid=(pspid)
|
34
|
+
raise ArgumentError, 'PSPID cannot be empty' if pspid.nil? || pspid == ''
|
35
|
+
@pspid = pspid
|
36
|
+
end
|
37
|
+
|
38
|
+
def add_parameters(parameters)
|
39
|
+
@parameters.merge! parameters
|
40
|
+
end
|
41
|
+
|
42
|
+
def fields_for_payment(parameters = {}, shasign_key = 'SHASIGN')
|
43
|
+
add_parameters(parameters || {})
|
44
|
+
check_mandatory_parameters!
|
45
|
+
|
46
|
+
upcase_keys(@parameters).merge(shasign_key.to_sym => sha_in_sign)
|
47
|
+
end
|
48
|
+
|
49
|
+
def check_shasign_out!(params)
|
50
|
+
params = upcase_keys(params)
|
51
|
+
raise OutboundSignatureMismatch if sha_out_sign(params) != params[:SHASIGN]
|
52
|
+
end
|
53
|
+
|
54
|
+
def upcase_keys(hash)
|
55
|
+
hash.each_with_object({}) { |(k, v), h| h[k.upcase.to_sym] = v; }
|
56
|
+
end
|
57
|
+
|
58
|
+
protected
|
59
|
+
|
60
|
+
def ogone_host
|
61
|
+
@environment == 'test' ? 'ogone.test.v-psp.com' : 'secure.ogone.com'
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def sha_in_sign
|
67
|
+
to_hash = sorted_upcased_parameters.each_with_object([]) do |(k, v), a|
|
68
|
+
a << "#{k}=#{v}#{@sha_in}" unless v.nil? || v == ''
|
69
|
+
end.join
|
70
|
+
sign to_hash
|
71
|
+
end
|
72
|
+
|
73
|
+
def sha_out_sign(params)
|
74
|
+
to_hash = self.class.const_get('OUTBOUND_SIGNATURE_PARAMETERS').each_with_object([]) do |p, a|
|
75
|
+
a << "#{p}=#{params[p]}#{@sha_out}" unless params[p].nil? || params[p] == ''
|
76
|
+
end.join
|
77
|
+
sign to_hash
|
78
|
+
end
|
79
|
+
|
80
|
+
def sign(to_hash)
|
81
|
+
unless SIGNING_ALGORITHMS.include?(@sha_algo)
|
82
|
+
raise ArgumentError, "Unsupported signature algorithm: '#{@sha_algo}'"
|
83
|
+
end
|
84
|
+
Digest.const_get(@sha_algo).hexdigest(to_hash).upcase
|
85
|
+
end
|
86
|
+
|
87
|
+
def sorted_upcased_parameters
|
88
|
+
upcase_keys(@parameters).sort
|
89
|
+
end
|
90
|
+
|
91
|
+
def check_mandatory_parameters!
|
92
|
+
keys = @parameters.keys.map(&:to_sym)
|
93
|
+
self.class.const_get('MANDATORY_PARAMETERS').each do |parameter|
|
94
|
+
raise MandatoryParameterMissing, parameter unless keys.include? parameter.to_sym
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
data/lib/ogone/ecommerce.rb
CHANGED
@@ -1,120 +1,75 @@
|
|
1
|
-
|
2
|
-
class Ecommerce
|
3
|
-
VALID_ENVIRONMENTS = %w(test prod) unless const_defined? :VALID_ENVIRONMENTS
|
4
|
-
SIGNING_ALGORITHMS = %w(SHA1 SHA256 SHA512) unless const_defined? :SIGNING_ALGORITHMS
|
5
|
-
|
6
|
-
class ConfigurationError < StandardError; end
|
7
|
-
|
8
|
-
MANDATORY_PARAMETERS = %w(PSPID ORDERID AMOUNT CURRENCY LANGUAGE) unless const_defined? :MANDATORY_PARAMETERS
|
9
|
-
class MandatoryParameterMissing < StandardError; end
|
10
|
-
|
11
|
-
OUTBOUND_SIGNATURE_PARAMETERS = %w(AAVADDRESS AAVCHECK AAVZIP ACCEPTANCE ALIAS AMOUNT BIN \
|
12
|
-
BRAND CARDNO CCCTY CN COMPLUS CREATION_STATUS CURRENCY \
|
13
|
-
CVCCHECK DCC_COMMPERCENTAGE DCC_CONVAMOUNT DCC_CONVCCY \
|
14
|
-
DCC_EXCHRATE DCC_EXCHRATESOURCE DCC_EXCHRATETS DCC_INDICATOR \
|
15
|
-
DCC_MARGINPERCENTAGE DCC_VALIDHOURS DIGESTCARDNO ECI ED \
|
16
|
-
ENCCARDNO FXAMOUNT FXCURRENCY IP IPCTY NBREMAILUSAGE NBRIPUSAGE\
|
17
|
-
NBRIPUSAGE_ALLTX NBRUSAGE NCERROR ORDERID PAYID PM SCO_CATEGORY \
|
18
|
-
SCORING STATUS SUBBRAND SUBSCRIPTION_ID TRXDATE VC).collect &:to_sym unless const_defined? :OUTBOUND_SIGNATURE_PARAMETERS
|
19
|
-
class OutboundSignatureMismatch < StandardError; end
|
20
|
-
|
21
|
-
attr_accessor :sha_in, :sha_out
|
1
|
+
require 'ogone/base'
|
22
2
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
3
|
+
module Ogone
|
4
|
+
class Ecommerce < Base
|
5
|
+
MANDATORY_PARAMETERS = %w[PSPID ORDERID AMOUNT CURRENCY LANGUAGE].freeze
|
6
|
+
|
7
|
+
OUTBOUND_SIGNATURE_PARAMETERS = %i[
|
8
|
+
AAVADDRESS
|
9
|
+
AAVCHECK
|
10
|
+
AAVZIP
|
11
|
+
ACCEPTANCE
|
12
|
+
ALIAS
|
13
|
+
AMOUNT
|
14
|
+
BIN
|
15
|
+
BRAND
|
16
|
+
CARDNO
|
17
|
+
CCCTY
|
18
|
+
CN
|
19
|
+
COMPLUS
|
20
|
+
CREATION_STATUS
|
21
|
+
CURRENCY
|
22
|
+
CVCCHECK
|
23
|
+
DCC_COMMPERCENTAGE
|
24
|
+
DCC_CONVAMOUNT
|
25
|
+
DCC_CONVCCY
|
26
|
+
DCC_EXCHRATE
|
27
|
+
DCC_EXCHRATESOURCE
|
28
|
+
DCC_EXCHRATETS
|
29
|
+
DCC_INDICATOR
|
30
|
+
DCC_MARGINPERCENTAGE
|
31
|
+
DCC_VALIDHOURS
|
32
|
+
DIGESTCARDNO
|
33
|
+
ECI
|
34
|
+
ED
|
35
|
+
ENCCARDNO
|
36
|
+
FXAMOUNT
|
37
|
+
FXCURRENCY
|
38
|
+
IP
|
39
|
+
IPCTY
|
40
|
+
NBREMAILUSAGE
|
41
|
+
NBRIPUSAGE
|
42
|
+
NBRIPUSAGE_ALLTX
|
43
|
+
NBRUSAGE
|
44
|
+
NCERROR
|
45
|
+
ORDERID
|
46
|
+
PAYID
|
47
|
+
PM
|
48
|
+
SCO_CATEGORY
|
49
|
+
SCORING
|
50
|
+
STATUS
|
51
|
+
SUBBRAND
|
52
|
+
SUBSCRIPTION_ID
|
53
|
+
TRXDATE
|
54
|
+
VC
|
55
|
+
].freeze
|
43
56
|
|
44
57
|
def pspid=(pspid)
|
45
|
-
|
58
|
+
super(pspid)
|
46
59
|
@parameters[:PSPID] = pspid
|
47
60
|
end
|
48
61
|
|
49
62
|
def form_action
|
50
63
|
unless VALID_ENVIRONMENTS.include? @environment.to_s
|
51
|
-
raise ConfigurationError
|
64
|
+
raise ConfigurationError, "Unsupported Ogone environment: '#{@environment}'."
|
52
65
|
end
|
53
66
|
"https://secure.ogone.com/ncol/#{@environment}/orderstandard_utf8.asp"
|
54
67
|
end
|
55
68
|
|
56
69
|
def add_single_return_url(return_url)
|
57
|
-
[
|
70
|
+
%i[ACCEPTURL DECLINEURL EXCEPTIONURL CANCELURL].each do |field|
|
58
71
|
@parameters[field] = return_url
|
59
72
|
end
|
60
73
|
end
|
61
|
-
|
62
|
-
def add_parameters(parameters)
|
63
|
-
@parameters.merge! parameters
|
64
|
-
end
|
65
|
-
|
66
|
-
def fields_for_payment(parameters = {})
|
67
|
-
add_parameters(parameters || {})
|
68
|
-
check_mandatory_parameters!
|
69
|
-
|
70
|
-
upcase_keys(@parameters).merge :SHASIGN => sha_in_sign
|
71
|
-
end
|
72
|
-
|
73
|
-
def check_shasign_out!(params)
|
74
|
-
params = upcase_keys(params)
|
75
|
-
raise OutboundSignatureMismatch.new if sha_out_sign(params) != params[:SHASIGN]
|
76
|
-
end
|
77
|
-
|
78
|
-
def upcase_keys(hash)
|
79
|
-
hash.inject({}) { |h, (k, v)| h[k.upcase.to_sym] = v; h }
|
80
|
-
end
|
81
|
-
|
82
|
-
private
|
83
|
-
|
84
|
-
def sha_in_sign
|
85
|
-
to_hash = sorted_upcased_parameters.inject([]) {
|
86
|
-
|a, (k, v)| a << "#{k}=#{v}#{@sha_in}" unless v.nil? || v == ""
|
87
|
-
a
|
88
|
-
}.join
|
89
|
-
sign to_hash
|
90
|
-
end
|
91
|
-
|
92
|
-
def sha_out_sign(params)
|
93
|
-
to_hash = OUTBOUND_SIGNATURE_PARAMETERS.inject([]) {
|
94
|
-
|a, p| a << "#{p}=#{params[p]}#{@sha_out}" unless params[p].nil? || params[p] == ""
|
95
|
-
a
|
96
|
-
}.join
|
97
|
-
sign to_hash
|
98
|
-
end
|
99
|
-
|
100
|
-
def sign(to_hash)
|
101
|
-
unless SIGNING_ALGORITHMS.include?(@sha_algo)
|
102
|
-
raise ArgumentError.new("Unsupported signature algorithm: '#{@sha_algo}'")
|
103
|
-
end
|
104
|
-
Digest.const_get(@sha_algo).hexdigest(to_hash).upcase
|
105
|
-
end
|
106
|
-
|
107
|
-
def sorted_upcased_parameters
|
108
|
-
upcase_keys(@parameters).sort
|
109
|
-
end
|
110
|
-
|
111
|
-
def check_mandatory_parameters!
|
112
|
-
MANDATORY_PARAMETERS.each do |parameter|
|
113
|
-
unless @parameters.include? parameter.to_sym
|
114
|
-
raise MandatoryParameterMissing.new parameter
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
74
|
end
|
120
|
-
end
|
75
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'ogone/base'
|
2
|
+
|
3
|
+
module Ogone
|
4
|
+
class Flexcheckout < Base
|
5
|
+
MANDATORY_PARAMETERS = %w[
|
6
|
+
ACCOUNT.PSPID
|
7
|
+
PARAMETERS.ACCEPTURL
|
8
|
+
PARAMETERS.EXCEPTIONURL
|
9
|
+
CARD.PAYMENTMETHOD
|
10
|
+
LANGUAGE
|
11
|
+
].freeze
|
12
|
+
|
13
|
+
OUTBOUND_SIGNATURE_PARAMETERS = %i[
|
14
|
+
ALIAS.ALIASID
|
15
|
+
ALIAS.NCERROR
|
16
|
+
ALIAS.NCERRORCARDNO
|
17
|
+
ALIAS.NCERRORCN
|
18
|
+
ALIAS.NCERRORCVC
|
19
|
+
ALIAS.NCERRORED
|
20
|
+
ALIAS.ORDERID
|
21
|
+
ALIAS.STATUS
|
22
|
+
ALIAS.STOREPERMANENTLY
|
23
|
+
CARD.BIC
|
24
|
+
CARD.BIN
|
25
|
+
CARD.BRAND
|
26
|
+
CARD.CARDHOLDERNAME
|
27
|
+
CARD.CARDNUMBER
|
28
|
+
CARD.CVC
|
29
|
+
CARD.EXPIRYDATE
|
30
|
+
].freeze
|
31
|
+
|
32
|
+
def pspid=(pspid)
|
33
|
+
super(pspid)
|
34
|
+
@parameters[:'ACCOUNT.PSPID'] = pspid
|
35
|
+
end
|
36
|
+
|
37
|
+
def fields_for_payment(parameters = {})
|
38
|
+
super(parameters, 'SHASIGNATURE.SHASIGN')
|
39
|
+
end
|
40
|
+
|
41
|
+
def form_url
|
42
|
+
"https://#{ogone_host}/Tokenization/HostedPage?#{URI.encode_www_form(fields_for_payment)}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'ogone/base'
|
2
|
+
|
3
|
+
module Ogone
|
4
|
+
class OrderDirect < Base
|
5
|
+
MANDATORY_PARAMETERS = %w[
|
6
|
+
PSPID
|
7
|
+
ORDERID
|
8
|
+
AMOUNT
|
9
|
+
CURRENCY
|
10
|
+
ALIAS
|
11
|
+
USERID
|
12
|
+
PSWD
|
13
|
+
OPERATION
|
14
|
+
].freeze
|
15
|
+
|
16
|
+
def pspid=(pspid)
|
17
|
+
super(pspid)
|
18
|
+
@parameters[:PSPID] = pspid
|
19
|
+
end
|
20
|
+
|
21
|
+
def perform_order
|
22
|
+
url = "https://#{ogone_host}/ncol/#{@environment}/orderdirect.asp"
|
23
|
+
res = HTTParty.get("#{url}?#{URI.encode_www_form(fields_for_payment)}")
|
24
|
+
res.body
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/ogone/status.rb
CHANGED
@@ -1,45 +1,45 @@
|
|
1
1
|
module Ogone
|
2
|
+
unless const_defined? :STATUS
|
3
|
+
STATUS = {
|
4
|
+
0 => 'Incomplete or invalid',
|
5
|
+
1 => 'Cancelled by client',
|
6
|
+
2 => 'Authorization refused',
|
7
|
+
4 => 'Order stored',
|
8
|
+
41 => 'Waiting client payment',
|
9
|
+
5 => 'Authorized',
|
10
|
+
51 => 'Authorization waiting',
|
11
|
+
52 => 'Authorization not known',
|
12
|
+
55 => 'Stand-by',
|
13
|
+
59 => 'Authoriz. to get manually',
|
14
|
+
6 => 'Authorized and cancelled',
|
15
|
+
61 => 'Author. deletion waiting',
|
16
|
+
62 => 'Author. deletion uncertain',
|
17
|
+
63 => 'Author. deletion refused',
|
18
|
+
64 => 'Authorized and cancelled',
|
19
|
+
7 => 'Payment deleted',
|
20
|
+
71 => 'Payment deletion pending',
|
21
|
+
72 => 'Payment deletion uncertain',
|
22
|
+
73 => 'Payment deletion refused',
|
23
|
+
74 => 'Payment deleted',
|
24
|
+
75 => 'Deletion processed by merchant',
|
25
|
+
8 => 'Refund',
|
26
|
+
81 => 'Refund pending',
|
27
|
+
82 => 'Refund uncertain',
|
28
|
+
83 => 'Refund refused',
|
29
|
+
84 => 'Payment declined by the acquirer',
|
30
|
+
85 => 'Refund processed by merchant',
|
31
|
+
9 => 'Payment requested',
|
32
|
+
91 => 'Payment processing',
|
33
|
+
92 => 'Payment uncertain',
|
34
|
+
93 => 'Payment refused',
|
35
|
+
94 => 'Refund declined by the acquirer',
|
36
|
+
95 => 'Payment processed by merchant',
|
37
|
+
99 => 'Being processed'
|
38
|
+
}.freeze
|
39
|
+
end
|
2
40
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
41 => 'Waiting client payment',
|
9
|
-
5 => 'Authorized',
|
10
|
-
51 => 'Authorization waiting',
|
11
|
-
52 => 'Authorization not known',
|
12
|
-
55 => 'Stand-by',
|
13
|
-
59 => 'Authoriz. to get manually',
|
14
|
-
6 => 'Authorized and cancelled',
|
15
|
-
61 => 'Author. deletion waiting',
|
16
|
-
62 => 'Author. deletion uncertain',
|
17
|
-
63 => 'Author. deletion refused',
|
18
|
-
64 => 'Authorized and cancelled',
|
19
|
-
7 => 'Payment deleted',
|
20
|
-
71 => 'Payment deletion pending',
|
21
|
-
72 => 'Payment deletion uncertain',
|
22
|
-
73 => 'Payment deletion refused',
|
23
|
-
74 => 'Payment deleted',
|
24
|
-
75 => 'Deletion processed by merchant',
|
25
|
-
8 => 'Refund',
|
26
|
-
81 => 'Refund pending',
|
27
|
-
82 => 'Refund uncertain',
|
28
|
-
83 => 'Refund refused',
|
29
|
-
84 => 'Payment declined by the acquirer',
|
30
|
-
85 => 'Refund processed by merchant',
|
31
|
-
9 => 'Payment requested',
|
32
|
-
91 => 'Payment processing',
|
33
|
-
92 => 'Payment uncertain',
|
34
|
-
93 => 'Payment refused',
|
35
|
-
94 => 'Refund declined by the acquirer',
|
36
|
-
95 => 'Payment processed by merchant',
|
37
|
-
99 => 'Being processed'
|
38
|
-
} unless const_defined? :STATUS
|
39
|
-
|
40
|
-
PAID_STATUSES = [4, 5, 9] unless const_defined? :PAID_STATUSES
|
41
|
-
PENDING_STATUSES = [41, 51, 52, 91, 92, 99] unless const_defined? :PENDING_STATUSES
|
42
|
-
CANCELLED_STATUSES = [1] unless const_defined? :CANCELLED_STATUSES
|
43
|
-
REFUNDED_STATUSES = [8] unless const_defined? :REFUNDED_STATUSES
|
44
|
-
|
45
|
-
end
|
41
|
+
PAID_STATUSES = [4, 5, 9].freeze unless const_defined? :PAID_STATUSES
|
42
|
+
PENDING_STATUSES = [41, 51, 52, 91, 92, 99].freeze unless const_defined? :PENDING_STATUSES
|
43
|
+
CANCELLED_STATUSES = [1].freeze unless const_defined? :CANCELLED_STATUSES
|
44
|
+
REFUNDED_STATUSES = [8].freeze unless const_defined? :REFUNDED_STATUSES
|
45
|
+
end
|
data/lib/ogone/version.rb
CHANGED
data/ogone.gemspec
CHANGED
@@ -1,28 +1,29 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
3
|
require 'ogone/version'
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
6
|
+
spec.name = 'ogone'
|
8
7
|
spec.version = Ogone::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
11
|
-
spec.description =
|
8
|
+
spec.authors = ['Sebastien Saunier']
|
9
|
+
spec.email = ['seb@saunier.me']
|
10
|
+
spec.description = 'Flexible Ogone ecommerce wrapper
|
12
11
|
|
13
12
|
Deal simply with multiple ogone ecommerce account within your application.
|
14
13
|
No hard coded configuration read from a *.yml file.
|
15
|
-
|
16
|
-
spec.summary =
|
17
|
-
spec.homepage =
|
18
|
-
spec.license =
|
14
|
+
'
|
15
|
+
spec.summary = 'Flexible Ogone ecommerce wrapper'
|
16
|
+
spec.homepage = 'https://github.com/applidget/ogone'
|
17
|
+
spec.license = 'MIT'
|
19
18
|
|
20
|
-
spec.files = `git ls-files`.split(
|
19
|
+
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
21
20
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
22
21
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
23
|
-
spec.require_paths = [
|
22
|
+
spec.require_paths = ['lib']
|
24
23
|
|
25
|
-
spec.add_development_dependency
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
25
|
+
spec.add_development_dependency 'rake'
|
26
|
+
spec.add_development_dependency 'rspec'
|
27
|
+
spec.add_development_dependency 'rubocop'
|
28
|
+
spec.add_dependency 'httparty'
|
28
29
|
end
|
@@ -1,90 +1,86 @@
|
|
1
|
-
require
|
1
|
+
require 'ogone/ecommerce'
|
2
2
|
|
3
3
|
module Ogone
|
4
4
|
describe Ecommerce do
|
5
|
-
|
6
5
|
before(:each) do
|
7
6
|
@ogone = Ogone::Ecommerce.new
|
8
7
|
end
|
9
8
|
|
10
|
-
it
|
9
|
+
it 'should raise an error if incorrect sha algorithm given' do
|
11
10
|
lambda { @ogone.sha_algo = 'WRONG_SHA' }.should raise_error ArgumentError
|
12
11
|
end
|
13
12
|
|
14
|
-
it
|
13
|
+
it 'should raise an error if incorrect ogone environment given' do
|
15
14
|
lambda { @ogone.environment = 'WRONG_ENV' }.should raise_error ArgumentError
|
16
15
|
end
|
17
16
|
|
18
|
-
it
|
17
|
+
it 'should raise an error if an empty PSPID is specified' do
|
19
18
|
lambda { @ogone.pspid = '' }.should raise_error ArgumentError
|
20
19
|
end
|
21
20
|
|
22
|
-
it
|
23
|
-
@ogone.environment =
|
24
|
-
@ogone.form_action.should eq
|
21
|
+
it 'should render the test Ogone url' do
|
22
|
+
@ogone.environment = 'test'
|
23
|
+
@ogone.form_action.should eq 'https://secure.ogone.com/ncol/test/orderstandard_utf8.asp'
|
25
24
|
end
|
26
25
|
|
27
|
-
it
|
28
|
-
@ogone.environment =
|
29
|
-
@ogone.form_action.should eq
|
26
|
+
it 'should render the production Ogone url' do
|
27
|
+
@ogone.environment = 'prod'
|
28
|
+
@ogone.form_action.should eq 'https://secure.ogone.com/ncol/prod/orderstandard_utf8.asp'
|
30
29
|
end
|
31
30
|
|
32
|
-
it
|
33
|
-
@ogone.pspid =
|
34
|
-
parameters[:PSPID].should eq
|
31
|
+
it 'should have the PSPID stored in the parameters' do
|
32
|
+
@ogone.pspid = 'pspid'
|
33
|
+
parameters[:PSPID].should eq 'pspid'
|
35
34
|
end
|
36
35
|
|
37
|
-
describe
|
38
|
-
|
36
|
+
describe '#check_shasign_out!' do
|
39
37
|
before(:each) do
|
40
|
-
@ogone = Ogone::Ecommerce.new :
|
38
|
+
@ogone = Ogone::Ecommerce.new sha_out: 'sha_out', sha_algo: 'SHA1'
|
41
39
|
end
|
42
40
|
|
43
|
-
it
|
41
|
+
it 'should check an inbound signature' do
|
44
42
|
params = ogone_return_parameters
|
45
43
|
lambda { @ogone.check_shasign_out! params }.should_not raise_error Ogone::Ecommerce::OutboundSignatureMismatch
|
46
44
|
end
|
47
45
|
|
48
|
-
it
|
46
|
+
it 'should throw an error if the outbound shasign does not match' do
|
49
47
|
params = {
|
50
|
-
|
51
|
-
|
48
|
+
'amonut' => '160',
|
49
|
+
'SHASIGN' => 'FOO'
|
52
50
|
}
|
53
51
|
lambda { @ogone.check_shasign_out! params }.should raise_error Ogone::Ecommerce::OutboundSignatureMismatch
|
54
52
|
end
|
55
53
|
end
|
56
54
|
|
57
|
-
describe
|
58
|
-
|
55
|
+
describe '#fields_for_payment' do
|
59
56
|
before(:each) do
|
60
|
-
@ogone = Ogone::Ecommerce.new :
|
57
|
+
@ogone = Ogone::Ecommerce.new pspid: 'pspid', sha_in: 'sha_in', sha_algo: 'SHA1'
|
61
58
|
end
|
62
59
|
|
63
|
-
it
|
64
|
-
fields = @ogone.fields_for_payment :
|
65
|
-
:
|
66
|
-
:
|
67
|
-
:
|
60
|
+
it 'should give a hash ready to be used in `hidden_field_tag`' do
|
61
|
+
fields = @ogone.fields_for_payment AMOUNT: 100,
|
62
|
+
CURRENCY: 'EUR',
|
63
|
+
ORDERID: '123',
|
64
|
+
LANGUAGE: 'en_US'
|
68
65
|
|
69
|
-
fields[:SHASIGN].should eq
|
66
|
+
fields[:SHASIGN].should eq 'AA7CA1F98159D14D0943311092F5435F239B4B36'
|
70
67
|
end
|
71
68
|
|
72
|
-
it
|
73
|
-
@ogone.add_parameters :
|
69
|
+
it 'should also work if parameters were given with #add_parameters' do
|
70
|
+
@ogone.add_parameters AMOUNT: 100, CURRENCY: 'EUR', ORDERID: '123', LANGUAGE: 'en_US'
|
74
71
|
|
75
72
|
fields = @ogone.fields_for_payment
|
76
|
-
fields[:SHASIGN].should eq
|
73
|
+
fields[:SHASIGN].should eq 'AA7CA1F98159D14D0943311092F5435F239B4B36'
|
77
74
|
end
|
78
|
-
|
79
75
|
end
|
80
76
|
|
81
|
-
describe
|
82
|
-
it
|
83
|
-
@ogone.add_single_return_url
|
84
|
-
parameters[:ACCEPTURL].should eq
|
85
|
-
parameters[:DECLINEURL].should eq
|
86
|
-
parameters[:EXCEPTIONURL].should eq
|
87
|
-
parameters[:CANCELURL].should eq
|
77
|
+
describe '#add_single_return_url' do
|
78
|
+
it 'should allow lazy folks to give just one back url' do
|
79
|
+
@ogone.add_single_return_url 'http://iamsola.zy'
|
80
|
+
parameters[:ACCEPTURL].should eq 'http://iamsola.zy'
|
81
|
+
parameters[:DECLINEURL].should eq 'http://iamsola.zy'
|
82
|
+
parameters[:EXCEPTIONURL].should eq 'http://iamsola.zy'
|
83
|
+
parameters[:CANCELURL].should eq 'http://iamsola.zy'
|
88
84
|
end
|
89
85
|
end
|
90
86
|
|
@@ -94,25 +90,27 @@ module Ogone
|
|
94
90
|
@ogone.instance_variable_get :@parameters
|
95
91
|
end
|
96
92
|
|
93
|
+
# rubocop:disable Metrics/MethodLength
|
97
94
|
def ogone_return_parameters
|
98
95
|
{
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
96
|
+
'orderID' => 'r_511b52f7230b430b3f000003_19',
|
97
|
+
'currency' => 'EUR',
|
98
|
+
'amount' => '160',
|
99
|
+
'PM' => 'CreditCard',
|
100
|
+
'ACCEPTANCE' => '',
|
101
|
+
'STATUS' => '1',
|
102
|
+
'CARDNO' => '',
|
103
|
+
'ED' => '',
|
104
|
+
'CN' => 'Sebastien Saunier',
|
105
|
+
'TRXDATE' => '02/13/13',
|
106
|
+
'PAYID' => '19113975',
|
107
|
+
'NCERROR' => '',
|
108
|
+
'BRAND' => '',
|
109
|
+
'COMPLUS' => 'registration_511b52f7230b430b3f000003',
|
110
|
+
'IP' => '80.12.86.33',
|
111
|
+
'SHASIGN' => 'F3F5F963C700F56B69EA36173F5BFB3B28CA25E5'
|
115
112
|
}
|
116
113
|
end
|
114
|
+
# rubocop:enable Metrics/MethodLength
|
117
115
|
end
|
118
|
-
end
|
116
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,58 +1,86 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ogone
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sebastien Saunier
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-08-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.3'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
-
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: httparty
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: "Flexible Ogone ecommerce wrapper\n\nDeal simply with multiple ogone
|
56
84
|
ecommerce account within your application.\nNo hard coded configuration read from
|
57
85
|
a *.yml file.\n "
|
58
86
|
email:
|
@@ -61,14 +89,18 @@ executables: []
|
|
61
89
|
extensions: []
|
62
90
|
extra_rdoc_files: []
|
63
91
|
files:
|
64
|
-
- .gitignore
|
65
|
-
- .rspec
|
92
|
+
- ".gitignore"
|
93
|
+
- ".rspec"
|
94
|
+
- ".rubocop.yml"
|
66
95
|
- Gemfile
|
67
96
|
- LICENSE.txt
|
68
97
|
- README.md
|
69
98
|
- Rakefile
|
70
99
|
- lib/ogone.rb
|
100
|
+
- lib/ogone/base.rb
|
71
101
|
- lib/ogone/ecommerce.rb
|
102
|
+
- lib/ogone/flexcheckout.rb
|
103
|
+
- lib/ogone/order_direct.rb
|
72
104
|
- lib/ogone/status.rb
|
73
105
|
- lib/ogone/version.rb
|
74
106
|
- ogone.gemspec
|
@@ -84,17 +116,17 @@ require_paths:
|
|
84
116
|
- lib
|
85
117
|
required_ruby_version: !ruby/object:Gem::Requirement
|
86
118
|
requirements:
|
87
|
-
- -
|
119
|
+
- - ">="
|
88
120
|
- !ruby/object:Gem::Version
|
89
121
|
version: '0'
|
90
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
123
|
requirements:
|
92
|
-
- -
|
124
|
+
- - ">="
|
93
125
|
- !ruby/object:Gem::Version
|
94
126
|
version: '0'
|
95
127
|
requirements: []
|
96
128
|
rubyforge_project:
|
97
|
-
rubygems_version: 2.
|
129
|
+
rubygems_version: 2.7.3
|
98
130
|
signing_key:
|
99
131
|
specification_version: 4
|
100
132
|
summary: Flexible Ogone ecommerce wrapper
|