adyen_jpiqueras 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|