adyen_jpiqueras 2.3.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/.gitignore +14 -0
- data/.travis.yml +30 -0
- data/CHANGELOG.md +128 -0
- data/CONTRIBUTING.md +85 -0
- data/Gemfile +11 -0
- data/LICENSE +21 -0
- data/README.md +31 -0
- data/Rakefile +54 -0
- data/adyen_jpiqueras.gemspec +44 -0
- data/config.ru +5 -0
- data/lib/adyen.rb +16 -0
- data/lib/adyen/api.rb +424 -0
- data/lib/adyen/api/cacert.pem +3894 -0
- data/lib/adyen/api/payment_service.rb +374 -0
- data/lib/adyen/api/recurring_service.rb +188 -0
- data/lib/adyen/api/response.rb +61 -0
- data/lib/adyen/api/simple_soap_client.rb +134 -0
- data/lib/adyen/api/templates/payment_service.rb +159 -0
- data/lib/adyen/api/templates/recurring_service.rb +71 -0
- data/lib/adyen/api/test_helpers.rb +133 -0
- data/lib/adyen/api/xml_querier.rb +137 -0
- data/lib/adyen/base.rb +17 -0
- data/lib/adyen/configuration.rb +179 -0
- data/lib/adyen/form.rb +419 -0
- data/lib/adyen/hpp.rb +27 -0
- data/lib/adyen/hpp/request.rb +192 -0
- data/lib/adyen/hpp/response.rb +52 -0
- data/lib/adyen/hpp/signature.rb +34 -0
- data/lib/adyen/matchers.rb +92 -0
- data/lib/adyen/notification_generator.rb +30 -0
- data/lib/adyen/railtie.rb +13 -0
- data/lib/adyen/rest.rb +67 -0
- data/lib/adyen/rest/authorise_payment.rb +234 -0
- data/lib/adyen/rest/authorise_recurring_payment.rb +46 -0
- data/lib/adyen/rest/client.rb +127 -0
- data/lib/adyen/rest/errors.rb +33 -0
- data/lib/adyen/rest/modify_payment.rb +89 -0
- data/lib/adyen/rest/payout.rb +89 -0
- data/lib/adyen/rest/request.rb +104 -0
- data/lib/adyen/rest/response.rb +80 -0
- data/lib/adyen/rest/signature.rb +27 -0
- data/lib/adyen/signature.rb +76 -0
- data/lib/adyen/templates/notification_migration.rb +29 -0
- data/lib/adyen/templates/notification_model.rb +69 -0
- data/lib/adyen/util.rb +147 -0
- data/lib/adyen/version.rb +5 -0
- data/spec/api/api_spec.rb +231 -0
- data/spec/api/payment_service_spec.rb +505 -0
- data/spec/api/recurring_service_spec.rb +236 -0
- data/spec/api/response_spec.rb +59 -0
- data/spec/api/simple_soap_client_spec.rb +133 -0
- data/spec/api/spec_helper.rb +463 -0
- data/spec/api/test_helpers_spec.rb +84 -0
- data/spec/functional/api_spec.rb +117 -0
- data/spec/functional/initializer.rb.ci +3 -0
- data/spec/functional/initializer.rb.sample +3 -0
- data/spec/spec_helper.rb +8 -0
- data/test/form_test.rb +303 -0
- data/test/functional/payment_authorisation_api_test.rb +107 -0
- data/test/functional/payment_modification_api_test.rb +58 -0
- data/test/functional/payout_api_test.rb +93 -0
- data/test/helpers/capybara.rb +12 -0
- data/test/helpers/configure_adyen.rb +6 -0
- data/test/helpers/example_server.rb +136 -0
- data/test/helpers/public/adyen.encrypt.js +679 -0
- data/test/helpers/public/adyen.encrypt.min.js +14 -0
- data/test/helpers/test_cards.rb +20 -0
- data/test/helpers/views/authorized.erb +7 -0
- data/test/helpers/views/hpp.erb +20 -0
- data/test/helpers/views/index.erb +6 -0
- data/test/helpers/views/pay.erb +36 -0
- data/test/helpers/views/redirect_shopper.erb +18 -0
- data/test/hpp/signature_test.rb +37 -0
- data/test/hpp_test.rb +250 -0
- data/test/integration/hpp_integration_test.rb +52 -0
- data/test/integration/payment_using_3d_secure_integration_test.rb +41 -0
- data/test/integration/payment_with_client_side_encryption_integration_test.rb +26 -0
- data/test/rest/signature_test.rb +36 -0
- data/test/rest_list_recurring_details_response_test.rb +22 -0
- data/test/rest_request_test.rb +43 -0
- data/test/rest_response_test.rb +19 -0
- data/test/signature_test.rb +76 -0
- data/test/test_helper.rb +45 -0
- data/test/util_test.rb +78 -0
- data/yard_extensions.rb +16 -0
- metadata +308 -0
data/lib/adyen/hpp.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'adyen/hpp/signature'
|
2
|
+
require 'adyen/hpp/request'
|
3
|
+
require 'adyen/hpp/response'
|
4
|
+
|
5
|
+
module Adyen
|
6
|
+
module HPP
|
7
|
+
|
8
|
+
# The DOMAIN of the Adyen payment system that still requires the current
|
9
|
+
# Adyen enviroment.
|
10
|
+
HPP_DOMAIN = "%s.adyen.com"
|
11
|
+
|
12
|
+
# The URL of the Adyen payment system that still requires the current
|
13
|
+
# domain and payment flow to be filled.
|
14
|
+
HPP_URL = "https://%s/hpp/%s.shtml"
|
15
|
+
|
16
|
+
class Error < Adyen::Error
|
17
|
+
end
|
18
|
+
|
19
|
+
class ForgedResponse < Adyen::HPP::Error
|
20
|
+
end
|
21
|
+
|
22
|
+
class Notification
|
23
|
+
def initialize(request)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
require 'adyen/hpp/signature'
|
2
|
+
require 'cgi'
|
3
|
+
|
4
|
+
module Adyen
|
5
|
+
module HPP
|
6
|
+
|
7
|
+
class Request
|
8
|
+
attr_accessor :parameters
|
9
|
+
attr_writer :skin, :environment, :shared_secret
|
10
|
+
|
11
|
+
# Initialize the HPP request
|
12
|
+
#
|
13
|
+
# @param [Hash] parameters The payment parameters
|
14
|
+
# You must not provide the +:merchant_sig+ parameter: it will be calculated automatically.
|
15
|
+
# @param [Hash|String] skin A skin hash in the same format that is returned by
|
16
|
+
# Adyen::Configuration.register_form_skin, or the name of a registered skin.
|
17
|
+
# When not set, the default skin specified in the configuration will be used.
|
18
|
+
# @param [String] environment The Adyen environment to use.
|
19
|
+
# When not set, the environment specified in the configuration will be used.
|
20
|
+
# @param [String] shared_secret The shared secret to use for signing the request.
|
21
|
+
# When not set, the shared secret of the skin will be used.
|
22
|
+
def initialize(parameters, skin: nil, environment: nil, shared_secret: nil)
|
23
|
+
@parameters, @skin, @environment, @shared_secret = parameters, skin, environment, shared_secret
|
24
|
+
@skin = Adyen.configuration.form_skin_by_name(@skin) unless skin.nil? || skin.is_a?(Hash)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns the Adyen skin to use for the request, in the same format that is
|
28
|
+
# returned by Adyen::Configuration.register_form_skin
|
29
|
+
#
|
30
|
+
# @return [Hash] skin if set, configuration default otherwise
|
31
|
+
def skin
|
32
|
+
@skin || Adyen.configuration.form_skin_by_name(Adyen.configuration.default_skin) || {}
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns the Adyen environment the request will be directed to
|
36
|
+
#
|
37
|
+
# @return [String] environment if set, configuration default otherwise
|
38
|
+
def environment
|
39
|
+
@environment || Adyen.configuration.environment
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns the shared secret to use for signing the request
|
43
|
+
#
|
44
|
+
# @return [String] shared secret if set, the skin's shared secret otherwise
|
45
|
+
def shared_secret
|
46
|
+
@shared_secret || skin[:shared_secret]
|
47
|
+
end
|
48
|
+
|
49
|
+
# Returns the DOMAIN of the Adyen payment system, adjusted for an Adyen environment.
|
50
|
+
#
|
51
|
+
# @return [String] The domain of the Adyen payment system that can be used
|
52
|
+
# for payment forms or redirects.
|
53
|
+
# @see Adyen::HPP::Request.redirect_url
|
54
|
+
def domain
|
55
|
+
(Adyen.configuration.payment_flow_domain || HPP_DOMAIN) % [environment.to_s]
|
56
|
+
end
|
57
|
+
|
58
|
+
# Returns the URL of the Adyen payment system, adjusted for an Adyen environment.
|
59
|
+
#
|
60
|
+
# @param [String] payment_flow The Adyen payment type to use. This parameter can be
|
61
|
+
# left out, in which case the default payment type will be used.
|
62
|
+
# @return [String] The absolute URL of the Adyen payment system that can be used
|
63
|
+
# for payment forms or redirects.
|
64
|
+
# @see Adyen::HPP::Request.domain
|
65
|
+
# @see Adyen::HPP::Request.redirect_url
|
66
|
+
# @see Adyen::HPP::Request.payment_methods_url
|
67
|
+
def url(payment_flow = nil)
|
68
|
+
payment_flow ||= Adyen.configuration.payment_flow
|
69
|
+
HPP_URL % [domain, payment_flow.to_s]
|
70
|
+
end
|
71
|
+
|
72
|
+
# Transforms the payment parameters hash to be in the correct format. It will also
|
73
|
+
# include the Adyen::Configuration#default_form_params hash and it will
|
74
|
+
# include the +:skin_code+ parameter and the default attributes of the skin
|
75
|
+
# Any default parameter value will be overrided if another value is provided in the request.
|
76
|
+
#
|
77
|
+
# @return [Hash] Completed and formatted payment parameters.
|
78
|
+
# @raise [ArgumentError] Thrown if some parameter health check fails.
|
79
|
+
def formatted_parameters
|
80
|
+
raise ArgumentError, "Cannot generate request: parameters should be a hash!" unless parameters.is_a?(Hash)
|
81
|
+
|
82
|
+
formatted_parameters = parameters
|
83
|
+
default_form_parameters = Adyen.configuration.default_form_params
|
84
|
+
unless skin.empty?
|
85
|
+
formatted_parameters[:skin_code] ||= skin[:skin_code]
|
86
|
+
default_form_parameters = default_form_parameters.merge(skin[:default_form_params] || {})
|
87
|
+
end
|
88
|
+
formatted_parameters = default_form_parameters.merge(formatted_parameters)
|
89
|
+
|
90
|
+
raise ArgumentError, "Cannot generate request: :currency code attribute not found!" unless formatted_parameters[:currency_code]
|
91
|
+
raise ArgumentError, "Cannot generate request: :payment_amount code attribute not found!" unless formatted_parameters[:payment_amount]
|
92
|
+
raise ArgumentError, "Cannot generate request: :merchant_account attribute not found!" unless formatted_parameters[:merchant_account]
|
93
|
+
raise ArgumentError, "Cannot generate request: :skin_code attribute not found!" unless formatted_parameters[:skin_code]
|
94
|
+
|
95
|
+
formatted_parameters[:recurring_contract] = 'RECURRING' if formatted_parameters.delete(:recurring) == true
|
96
|
+
formatted_parameters[:order_data] = Adyen::Util.gzip_base64(formatted_parameters.delete(:order_data_raw)) if formatted_parameters[:order_data_raw]
|
97
|
+
formatted_parameters[:ship_before_date] = Adyen::Util.format_date(formatted_parameters[:ship_before_date])
|
98
|
+
formatted_parameters[:session_validity] = Adyen::Util.format_timestamp(formatted_parameters[:session_validity])
|
99
|
+
formatted_parameters
|
100
|
+
end
|
101
|
+
|
102
|
+
# Transforms and flattens payment parameters to be in the correct format which is understood and accepted by adyen
|
103
|
+
#
|
104
|
+
# @return [Hash] The payment parameters, with camelized and prefixed key, stringified values and
|
105
|
+
# the +:merchant_signature+ parameter set.
|
106
|
+
def flat_payment_parameters
|
107
|
+
Adyen::HPP::Signature.sign(Adyen::Util.flatten(formatted_parameters), shared_secret)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Returns an absolute URL to the Adyen payment system, with the payment parameters included
|
111
|
+
# as GET parameters in the URL. The URL also depends on the Adyen enviroment
|
112
|
+
#
|
113
|
+
# Note that Internet Explorer has a maximum length for URLs it can handle (2083 characters).
|
114
|
+
# Make sure that the URL is not longer than this limit if you want your site to work in IE.
|
115
|
+
#
|
116
|
+
# @example
|
117
|
+
#
|
118
|
+
# def pay
|
119
|
+
# # Generate a URL to redirect to Adyen's payment system.
|
120
|
+
# payment_parameters = {
|
121
|
+
# :currency_code => 'USD',
|
122
|
+
# :payment_amount => 1000,
|
123
|
+
# :merchant_account => 'MyMerchant',
|
124
|
+
# ...
|
125
|
+
# }
|
126
|
+
# hpp_request = Adyen::HPP::Request.new(payment_parameters, skin: :my_skin, environment: :test)
|
127
|
+
#
|
128
|
+
# respond_to do |format|
|
129
|
+
# format.html { redirect_to(hpp_request.redirect_url) }
|
130
|
+
# end
|
131
|
+
# end
|
132
|
+
#
|
133
|
+
# @return [String] An absolute URL to redirect to the Adyen payment system.
|
134
|
+
def redirect_url
|
135
|
+
url + '?' + flat_payment_parameters.map { |(k, v)|
|
136
|
+
"#{CGI.escape(k)}=#{CGI.escape(v)}"
|
137
|
+
}.join('&')
|
138
|
+
end
|
139
|
+
|
140
|
+
# @see Adyen::HPP::Request.redirect_url
|
141
|
+
#
|
142
|
+
# Returns an absolute URL very similar to the one returned by Adyen::HPP::Request.redirect_url
|
143
|
+
# except that it uses the directory.shtml call which returns a list of all available
|
144
|
+
# payment methods
|
145
|
+
#
|
146
|
+
# @return [String] An absolute URL to redirect to the Adyen payment system.
|
147
|
+
def payment_methods_url
|
148
|
+
url(:directory) + '?' + flat_payment_parameters.map { |(k, v)|
|
149
|
+
"#{CGI.escape(k)}=#{CGI.escape(v)}"
|
150
|
+
}.join('&')
|
151
|
+
end
|
152
|
+
|
153
|
+
# Returns a HTML snippet of hidden INPUT tags with the provided payment parameters.
|
154
|
+
# The snippet can be included in a payment form that POSTs to the Adyen payment system.
|
155
|
+
#
|
156
|
+
# The payment parameters that are provided to this method will be merged with the
|
157
|
+
# {Adyen::Configuration#default_form_params} hash. The default parameter values will be
|
158
|
+
# overrided if another value is provided to this method.
|
159
|
+
#
|
160
|
+
# You do not have to provide the +:merchant_sig+ parameter: it will be calculated automatically.
|
161
|
+
#
|
162
|
+
# @example
|
163
|
+
#
|
164
|
+
# <%
|
165
|
+
# payment_parameters = {
|
166
|
+
# :currency_code => 'USD',
|
167
|
+
# :payment_amount => 1000,
|
168
|
+
# :merchant_account => 'MyMerchant',
|
169
|
+
# ...
|
170
|
+
# }
|
171
|
+
# hpp_request = Adyen::HPP::Request.new(payment_parameters, skin: :my_skin, environment: :test)
|
172
|
+
# %>
|
173
|
+
#
|
174
|
+
# <%= form_tag(hpp_request.url, authenticity_token: false, enforce_utf8: false) do %>
|
175
|
+
# <%= hpp_request.hidden_fields %>
|
176
|
+
# <%= submit_tag("Pay invoice")
|
177
|
+
# <% end %>
|
178
|
+
#
|
179
|
+
# @return [String] An HTML snippet that can be included in a form that POSTs to the
|
180
|
+
# Adyen payment system.
|
181
|
+
def hidden_fields
|
182
|
+
|
183
|
+
# Generate a hidden input tag per parameter, join them by newlines.
|
184
|
+
form_str = flat_payment_parameters.map { |key, value|
|
185
|
+
"<input type=\"hidden\" name=\"#{CGI.escapeHTML(key)}\" value=\"#{CGI.escapeHTML(value)}\" />"
|
186
|
+
}.join("\n")
|
187
|
+
|
188
|
+
form_str.respond_to?(:html_safe) ? form_str.html_safe : form_str
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Adyen
|
2
|
+
module HPP
|
3
|
+
|
4
|
+
class Response
|
5
|
+
attr_reader :params, :shared_secret
|
6
|
+
|
7
|
+
# Initialize the HPP response
|
8
|
+
#
|
9
|
+
# @param [Hash] params params A hash of HTTP GET parameters for the redirect request. This
|
10
|
+
# should include the +:merchantSig+ parameter, which contains the signature.
|
11
|
+
# @param [String] shared_secret Optional shared secret; if not provided, the shared secret
|
12
|
+
# of the skin determined by params['skinCode'] will be used
|
13
|
+
def initialize(params, shared_secret: nil)
|
14
|
+
raise ArgumentError, "params should be a Hash" unless params.is_a?(Hash)
|
15
|
+
raise ArgumentError, "params should contain :merchantSig" unless params.key?('merchantSig')
|
16
|
+
|
17
|
+
@params = params
|
18
|
+
skin = Adyen.configuration.form_skin_by_code(params['skinCode']) || {}
|
19
|
+
@shared_secret = shared_secret || skin[:shared_secret]
|
20
|
+
end
|
21
|
+
|
22
|
+
# Checks the redirect signature for this request by calculating the signature from
|
23
|
+
# the provided parameters, and comparing it to the signature provided in the +merchantSig+
|
24
|
+
# parameter.
|
25
|
+
#
|
26
|
+
# If this method returns false, the request could be a forgery and should not be handled.
|
27
|
+
# Therefore, you should include this check in a +before_filter+, and raise an error of the
|
28
|
+
# signature check fails.
|
29
|
+
#
|
30
|
+
# @example
|
31
|
+
# class PaymentsController < ApplicationController
|
32
|
+
# before_filter :check_signature, :only => [:return_from_adyen]
|
33
|
+
#
|
34
|
+
# def return_from_adyen
|
35
|
+
# @invoice = Invoice.find(params[:merchantReference])
|
36
|
+
# @invoice.set_paid! if params[:authResult] == 'AUTHORISED'
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# private
|
40
|
+
#
|
41
|
+
# def check_signature
|
42
|
+
# raise "Forgery!" unless Adyen::HPP::Response.new(params).has_valid_signature?
|
43
|
+
# end
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# @return [true, false] Returns true only if the signature in the parameters is correct.
|
47
|
+
def has_valid_signature?
|
48
|
+
Adyen::HPP::Signature.verify(params, shared_secret)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'adyen/signature'
|
2
|
+
|
3
|
+
module Adyen
|
4
|
+
module HPP
|
5
|
+
# The Signature module can sign and verify HMAC SHA-256 signatures for Hosted Payment Pages
|
6
|
+
module Signature
|
7
|
+
extend self
|
8
|
+
|
9
|
+
# Sign the parameters with the given shared secret
|
10
|
+
# @param [Hash] params The set of parameters to sign.
|
11
|
+
# @param [String] shared_secret The shared secret for signing.
|
12
|
+
# @return [Hash] params The params that were passed in plus a new `merchantSig` param
|
13
|
+
def sign(params, shared_secret)
|
14
|
+
params = params.dup
|
15
|
+
params.delete('merchantSig')
|
16
|
+
params["sharedSecret"] ||= shared_secret
|
17
|
+
params.merge('merchantSig' => Adyen::Signature.sign(params))
|
18
|
+
end
|
19
|
+
|
20
|
+
# Verify the parameters with the given shared secret
|
21
|
+
# @param [Hash] params The set of parameters to verify. Must include a `merchantSig`
|
22
|
+
# param that will be compared to the signature we calculate.
|
23
|
+
# @param [String] shared_secret The shared secret for verification.
|
24
|
+
# @return [Boolean] true if the `merchantSig` in the params matches our calculated signature
|
25
|
+
def verify(params, shared_secret)
|
26
|
+
params = params.dup
|
27
|
+
params["sharedSecret"] ||= shared_secret
|
28
|
+
their_sig = params.delete('merchantSig')
|
29
|
+
raise ArgumentError, "params must include 'merchantSig' for verification" if their_sig.empty?
|
30
|
+
Adyen::Signature.verify(params, their_sig)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'adyen/api/xml_querier'
|
2
|
+
|
3
|
+
module Adyen
|
4
|
+
module Matchers
|
5
|
+
|
6
|
+
module XPathPaymentFormCheck
|
7
|
+
|
8
|
+
def self.build_xpath_query(checks)
|
9
|
+
# Start by finding the check for the Adyen form tag
|
10
|
+
xpath_query = "//form[@id='adyen']"
|
11
|
+
|
12
|
+
# Add recurring/single check if specified
|
13
|
+
recurring = checks.delete(:recurring)
|
14
|
+
unless recurring.nil?
|
15
|
+
if recurring
|
16
|
+
xpath_query << "[descendant::input[@type='hidden'][@name='recurringContract']]"
|
17
|
+
else
|
18
|
+
xpath_query << "[not(descendant::input[@type='hidden'][@name='recurringContract'])]"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Add a check for all the other fields specified
|
23
|
+
checks.each do |key, value|
|
24
|
+
condition = "\n descendant::input[@type='hidden'][@name='#{Adyen::Util.camelize(key)}']"
|
25
|
+
condition << "[@value='#{value}']" unless value == :anything
|
26
|
+
xpath_query << "[#{condition}]"
|
27
|
+
end
|
28
|
+
|
29
|
+
return xpath_query
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.check(subject, checks = {})
|
33
|
+
document = Adyen::API::XMLQuerier.html(subject)
|
34
|
+
result = document.xpath(build_xpath_query(checks))
|
35
|
+
!result.empty?
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
class HaveAdyenPaymentForm
|
40
|
+
|
41
|
+
def initialize(checks)
|
42
|
+
@checks = checks
|
43
|
+
end
|
44
|
+
|
45
|
+
def matches?(document)
|
46
|
+
Adyen::Matchers::XPathPaymentFormCheck.check(document, @checks)
|
47
|
+
end
|
48
|
+
|
49
|
+
def description
|
50
|
+
"have an adyen payment form"
|
51
|
+
end
|
52
|
+
|
53
|
+
def failure_message
|
54
|
+
"expected to find a valid Adyen form on this page"
|
55
|
+
end
|
56
|
+
|
57
|
+
def negative_failure_message
|
58
|
+
"expected not to find a valid Adyen form on this page"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def have_adyen_payment_form(checks = {})
|
63
|
+
default_checks = {:merchant_sig => :anything, :payment_amount => :anything, :currency_code => :anything, :skin_code => :anything }
|
64
|
+
HaveAdyenPaymentForm.new(default_checks.merge(checks))
|
65
|
+
end
|
66
|
+
|
67
|
+
def have_adyen_recurring_payment_form(checks = {})
|
68
|
+
recurring_checks = { :recurring => true, :shopper_email => :anything, :shopper_reference => :anything }
|
69
|
+
have_adyen_payment_form(recurring_checks.merge(checks))
|
70
|
+
end
|
71
|
+
|
72
|
+
def have_adyen_single_payment_form(checks = {})
|
73
|
+
recurring_checks = { :recurring => false }
|
74
|
+
have_adyen_payment_form(recurring_checks.merge(checks))
|
75
|
+
end
|
76
|
+
|
77
|
+
def assert_adyen_payment_form(subject, checks = {})
|
78
|
+
default_checks = {:merchant_sig => :anything, :payment_amount => :anything, :currency_code => :anything, :skin_code => :anything }
|
79
|
+
assert Adyen::Matchers::XPathPaymentFormCheck.check(subject, default_checks.merge(checks)), 'No Adyen payment form found'
|
80
|
+
end
|
81
|
+
|
82
|
+
def assert_adyen_recurring_payment_form(subject, checks = {})
|
83
|
+
recurring_checks = { :recurring => true, :shopper_email => :anything, :shopper_reference => :anything }
|
84
|
+
assert_adyen_payment_form(subject, recurring_checks.merge(checks))
|
85
|
+
end
|
86
|
+
|
87
|
+
def assert_adyen_single_payment_form(subject, checks = {})
|
88
|
+
recurring_checks = { :recurring => false }
|
89
|
+
assert_adyen_payment_form(subject, recurring_checks.merge(checks))
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/migration'
|
3
|
+
|
4
|
+
# @private
|
5
|
+
class Adyen::NotificationGenerator < Rails::Generators::Base
|
6
|
+
include Rails::Generators::Migration
|
7
|
+
|
8
|
+
def self.source_root
|
9
|
+
@source_root ||= File.join(File.dirname(__FILE__), 'templates')
|
10
|
+
end
|
11
|
+
|
12
|
+
# Implement the required interface for Rails::Generators::Migration.
|
13
|
+
# taken from http://github.com/rails/rails/blob/master/activerecord/lib/generators/active_record.rb
|
14
|
+
def self.next_migration_number(dirname)
|
15
|
+
if ActiveRecord::Base.timestamped_migrations
|
16
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
17
|
+
else
|
18
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Create a migration file for the adyen_notifications table
|
23
|
+
def create_migration_file
|
24
|
+
migration_template 'notification_migration.rb', 'db/migrate/create_adyen_notifications.rb'
|
25
|
+
end
|
26
|
+
|
27
|
+
def create_model_file
|
28
|
+
template 'notification_model.rb', 'app/models/adyen_notification.rb'
|
29
|
+
end
|
30
|
+
end
|