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.
Files changed (87) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.travis.yml +30 -0
  4. data/CHANGELOG.md +128 -0
  5. data/CONTRIBUTING.md +85 -0
  6. data/Gemfile +11 -0
  7. data/LICENSE +21 -0
  8. data/README.md +31 -0
  9. data/Rakefile +54 -0
  10. data/adyen_jpiqueras.gemspec +44 -0
  11. data/config.ru +5 -0
  12. data/lib/adyen.rb +16 -0
  13. data/lib/adyen/api.rb +424 -0
  14. data/lib/adyen/api/cacert.pem +3894 -0
  15. data/lib/adyen/api/payment_service.rb +374 -0
  16. data/lib/adyen/api/recurring_service.rb +188 -0
  17. data/lib/adyen/api/response.rb +61 -0
  18. data/lib/adyen/api/simple_soap_client.rb +134 -0
  19. data/lib/adyen/api/templates/payment_service.rb +159 -0
  20. data/lib/adyen/api/templates/recurring_service.rb +71 -0
  21. data/lib/adyen/api/test_helpers.rb +133 -0
  22. data/lib/adyen/api/xml_querier.rb +137 -0
  23. data/lib/adyen/base.rb +17 -0
  24. data/lib/adyen/configuration.rb +179 -0
  25. data/lib/adyen/form.rb +419 -0
  26. data/lib/adyen/hpp.rb +27 -0
  27. data/lib/adyen/hpp/request.rb +192 -0
  28. data/lib/adyen/hpp/response.rb +52 -0
  29. data/lib/adyen/hpp/signature.rb +34 -0
  30. data/lib/adyen/matchers.rb +92 -0
  31. data/lib/adyen/notification_generator.rb +30 -0
  32. data/lib/adyen/railtie.rb +13 -0
  33. data/lib/adyen/rest.rb +67 -0
  34. data/lib/adyen/rest/authorise_payment.rb +234 -0
  35. data/lib/adyen/rest/authorise_recurring_payment.rb +46 -0
  36. data/lib/adyen/rest/client.rb +127 -0
  37. data/lib/adyen/rest/errors.rb +33 -0
  38. data/lib/adyen/rest/modify_payment.rb +89 -0
  39. data/lib/adyen/rest/payout.rb +89 -0
  40. data/lib/adyen/rest/request.rb +104 -0
  41. data/lib/adyen/rest/response.rb +80 -0
  42. data/lib/adyen/rest/signature.rb +27 -0
  43. data/lib/adyen/signature.rb +76 -0
  44. data/lib/adyen/templates/notification_migration.rb +29 -0
  45. data/lib/adyen/templates/notification_model.rb +69 -0
  46. data/lib/adyen/util.rb +147 -0
  47. data/lib/adyen/version.rb +5 -0
  48. data/spec/api/api_spec.rb +231 -0
  49. data/spec/api/payment_service_spec.rb +505 -0
  50. data/spec/api/recurring_service_spec.rb +236 -0
  51. data/spec/api/response_spec.rb +59 -0
  52. data/spec/api/simple_soap_client_spec.rb +133 -0
  53. data/spec/api/spec_helper.rb +463 -0
  54. data/spec/api/test_helpers_spec.rb +84 -0
  55. data/spec/functional/api_spec.rb +117 -0
  56. data/spec/functional/initializer.rb.ci +3 -0
  57. data/spec/functional/initializer.rb.sample +3 -0
  58. data/spec/spec_helper.rb +8 -0
  59. data/test/form_test.rb +303 -0
  60. data/test/functional/payment_authorisation_api_test.rb +107 -0
  61. data/test/functional/payment_modification_api_test.rb +58 -0
  62. data/test/functional/payout_api_test.rb +93 -0
  63. data/test/helpers/capybara.rb +12 -0
  64. data/test/helpers/configure_adyen.rb +6 -0
  65. data/test/helpers/example_server.rb +136 -0
  66. data/test/helpers/public/adyen.encrypt.js +679 -0
  67. data/test/helpers/public/adyen.encrypt.min.js +14 -0
  68. data/test/helpers/test_cards.rb +20 -0
  69. data/test/helpers/views/authorized.erb +7 -0
  70. data/test/helpers/views/hpp.erb +20 -0
  71. data/test/helpers/views/index.erb +6 -0
  72. data/test/helpers/views/pay.erb +36 -0
  73. data/test/helpers/views/redirect_shopper.erb +18 -0
  74. data/test/hpp/signature_test.rb +37 -0
  75. data/test/hpp_test.rb +250 -0
  76. data/test/integration/hpp_integration_test.rb +52 -0
  77. data/test/integration/payment_using_3d_secure_integration_test.rb +41 -0
  78. data/test/integration/payment_with_client_side_encryption_integration_test.rb +26 -0
  79. data/test/rest/signature_test.rb +36 -0
  80. data/test/rest_list_recurring_details_response_test.rb +22 -0
  81. data/test/rest_request_test.rb +43 -0
  82. data/test/rest_response_test.rb +19 -0
  83. data/test/signature_test.rb +76 -0
  84. data/test/test_helper.rb +45 -0
  85. data/test/util_test.rb +78 -0
  86. data/yard_extensions.rb +16 -0
  87. metadata +308 -0
