buckaroo-ideal 0.0.1
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.
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.rvmrc +48 -0
- data/.travis.yml +5 -0
- data/.yardopts +3 -0
- data/Gemfile +29 -0
- data/Guardfile +13 -0
- data/LICENSE +22 -0
- data/README.md +45 -0
- data/Rakefile +19 -0
- data/buckaroo-ideal.gemspec +20 -0
- data/files/statuscodes.csv +213 -0
- data/lib/buckaroo-ideal.rb +26 -0
- data/lib/buckaroo-ideal/config.rb +101 -0
- data/lib/buckaroo-ideal/order.rb +46 -0
- data/lib/buckaroo-ideal/request.rb +164 -0
- data/lib/buckaroo-ideal/request_signature.rb +74 -0
- data/lib/buckaroo-ideal/response.rb +68 -0
- data/lib/buckaroo-ideal/response_signature.rb +54 -0
- data/lib/buckaroo-ideal/status.rb +67 -0
- data/lib/buckaroo-ideal/util.rb +41 -0
- data/lib/buckaroo-ideal/version.rb +5 -0
- data/spec/buckaroo-ideal/config_spec.rb +72 -0
- data/spec/buckaroo-ideal/order_spec.rb +43 -0
- data/spec/buckaroo-ideal/request_signature_spec.rb +34 -0
- data/spec/buckaroo-ideal/request_spec.rb +170 -0
- data/spec/buckaroo-ideal/response_signature_spec.rb +59 -0
- data/spec/buckaroo-ideal/response_spec.rb +77 -0
- data/spec/buckaroo-ideal/status_spec.rb +132 -0
- data/spec/buckaroo-ideal/util_spec.rb +62 -0
- data/spec/fixtures/statuscodes.csv +2 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/support/.gitkeep +0 -0
- metadata +113 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
$LOAD_PATH << File.expand_path('..', __FILE__)
|
2
|
+
|
3
|
+
module Buckaroo
|
4
|
+
module Ideal
|
5
|
+
# The banks that are supported by Buckaroo's iDEAL platform
|
6
|
+
BANKS = %w[ ABNAMRO ASNBANK FRIESLAND
|
7
|
+
INGBANK RABOBANK SNSBANK
|
8
|
+
SNSREGIO TRIODOS LANSCHOT ]
|
9
|
+
|
10
|
+
# The currencies that are supported by Buckaroo's iDEAL platform
|
11
|
+
CURRENCIES = %w[ EUR ]
|
12
|
+
|
13
|
+
# The languages supported by Buckaroo's user interface:
|
14
|
+
LANGUAGES = %w[ NL EN DE FR ]
|
15
|
+
|
16
|
+
autoload :VERSION, 'buckaroo-ideal/version'
|
17
|
+
autoload :Config, 'buckaroo-ideal/config'
|
18
|
+
autoload :Order, 'buckaroo-ideal/order'
|
19
|
+
autoload :Response, 'buckaroo-ideal/response'
|
20
|
+
autoload :ResponseSignature, 'buckaroo-ideal/response_signature'
|
21
|
+
autoload :RequestSignature, 'buckaroo-ideal/request_signature'
|
22
|
+
autoload :Request, 'buckaroo-ideal/request'
|
23
|
+
autoload :Status, 'buckaroo-ideal/status'
|
24
|
+
autoload :Util, 'buckaroo-ideal/util'
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module Buckaroo
|
2
|
+
module Ideal
|
3
|
+
#
|
4
|
+
# Configuration singleton for storing settings required for making
|
5
|
+
# transactions.
|
6
|
+
#
|
7
|
+
class Config
|
8
|
+
class << self
|
9
|
+
# The gateway URL that is used to post form data to.
|
10
|
+
#
|
11
|
+
# @return [String] The gateway URL
|
12
|
+
attr_accessor :gateway_url
|
13
|
+
|
14
|
+
# The merchant-key is supllied by Buckaroo. Every application MUST have
|
15
|
+
# it's own merchant key.
|
16
|
+
#
|
17
|
+
# @return [String] The merchant-key for the application
|
18
|
+
attr_accessor :merchant_key
|
19
|
+
|
20
|
+
# The secret_key should only be known by your application and Buckaroo.
|
21
|
+
# It is used to sign orders and validate transactions.
|
22
|
+
#
|
23
|
+
# @return [String] The shared secret key that is used to sign
|
24
|
+
# transaction requests
|
25
|
+
attr_accessor :secret_key
|
26
|
+
|
27
|
+
# If test_mode is enabled, transactions will be registered by Buckaroo,
|
28
|
+
# but clients will not be forwared to the iDEAL page of their bank.
|
29
|
+
#
|
30
|
+
# Clients will be redirected back to the success_url of your application
|
31
|
+
#
|
32
|
+
# @return [Boolean] Test mode on/off
|
33
|
+
attr_accessor :test_mode
|
34
|
+
|
35
|
+
# @return [String] The URL the user will be redirected to after a
|
36
|
+
# successful transaction
|
37
|
+
attr_accessor :success_url
|
38
|
+
|
39
|
+
# @return [String] The URL the user will be redirected to after a failed
|
40
|
+
# transaction
|
41
|
+
attr_accessor :reject_url
|
42
|
+
|
43
|
+
# @return [String] The URL the user will be redirected to after an error
|
44
|
+
# occured during the transaction
|
45
|
+
attr_accessor :error_url
|
46
|
+
|
47
|
+
# @return [String] The HTTP method that will be used to return the user
|
48
|
+
# back to the application after a transaction
|
49
|
+
attr_accessor :return_method
|
50
|
+
|
51
|
+
# There are 2 styles that you can use to integrate Buckaroo iDEAL:
|
52
|
+
# * POPUP - The transaction is performed in a popup
|
53
|
+
# * PAGE - The transaction is performed in the original window
|
54
|
+
#
|
55
|
+
# @return [String] The style that is being used
|
56
|
+
attr_accessor :style
|
57
|
+
|
58
|
+
# If the POPUP style is being used, you can autoclose the popup after
|
59
|
+
# a transaction. You will have to provide information about the
|
60
|
+
# transaction to the user on the page he will arrive on.
|
61
|
+
#
|
62
|
+
# @return [Boolean] Autoclose the popup after a transaction
|
63
|
+
attr_accessor :autoclose_popup
|
64
|
+
|
65
|
+
# Default settings
|
66
|
+
def defaults
|
67
|
+
{
|
68
|
+
gateway_url: 'https://payment.buckaroo.nl/gateway/payment.asp',
|
69
|
+
merchant_key: nil,
|
70
|
+
secret_key: nil,
|
71
|
+
test_mode: false,
|
72
|
+
success_url: nil,
|
73
|
+
reject_url: nil,
|
74
|
+
error_url: nil,
|
75
|
+
return_method: 'POST',
|
76
|
+
style: 'PAGE',
|
77
|
+
autoclose_popup: false
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
# Configure the integration with Buckaroo
|
82
|
+
def configure(settings = {})
|
83
|
+
defaults.merge(settings).each do |key, value|
|
84
|
+
set key, value
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Reset the configuration to the default values
|
89
|
+
def reset
|
90
|
+
configure({})
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def set(key, value)
|
96
|
+
instance_variable_set(:"@#{key}", value)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'active_support/core_ext/module/delegation'
|
2
|
+
|
3
|
+
module Buckaroo
|
4
|
+
module Ideal
|
5
|
+
class Order
|
6
|
+
def self.defaults
|
7
|
+
{ currency: 'EUR' }
|
8
|
+
end
|
9
|
+
|
10
|
+
# @return [Float] The total amount that this order is for
|
11
|
+
attr_accessor :amount
|
12
|
+
|
13
|
+
# @return [String] The currency that is being used for the transaction
|
14
|
+
attr_accessor :currency
|
15
|
+
|
16
|
+
# @return [String] The bank that will be used for the order's transaction.
|
17
|
+
attr_accessor :bank
|
18
|
+
|
19
|
+
# @return [String] The description for the transaction
|
20
|
+
attr_accessor :description
|
21
|
+
|
22
|
+
# @return [String] The reference that will be passed to the response URLs
|
23
|
+
attr_accessor :reference
|
24
|
+
|
25
|
+
# @return [String] The invoice number that is associated with the order
|
26
|
+
attr_accessor :invoice_number
|
27
|
+
|
28
|
+
# Initialize a new +Order+ with the given settings. Uses the defaults from
|
29
|
+
# +Buckaroo::Ideal::Order.defaults+ for settings that are not specified.
|
30
|
+
#
|
31
|
+
# @return [Buckaroo::Ideal::Order] The +Order+ instance
|
32
|
+
def initialize(settings = {})
|
33
|
+
settings = self.class.defaults.merge(settings)
|
34
|
+
settings.each do |key, value|
|
35
|
+
set key, value
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def set(key, value)
|
42
|
+
instance_variable_set(:"@#{key}", value)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
require 'active_support/core_ext/module/delegation'
|
2
|
+
|
3
|
+
module Buckaroo
|
4
|
+
module Ideal
|
5
|
+
#
|
6
|
+
# A class to help with the generation of payment forms for the Buckaroo
|
7
|
+
# Payment Gateway.
|
8
|
+
#
|
9
|
+
# A form has a number of required parameters that are retreived from the
|
10
|
+
# +Buckaroo::Idea::Order+:
|
11
|
+
# * +currency+ -- required; but set by default to 'EUR'
|
12
|
+
# * +invoice_number+ -- required; not set by default
|
13
|
+
# * +amount+ -- required; this is the whole amount, it is automatically
|
14
|
+
# converted to cents
|
15
|
+
# * +bank+ -- optional
|
16
|
+
# * +description+ -- optional
|
17
|
+
#
|
18
|
+
# It is possible to set the following options for this form:
|
19
|
+
# * +language+ -- required, defaults to 'NL'
|
20
|
+
# * +return_method+ -- required, defaults to +Buckaroo::Ideal::Config.return_method+
|
21
|
+
# * +style+ -- required, defaults to +Buckaroo::Ideal::Config.style+
|
22
|
+
# * +autoclose_popup+ -- required, defaults to +Buckaroo::Ideal::Config.autoclose_popup+
|
23
|
+
# * +reference+ -- optional
|
24
|
+
# * +success_url+ -- optional according to documentation
|
25
|
+
# * +reject_url+ -- optional
|
26
|
+
# * +error_url+ -- optional
|
27
|
+
#
|
28
|
+
# The +test_mode+, +gateway_url+ and +merchant_key+ are read from
|
29
|
+
# +Buckaroo::Ideal::Config+.
|
30
|
+
#
|
31
|
+
# To access the information required to create a form, instantiate a new
|
32
|
+
# +Buckaroo::Ideal::Request+ with an +Buckaroo::Ideal::Order+ instance:
|
33
|
+
#
|
34
|
+
# order = Buckaroo::Ideal::Order.new(amount: 100, invoice_number: 'EETNU-123')
|
35
|
+
# request = Buckaroo::Ideal::Request.new(order)
|
36
|
+
#
|
37
|
+
# You can then use the information to create a form. An example in Rails:
|
38
|
+
#
|
39
|
+
# <%= form_tag request.gateway_url do %>
|
40
|
+
# <% request.parameters.each do |name, value| %>
|
41
|
+
# <%= hidden_field_tag name, value %>
|
42
|
+
# <% end %>
|
43
|
+
# <%= submit_tag 'Proceed to payment' %>
|
44
|
+
# <% end %>
|
45
|
+
class Request
|
46
|
+
def self.defaults
|
47
|
+
{
|
48
|
+
language: 'NL',
|
49
|
+
success_url: Config.success_url,
|
50
|
+
reject_url: Config.reject_url,
|
51
|
+
error_url: Config.error_url,
|
52
|
+
return_method: Config.return_method,
|
53
|
+
style: Config.style,
|
54
|
+
autoclose_popup: Config.autoclose_popup
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
# @return [String] The configured gateway_url in +Buckaroo::Ideal::Config+
|
59
|
+
delegate :gateway_url, to: Config
|
60
|
+
|
61
|
+
# @return [Boolean] The configured test_mode in +Buckaroo::Ideal::Config+
|
62
|
+
delegate :test_mode, to: Config
|
63
|
+
|
64
|
+
# @return [String] The configured merchant_key in +Buckaroo::Ideal::Config+
|
65
|
+
delegate :merchant_key, to: Config
|
66
|
+
|
67
|
+
# @return [Buckaroo::Ideal::Order] The order for which the payment request
|
68
|
+
# is being made
|
69
|
+
attr_reader :order
|
70
|
+
|
71
|
+
# @return [String] The language in wich Buckaroo's user interface is
|
72
|
+
# presented.
|
73
|
+
attr_accessor :language
|
74
|
+
|
75
|
+
# Defaults to the configured +Buckaroo::Ideal::Config.success_url+, but
|
76
|
+
# can be overwritten in the +Order+ instance.
|
77
|
+
#
|
78
|
+
# @return [String] The URL the user will be redirected to after a
|
79
|
+
# successful transaction
|
80
|
+
attr_accessor :success_url
|
81
|
+
|
82
|
+
# Defaults to the configured +Buckaroo::Ideal::Config.reject_url+, but can
|
83
|
+
# be overwritten in the +Order+ instance.
|
84
|
+
#
|
85
|
+
# @return [String] The URL the user will be redirected to after a failed
|
86
|
+
# transaction
|
87
|
+
attr_accessor :reject_url
|
88
|
+
|
89
|
+
# Defaults to the configured +Buckaroo::Ideal::Config.error_url+, but can
|
90
|
+
# be overwritten in the +Order+ instance.
|
91
|
+
#
|
92
|
+
# @return [String] The URL the user will be redirected to after an error
|
93
|
+
# occured during the transaction
|
94
|
+
attr_accessor :error_url
|
95
|
+
|
96
|
+
# Defaults to the configured +Buckaroo::Ideal::Config.return_method+, but
|
97
|
+
# can be overwritten in the +Order+ instance.
|
98
|
+
#
|
99
|
+
# @return [String] The HTTP method that will be used to return the user
|
100
|
+
# back to the application after a transaction
|
101
|
+
attr_accessor :return_method
|
102
|
+
|
103
|
+
# Defaults to the configured +Buckaroo::Ideal::Config.style+, but can be
|
104
|
+
# overwritten in the +Order+ instance.
|
105
|
+
#
|
106
|
+
# @return [String] The style that is being used
|
107
|
+
attr_accessor :style
|
108
|
+
|
109
|
+
# Defaults to the configured +Buckaroo::Ideal::Config.autoclose_popup+,
|
110
|
+
# but can be overwritten in the +Order+ instance.
|
111
|
+
#
|
112
|
+
# @return [Boolean] Autoclose the popup after a transaction
|
113
|
+
attr_accessor :autoclose_popup
|
114
|
+
|
115
|
+
# Initialize a new +Buckaroo::Ideal::Request+ instance for the given
|
116
|
+
# order.
|
117
|
+
#
|
118
|
+
# @param [Buckaroo::Ideal::Order] The order that needs to be signed.
|
119
|
+
# @param [Hash] The settings for this form.
|
120
|
+
# @return [Buckaroo::Ideal::Request] The form for the order instance.
|
121
|
+
def initialize(order, settings = {})
|
122
|
+
@order = order
|
123
|
+
settings = self.class.defaults.merge(settings)
|
124
|
+
settings.each do |key, value|
|
125
|
+
set key, value
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def parameters
|
130
|
+
{
|
131
|
+
'BPE_Currency' => order.currency,
|
132
|
+
'BPE_Invoice' => order.invoice_number,
|
133
|
+
'BPE_Amount' => to_cents(order.amount),
|
134
|
+
'BPE_Merchant' => merchant_key,
|
135
|
+
'BPE_Language' => language,
|
136
|
+
'BPE_Mode' => to_numeric_boolean(test_mode),
|
137
|
+
'BPE_Return_Method' => return_method,
|
138
|
+
'BPE_Style' => style,
|
139
|
+
'BPE_Autoclose_Popup' => to_numeric_boolean(autoclose_popup),
|
140
|
+
'BPE_Signature2' => signature
|
141
|
+
}.merge compact({
|
142
|
+
'BPE_Issuer' => order.bank,
|
143
|
+
'BPE_Description' => order.description,
|
144
|
+
'BPE_Reference' => order.reference,
|
145
|
+
'BPE_Return_Success' => success_url,
|
146
|
+
'BPE_Return_Reject' => reject_url,
|
147
|
+
'BPE_Return_Error' => error_url
|
148
|
+
})
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
|
153
|
+
def signature
|
154
|
+
RequestSignature.new(order).signature
|
155
|
+
end
|
156
|
+
|
157
|
+
def set(key, value)
|
158
|
+
instance_variable_set(:"@#{key}", value)
|
159
|
+
end
|
160
|
+
|
161
|
+
include Util
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
require 'active_support/core_ext/module/delegation'
|
3
|
+
|
4
|
+
module Buckaroo
|
5
|
+
module Ideal
|
6
|
+
#
|
7
|
+
# Digital signature generator for +Buckaroo::Ideal::Order+ instances.
|
8
|
+
#
|
9
|
+
# A digital signature is used to sign your request so the Buckaroo Payment
|
10
|
+
# Service can validate that the request was made by your application.
|
11
|
+
#
|
12
|
+
# A digital signature is composed by generating a MD5 hash of the following
|
13
|
+
# values:
|
14
|
+
# * Merchant Key: The +merchant_key+ that is provided by Buckaroo and set
|
15
|
+
# in +Buckaroo::Ideal::Config+.
|
16
|
+
# * Invoice Number: The +invoice_number+ that is set in your
|
17
|
+
# +Buckaroo::Ideal::Order+ instance.
|
18
|
+
# * Amount: The +amount+ that is set in your +Buckaroo::Ideal::Order+
|
19
|
+
# instance in cents.
|
20
|
+
# * Currency: The +currency+ that is set in your +Buckaroo::Ideal::Order+
|
21
|
+
# instance.
|
22
|
+
# * Mode: The +test_mode+ that is set in +Buckaroo::Ideal::Config+.
|
23
|
+
#
|
24
|
+
# To create a signature for an +Buckaroo::Ideal::Order+, instantiate a new
|
25
|
+
# +Buckaroo::Ideal::RequestSignature+ and provide the order:
|
26
|
+
#
|
27
|
+
# order = Buckaroo::Ideal::Order.new(amount: 100, invoice_number: 'EETNU-123')
|
28
|
+
# signature = Buckaroo::Ideal::Signature.new(order)
|
29
|
+
class RequestSignature
|
30
|
+
|
31
|
+
# @return [Buckaroo::Ideal::Order] The order that is being signed.
|
32
|
+
attr_reader :order
|
33
|
+
|
34
|
+
# @return [Boolean] The configured test_mode in +Buckaroo::Ideal::Config+
|
35
|
+
delegate :test_mode, to: Config
|
36
|
+
|
37
|
+
# @return [String] The configured merchant_key in +Buckaroo::Ideal::Config+
|
38
|
+
delegate :merchant_key, to: Config
|
39
|
+
|
40
|
+
# @return [String] The configured secret_key in +Buckaroo::Ideal::Config+
|
41
|
+
delegate :secret_key, to: Config
|
42
|
+
|
43
|
+
# Initialize a new +Buckaroo::Ideal::Signature+ instance for the given
|
44
|
+
# order.
|
45
|
+
#
|
46
|
+
# @param [Buckaroo::Ideal::Order] The order that needs to be signed.
|
47
|
+
# @param [String] The secret key that is used to sign the order.
|
48
|
+
# Defaults to the configured +Buckaroo::Ideal::Config.secret_key+.
|
49
|
+
# @return [Buckaroo::Ideal::Signature] The signature for the order
|
50
|
+
# instance.
|
51
|
+
def initialize(order)
|
52
|
+
@order = order
|
53
|
+
end
|
54
|
+
|
55
|
+
def signature
|
56
|
+
salt = [
|
57
|
+
merchant_key,
|
58
|
+
to_normalized_string(order.invoice_number),
|
59
|
+
to_cents(order.amount),
|
60
|
+
order.currency,
|
61
|
+
to_numeric_boolean(test_mode),
|
62
|
+
secret_key
|
63
|
+
].join
|
64
|
+
|
65
|
+
Digest::MD5.hexdigest(salt)
|
66
|
+
end
|
67
|
+
alias_method :to_s, :signature
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
include Util
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'active_support/core_ext/module/delegation'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
module Buckaroo
|
5
|
+
module Ideal
|
6
|
+
class Response
|
7
|
+
# @return [Hash] The raw parameters that form the heart of the response
|
8
|
+
attr_reader :parameters
|
9
|
+
|
10
|
+
# @return [String] The unique code that is given to the transaction by
|
11
|
+
# Buckaroo's Payment Gateway
|
12
|
+
attr_reader :transaction_id
|
13
|
+
|
14
|
+
# @return [Buckaroo::Ideal::Status] The status of the transaction
|
15
|
+
attr_reader :status
|
16
|
+
|
17
|
+
# @return [String] The reference that was given to the
|
18
|
+
# +Buckaroo::Ideal::Order+
|
19
|
+
attr_reader :reference
|
20
|
+
|
21
|
+
# @return [String] The invoice_number that was given to the
|
22
|
+
# +Buckaroo::Ideal::Order+
|
23
|
+
attr_reader :invoice_number
|
24
|
+
|
25
|
+
# @return [Buckaroo::Ideal::ResponseSignature] The signature of the
|
26
|
+
# transaction, which can be used to validate it's authenticity.
|
27
|
+
attr_reader :signature
|
28
|
+
|
29
|
+
# @return [String] The currency that was used during the transaction
|
30
|
+
attr_reader :currency
|
31
|
+
|
32
|
+
# @return [Time] The date and time of the transaction
|
33
|
+
attr_reader :time
|
34
|
+
|
35
|
+
# @return [String] The timestamp of the transaction
|
36
|
+
attr_reader :timestamp
|
37
|
+
|
38
|
+
# @return [Float] The amount that was transferred during the transaction
|
39
|
+
attr_reader :amount
|
40
|
+
|
41
|
+
# @return [Boolean] Returns +true+ if the transaction was a test, +false+
|
42
|
+
# if it was real
|
43
|
+
attr_reader :test_mode
|
44
|
+
|
45
|
+
def initialize(params = {})
|
46
|
+
@parameters = params
|
47
|
+
@transaction_id = parameters['bpe_trx']
|
48
|
+
@reference = parameters['bpe_reference']
|
49
|
+
@invoice_number = parameters['bpe_invoice']
|
50
|
+
@currency = parameters['bpe_currency']
|
51
|
+
@timestamp = parameters['bpe_timestamp']
|
52
|
+
@time = Time.parse(timestamp)
|
53
|
+
@amount = from_cents(parameters['bpe_amount'])
|
54
|
+
@test_mode = from_numeric_boolean(parameters['bpe_mode'])
|
55
|
+
@status = Status.new(parameters['bpe_result'])
|
56
|
+
@signature = ResponseSignature.new(self, parameters['bpe_signature2'])
|
57
|
+
end
|
58
|
+
|
59
|
+
def valid?
|
60
|
+
signature.valid?
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
include Util
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|