@@ -0,0 +1,84 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'api/spec_helper'
4
+ require 'adyen/api/test_helpers'
5
+
6
+ describe "Test helpers" do
7
+ include APISpecHelper
8
+
9
+ after do
10
+ Net::HTTP.stubbing_enabled = false
11
+ end
12
+
13
+ describe Adyen::API::PaymentService do
14
+ before do
15
+ @params = {
16
+ :reference => 'order-id',
17
+ :amount => {
18
+ :currency => 'EUR',
19
+ :value => '1234',
20
+ },
21
+ :shopper => {
22
+ :email => 's.hopper@example.com',
23
+ :reference => 'user-id',
24
+ :ip => '61.294.12.12',
25
+ :statement => 'Invoice number 123456'
26
+ },
27
+ :card => {
28
+ :expiry_month => 12,
29
+ :expiry_year => 2012,
30
+ :holder_name => 'Simon わくわく Hopper',
31
+ :number => '4444333322221111',
32
+ :cvc => '737',
33
+ # Maestro UK/Solo only
34
+ #:issue_number => ,
35
+ #:start_month => ,
36
+ #:start_year => ,
37
+ }
38
+ }
39
+ @payment = @object = Adyen::API::PaymentService.new(@params)
40
+ end
41
+
42
+ it "returns an `authorized' response" do
43
+ stub_net_http(AUTHORISATION_DECLINED_RESPONSE)
44
+ Adyen::API::PaymentService.stub_success!
45
+ @payment.authorise_payment.should be_authorized
46
+
47
+ @payment.authorise_payment.should_not be_authorized
48
+ end
49
+
50
+ it "returns a `refused' response" do
51
+ stub_net_http(AUTHORISE_RESPONSE)
52
+ Adyen::API::PaymentService.stub_refused!
53
+ response = @payment.authorise_payment
54
+ response.should_not be_authorized
55
+ response.should_not be_invalid_request
56
+
57
+ @payment.authorise_payment.should be_authorized
58
+ end
59
+
60
+ it "returns a `invalid request' response" do
61
+ stub_net_http(AUTHORISE_RESPONSE)
62
+ Adyen::API::PaymentService.stub_invalid!
63
+ response = @payment.authorise_payment
64
+ response.should_not be_authorized
65
+ response.should be_invalid_request
66
+
67
+ @payment.authorise_payment.should be_authorized
68
+ end
69
+ end
70
+
71
+ describe Adyen::API::RecurringService do
72
+ before do
73
+ @params = { :shopper => { :reference => 'user-id' } }
74
+ @recurring = @object = Adyen::API::RecurringService.new(@params)
75
+ end
76
+
77
+ it "returns a `disabled' response" do
78
+ stub_net_http(DISABLE_RESPONSE % 'nope')
79
+ Adyen::API::RecurringService.stub_disabled!
80
+ @recurring.disable.should be_disabled
81
+ @recurring.disable.should_not be_disabled
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,117 @@
1
+ # encoding: UTF-8
2
+ require 'api/spec_helper'
3
+ require 'nokogiri'
4
+
5
+ API_SPEC_INITIALIZER = File.expand_path("../initializer.rb", __FILE__)
6
+
7
+ if File.exist?(API_SPEC_INITIALIZER)
8
+
9
+ describe Adyen::API, "with an actual remote connection" do
10
+
11
+ before :all do
12
+ require API_SPEC_INITIALIZER
13
+ Net::HTTP.stubbing_enabled = false
14
+ @order_id = @user_id = Time.now.to_i
15
+ @payment_response = perform_payment_request
16
+ end
17
+
18
+ after :all do
19
+ Net::HTTP.stubbing_enabled = true
20
+ end
21
+
22
+ it "performs a payment request" do
23
+ @payment_response.should be_authorized
24
+ @payment_response.psp_reference.should_not be_empty
25
+ end
26
+
27
+ def perform_payment_request
28
+ Adyen::API.authorise_payment(
29
+ @order_id,
30
+ { :currency => 'EUR', :value => '1234' },
31
+ { :email => "#{@user_id}@example.com", :reference => @user_id },
32
+ { :expiry_month => '08', :expiry_year => '2018', :holder_name => "Simon #{@user_id} Hopper", :number => '4111111111111111', :cvc => '737' },
33
+ true
34
+ )
35
+ end
36
+
37
+ it "performs a recurring payment request" do
38
+ response = Adyen::API.authorise_recurring_payment(
39
+ @order_id,
40
+ { :currency => 'EUR', :value => '1234' },
41
+ { :email => "#{@user_id}@example.com", :reference => @user_id }
42
+ )
43
+ response.should be_authorized
44
+ response.psp_reference.should_not be_empty
45
+ end
46
+
47
+ it "performs a one-click payment request" do
48
+ detail = Adyen::API.list_recurring_details(@user_id).references.last
49
+ response = Adyen::API.authorise_one_click_payment(
50
+ @order_id,
51
+ { :currency => 'EUR', :value => '1234' },
52
+ { :email => "#{@user_id}@example.com", :reference => @user_id },
53
+ { :cvc => '737' },
54
+ detail
55
+ )
56
+ response.should be_authorized
57
+ response.psp_reference.should_not be_empty
58
+ end
59
+
60
+ it "stores the provided ELV account details" do
61
+ response = Adyen::API.store_recurring_token(
62
+ { :email => "#{@user_id}@example.com", :reference => @user_id },
63
+ { :bank_location => "Berlin", :bank_name => "TestBank", :bank_location_id => "12345678", :holder_name => "Simon #{@user_id} Hopper", :number => "1234567890" }
64
+ )
65
+ response.should be_stored
66
+ response.recurring_detail_reference.should_not be_empty
67
+ end
68
+
69
+ it "stores the provided creditcard details" do
70
+ response = Adyen::API.store_recurring_token(
71
+ { :email => "#{@user_id}@example.com", :reference => @user_id },
72
+ { :expiry_month => '08', :expiry_year => '2018', :holder_name => "Simon #{@user_id} Hopper", :number => '4111111111111111' }
73
+ )
74
+ response.should be_stored
75
+ response.recurring_detail_reference.should_not be_empty
76
+ end
77
+
78
+ it "disables a recurring contract" do
79
+ response = Adyen::API.disable_recurring_contract(@user_id)
80
+ response.should be_success
81
+ response.should be_disabled
82
+ end
83
+
84
+ it "captures a payment" do
85
+ response = Adyen::API.capture_payment(@payment_response.psp_reference, { :currency => 'EUR', :value => '1234' })
86
+ response.should be_success
87
+ end
88
+
89
+ it "refunds a payment" do
90
+ response = Adyen::API.refund_payment(@payment_response.psp_reference, { :currency => 'EUR', :value => '1234' })
91
+ response.should be_success
92
+ end
93
+
94
+ it "cancels or refunds a payment" do
95
+ response = Adyen::API.cancel_or_refund_payment(@payment_response.psp_reference)
96
+ response.should be_success
97
+ end
98
+
99
+ it "cancels a payment" do
100
+ response = Adyen::API.cancel_payment(@payment_response.psp_reference)
101
+ response.should be_success
102
+ end
103
+
104
+ it "generates a billet" do
105
+ response = Adyen::API.generate_billet("{\"user_id\":66722,\"order_id\":6863}#signup",
106
+ { currency: "BRL", value: 1000 },
107
+ { first_name: "Jow", last_name: "Silver" },
108
+ "19762003691",
109
+ "boletobancario_santander",
110
+ "2014-07-16T18:16:11Z")
111
+ response.should be_success
112
+ end
113
+ end
114
+
115
+ else
116
+ puts "[!] To run the functional tests you'll need to create `spec/functional/initializer.rb' and configure with your test account settings. See `spec/functional/initializer.rb.sample'."
117
+ end
@@ -0,0 +1,3 @@
1
+ Adyen.configuration.default_api_params = { :merchant_account => ENV['ADYEN_MERCHANT_ACCOUNT'] }
2
+ Adyen.configuration.api_username = ENV['ADYEN_API_USERNAME']
3
+ Adyen.configuration.api_password = ENV['ADYEN_API_PASSWORD']
@@ -0,0 +1,3 @@
1
+ Adyen.configuration.default_api_params = { :merchant_account => 'SuperShopperCOM' }
2
+ Adyen.configuration.api_username = 'ws@company.SuperShopper'
3
+ Adyen.configuration.api_password = '$ecret'
@@ -0,0 +1,8 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'rspec'
4
+ require 'adyen/matchers'
5
+
6
+ RSpec.configure do |config|
7
+ config.include Adyen::Matchers
8
+ end
data/test/form_test.rb ADDED
@@ -0,0 +1,303 @@
1
+ require 'test_helper'
2
+ require 'adyen/form'
3
+
4
+ class FormTest < Minitest::Test
5
+ include Adyen::Matchers
6
+ include Adyen::Test::EachXMLBackend
7
+
8
+ def setup
9
+ Adyen.configuration.default_form_params[:merchant_account] = 'TestMerchant'
10
+ Adyen.configuration.register_form_skin(:testing, '4aD37dJA', 'Kah942*$7sdp0)')
11
+ Adyen.configuration.register_form_skin(:other, 'sk1nC0de', 'shared_secret', merchant_account: 'OtherMerchant')
12
+
13
+ # Use autodetection for the environment unless otherwise specified
14
+ Adyen.configuration.environment = nil
15
+ Adyen.configuration.payment_flow = :select
16
+ Adyen.configuration.payment_flow_domain = nil
17
+
18
+ @payment_attributes = {
19
+ :skin => :testing,
20
+ :currency_code => 'GBP',
21
+ :payment_amount => 10000,
22
+ :merchant_reference => 'Internet Order 12345',
23
+ :ship_before_date => '2007-10-20',
24
+ :session_validity => '2007-10-11T11:00:00Z',
25
+ :billing_address => {
26
+ :street => 'Alexanderplatz',
27
+ :house_number_or_name => '0815',
28
+ :city => 'Berlin',
29
+ :postal_code => '10119',
30
+ :state_or_province => 'Berlin',
31
+ :country => 'Germany',
32
+ },
33
+ :delivery_address => {
34
+ :street => 'Pecunialaan',
35
+ :house_number_or_name => '316',
36
+ :city => 'Geldrop',
37
+ :state_or_province => 'None',
38
+ :postal_code => '1234 AB',
39
+ :country => 'Netherlands',
40
+ },
41
+ :shopper => {
42
+ :telephone_number => '1234512345',
43
+ :first_name => 'John',
44
+ :last_name => 'Doe',
45
+ :social_security_number => '123-45-1234'
46
+ },
47
+ :openinvoicedata => {
48
+ :number_of_lines => 1,
49
+ :line1 => {
50
+ :number_of_items => 2,
51
+ :item_amount => 4000,
52
+ :currency_code => 'GBP',
53
+ :item_vat_amount => 1000,
54
+ :item_vat_percentage => 2500,
55
+ :item_vat_category => 'High',
56
+ :description => 'Product Awesome'
57
+ },
58
+ :refund_description => 'Refund for 12345'
59
+ }
60
+ }
61
+
62
+ @recurring_payment_attributes = @payment_attributes.merge(
63
+ :skin => :other,
64
+ :recurring_contract => 'DEFAULT',
65
+ :shopper_reference => 'grasshopper52',
66
+ :shopper_email => 'gras.shopper@somewhere.org'
67
+ )
68
+
69
+ Adyen::Form.do_parameter_transformations!(@payment_attributes)
70
+ Adyen::Form.do_parameter_transformations!(@recurring_payment_attributes)
71
+ end
72
+
73
+ def test_autodetected_redirect_url
74
+ assert_equal 'https://test.adyen.com/hpp/select.shtml', Adyen::Form.url
75
+
76
+ Adyen.configuration.stubs(:autodetect_environment).returns('live')
77
+ assert_equal 'https://live.adyen.com/hpp/select.shtml', Adyen::Form.url
78
+ end
79
+
80
+ def test_explicit_redirect_url
81
+ assert_equal 'https://live.adyen.com/hpp/select.shtml', Adyen::Form.url(:live)
82
+ assert_equal 'https://test.adyen.com/hpp/select.shtml', Adyen::Form.url(:test)
83
+
84
+ Adyen.configuration.environment = :live
85
+ assert_equal 'https://live.adyen.com/hpp/select.shtml', Adyen::Form.url
86
+ end
87
+
88
+ def test_redirect_url_for_different_payment_flows
89
+ Adyen.configuration.payment_flow = :select
90
+ assert_equal 'https://test.adyen.com/hpp/select.shtml', Adyen::Form.url
91
+
92
+ Adyen.configuration.payment_flow = :pay
93
+ assert_equal 'https://test.adyen.com/hpp/pay.shtml', Adyen::Form.url
94
+
95
+ Adyen.configuration.payment_flow = :details
96
+ assert_equal 'https://test.adyen.com/hpp/details.shtml', Adyen::Form.url
97
+ end
98
+
99
+ def test_redirect_url_for_custom_domain
100
+ Adyen.configuration.payment_flow_domain = "checkout.mydomain.com"
101
+ assert_equal 'https://checkout.mydomain.com/hpp/select.shtml', Adyen::Form.url
102
+ end
103
+
104
+ def test_redirect_url_generation
105
+ attributes = {
106
+ :currency_code => 'GBP', :payment_amount => 10000, :ship_before_date => Date.today,
107
+ :merchant_reference => 'Internet Order 12345', :skin => :testing, :session_validity => Time.now + 3600
108
+ }
109
+
110
+ redirect_uri = URI(Adyen::Form.redirect_url(attributes))
111
+ assert_match %r[^#{Adyen::Form.url}], redirect_uri.to_s
112
+
113
+ params = CGI.parse(redirect_uri.query)
114
+ attributes.each do |key, value|
115
+ assert_equal value.to_s, params[Adyen::Util.camelize(key).to_s].first
116
+ end
117
+
118
+ assert params.key?('merchantSig'), "Expected a merchantSig parameter to be set"
119
+ end
120
+
121
+ def test_payment_methods_url_generation
122
+ attributes = {
123
+ :currency_code => 'GBP', :payment_amount => 10000, :ship_before_date => Date.today,
124
+ :merchant_reference => 'Internet Order 12345', :skin => :testing, :session_validity => Time.now + 3600
125
+ }
126
+
127
+ redirect_uri = URI(Adyen::Form.payment_methods_url(attributes))
128
+ assert_match %r[^#{Adyen::Form.url(nil, :directory)}], redirect_uri.to_s
129
+
130
+ params = CGI.parse(redirect_uri.query)
131
+ attributes.each do |key, value|
132
+ assert_equal value.to_s, params[Adyen::Util.camelize(key).to_s].first
133
+ end
134
+
135
+ assert params.key?('merchantSig'), "Expected a merchantSig parameter to be set"
136
+ end
137
+
138
+ def test_redirect_signature_string
139
+ signature_string = Adyen::Form.calculate_signature_string(@payment_attributes)
140
+ assert_equal "10000GBP2007-10-20Internet Order 123454aD37dJATestMerchant2007-10-11T11:00:00Z", signature_string
141
+
142
+ signature_string = Adyen::Form.calculate_signature_string(@payment_attributes.merge(:merchant_return_data => 'testing123'))
143
+ assert_equal "10000GBP2007-10-20Internet Order 123454aD37dJATestMerchant2007-10-11T11:00:00Ztesting123", signature_string
144
+
145
+ signature_string = Adyen::Form.calculate_signature_string(@recurring_payment_attributes)
146
+ assert_equal "10000GBP2007-10-20Internet Order 12345sk1nC0deOtherMerchant2007-10-11T11:00:00Zgras.shopper@somewhere.orggrasshopper52DEFAULT", signature_string
147
+
148
+ signature_string = Adyen::Form.calculate_signature_string(@payment_attributes.merge(:billing_address_type => '1', :delivery_address_type => '2'))
149
+ assert_equal "10000GBP2007-10-20Internet Order 123454aD37dJATestMerchant2007-10-11T11:00:00Z12", signature_string
150
+
151
+ signature_string = Adyen::Form.calculate_signature_string(@payment_attributes.merge(:delivery_address_type => '2', :shopper_type => '1'))
152
+ assert_equal "10000GBP2007-10-20Internet Order 123454aD37dJATestMerchant2007-10-11T11:00:00Z21", signature_string
153
+ end
154
+
155
+ def test_redirect_signature
156
+ assert_equal 'x58ZcRVL1H6y+XSeBGrySJ9ACVo=', Adyen::Form.calculate_signature(@payment_attributes)
157
+ assert_equal 'EZtZS/33I6qsXptTfRIFMJxeKFE=', Adyen::Form.calculate_signature(@recurring_payment_attributes)
158
+
159
+ @payment_attributes.delete(:shared_secret)
160
+ assert_raises(ArgumentError) { Adyen::Form.calculate_signature(@payment_attributes) }
161
+ end
162
+
163
+ def test_shopper_signature
164
+ signature_string = Adyen::Form.calculate_shopper_signature_string(@payment_attributes[:shopper])
165
+ assert_equal "JohnDoe1234512345", signature_string
166
+ assert_equal 'rb2GEs1kGKuLh255a3QRPBYXmsQ=', Adyen::Form.calculate_shopper_signature(@payment_attributes)
167
+
168
+ @payment_attributes.delete(:shared_secret)
169
+ assert_raises(ArgumentError) { Adyen::Form.calculate_shopper_signature(@payment_attributes) }
170
+ end
171
+
172
+ def test_billing_address_signature
173
+ signature_string = Adyen::Form.calculate_billing_address_signature_string(@payment_attributes[:billing_address])
174
+ assert_equal "Alexanderplatz0815Berlin10119BerlinGermany", signature_string
175
+ assert_equal '5KQb7VJq4cz75cqp11JDajntCY4=', Adyen::Form.calculate_billing_address_signature(@payment_attributes)
176
+
177
+ @payment_attributes.delete(:shared_secret)
178
+ assert_raises(ArgumentError) { Adyen::Form.calculate_billing_address_signature(@payment_attributes) }
179
+ end
180
+
181
+ def test_delivery_address_signature
182
+ signature_string = Adyen::Form.calculate_delivery_address_signature_string(@payment_attributes[:delivery_address])
183
+ assert_equal "Pecunialaan316Geldrop1234 ABNoneNetherlands", signature_string
184
+ assert_equal 'g8wPEWYrDPatkGXzuQbN1++JVbE=', Adyen::Form.calculate_delivery_address_signature(@payment_attributes)
185
+
186
+ @payment_attributes.delete(:shared_secret)
187
+ assert_raises(ArgumentError) { Adyen::Form.calculate_delivery_address_signature(@payment_attributes) }
188
+ end
189
+
190
+ def test_open_invoice_signature
191
+ merchant_sig = Adyen::Form.calculate_signature(@payment_attributes, @payment_attributes[:shared_secret])
192
+ signature_string = Adyen::Form.calculate_open_invoice_signature_string(merchant_sig, @payment_attributes[:openinvoicedata])
193
+ expected_string =
194
+ [
195
+ 'merchantSig',
196
+ 'openinvoicedata.line1.currencyCode',
197
+ 'openinvoicedata.line1.description',
198
+ 'openinvoicedata.line1.itemAmount',
199
+ 'openinvoicedata.line1.itemVatAmount',
200
+ 'openinvoicedata.line1.itemVatCategory',
201
+ 'openinvoicedata.line1.itemVatPercentage',
202
+ 'openinvoicedata.line1.numberOfItems',
203
+ 'openinvoicedata.numberOfLines',
204
+ 'openinvoicedata.refundDescription'
205
+ ].join(':') +
206
+ '|' +
207
+ [
208
+ merchant_sig,
209
+ 'GBP',
210
+ 'Product Awesome',
211
+ 4000,
212
+ 1000,
213
+ 'High',
214
+ 2500,
215
+ 2,
216
+ 1,
217
+ 'Refund for 12345'
218
+ ].join(':')
219
+
220
+ assert_equal expected_string, signature_string
221
+ assert_equal 'OI71VGB7G3vKBRrtE6Ibv+RWvYY=', Adyen::Form.calculate_open_invoice_signature(@payment_attributes)
222
+
223
+ @payment_attributes.delete(:shared_secret)
224
+ assert_raises(ArgumentError) { Adyen::Form.calculate_open_invoice_signature(@payment_attributes) }
225
+ end
226
+
227
+ def test_billing_signatures_in_redirect_url
228
+ get_params = CGI.parse(URI(Adyen::Form.redirect_url(@payment_attributes)).query)
229
+ assert_equal '5KQb7VJq4cz75cqp11JDajntCY4=', get_params['billingAddressSig'].first
230
+ assert_equal 'g8wPEWYrDPatkGXzuQbN1++JVbE=', get_params['deliveryAddressSig'].first
231
+ assert_equal 'rb2GEs1kGKuLh255a3QRPBYXmsQ=', get_params['shopperSig'].first
232
+ assert_equal 'OI71VGB7G3vKBRrtE6Ibv+RWvYY=', get_params['openinvoicedata.sig'].first
233
+ end
234
+
235
+ def test_redirect_signature_check
236
+ params = {
237
+ 'authResult' => 'AUTHORISED', 'pspReference' => '1211992213193029',
238
+ 'merchantReference' => 'Internet Order 12345', 'skinCode' => '4aD37dJA',
239
+ 'merchantSig' => 'ytt3QxWoEhAskUzUne0P5VA9lPw='
240
+ }
241
+
242
+ assert_equal params['merchantSig'], Adyen::Form.redirect_signature(params)
243
+
244
+ assert Adyen::Form.redirect_signature_check(params) # shared secret from registered skin
245
+ assert Adyen::Form.redirect_signature_check(params, 'Kah942*$7sdp0)') # explicitly provided shared secret
246
+
247
+ refute Adyen::Form.redirect_signature_check(params.merge('skinCode' => 'sk1nC0de'))
248
+ refute Adyen::Form.redirect_signature_check(params, 'wrong_shared_secret')
249
+
250
+ refute Adyen::Form.redirect_signature_check(params.merge('pspReference' => 'tampered'))
251
+ refute Adyen::Form.redirect_signature_check(params.merge('merchantSig' => 'tampered'))
252
+
253
+ assert_raises(ArgumentError) { Adyen::Form.redirect_signature_check(nil) }
254
+ assert_raises(ArgumentError) { Adyen::Form.redirect_signature_check({}) }
255
+ assert_raises(ArgumentError) { Adyen::Form.redirect_signature_check(params.delete(:skinCode)) }
256
+ end
257
+
258
+ def test_redirect_signature_check_with_escaped_params
259
+ Adyen.configuration.register_form_skin(:testing, 'tifSfXeX', 'testing123', :merchant_account => 'VanBergenORG')
260
+
261
+ # http://example.com/result?merchantReference=HPP+test+order+%25231&skinCode=tifSfXeX&shopperLocale=en_GB&paymentMethod=visa&authResult=AUTHORISED&pspReference=8814131153369759&merchantSig=il8cjgOiG4N9l2PlSf6h4EVQ6hk%253D
262
+ params = {
263
+ "merchantReference"=>CGI.unescape("HPP test order %231"), "skinCode"=>"tifSfXeX",
264
+ "shopperLocale"=>"en_GB", "paymentMethod"=>"visa", "authResult"=>"AUTHORISED",
265
+ "pspReference"=>"8814131148758652", "merchantSig"=> CGI.unescape("q8J9P%2Fp%2FYsbnnFn%2F83TFsv7Hais%3D")
266
+ }
267
+
268
+ assert_equal params['merchantSig'], Adyen::Form.redirect_signature(params)
269
+ end
270
+
271
+ def test_hidden_payment_form_fields
272
+ payment_snippet = <<-HTML
273
+ <form id="adyen" action="#{CGI.escapeHTML(Adyen::Form.url)}" method="post">
274
+ #{Adyen::Form.hidden_fields(@payment_attributes)}
275
+ </form>
276
+ HTML
277
+
278
+ for_each_xml_backend do
279
+ assert_adyen_single_payment_form payment_snippet,
280
+ merchantAccount: 'TestMerchant',
281
+ currencyCode: 'GBP',
282
+ paymentAmount: '10000',
283
+ skinCode: '4aD37dJA'
284
+ end
285
+ end
286
+
287
+ def test_hidden_recurring_payment_form_fields
288
+ recurring_snippet = <<-HTML
289
+ <form id="adyen" action="#{CGI.escapeHTML(Adyen::Form.url)}" method="post">
290
+ #{Adyen::Form.hidden_fields(@recurring_payment_attributes)}
291
+ </form>
292
+ HTML
293
+
294
+ for_each_xml_backend do
295
+ assert_adyen_recurring_payment_form recurring_snippet,
296
+ merchantAccount: 'OtherMerchant',
297
+ currencyCode: 'GBP',
298
+ paymentAmount: '10000',
299
+ recurringContract: 'DEFAULT',
300
+ skinCode: 'sk1nC0de'
301
+ end
302
+ end
303
+ end