adyen 1.1.0 → 1.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.
- data/TODO +4 -8
- data/adyen.gemspec +2 -2
- data/lib/adyen.rb +1 -1
- data/lib/adyen/api.rb +41 -0
- data/lib/adyen/api/recurring_service.rb +39 -0
- data/lib/adyen/api/simple_soap_client.rb +11 -0
- data/lib/adyen/api/templates/recurring_service.rb +27 -2
- data/lib/adyen/configuration.rb +11 -0
- data/lib/adyen/form.rb +11 -9
- data/spec/api/api_spec.rb +11 -0
- data/spec/api/recurring_service_spec.rb +75 -2
- data/spec/form_spec.rb +9 -2
- data/spec/functional/api_spec.rb +11 -3
- metadata +3 -3
data/TODO
CHANGED
@@ -1,11 +1,3 @@
|
|
1
|
-
1.0
|
2
|
-
===
|
3
|
-
|
4
|
-
* Screen documentation
|
5
|
-
|
6
|
-
Possible/Later
|
7
|
-
==============
|
8
|
-
|
9
1
|
* Add a capture! method to an authorisation response from the PaymentService.
|
10
2
|
|
11
3
|
* Add iDEAL API. To get started, see the `iDEAL' topic-branch which contains `ideal-scratchpad.rb' and a stub for a functional spec.
|
@@ -18,3 +10,7 @@ Possible/Later
|
|
18
10
|
* adyen-soap
|
19
11
|
* adyen-railtie
|
20
12
|
* adyen-activemerchant
|
13
|
+
|
14
|
+
* Add mocks for notification requests in order to test your app
|
15
|
+
|
16
|
+
* Add more mock SOAP responses for testing your app.
|
data/adyen.gemspec
CHANGED
data/lib/adyen.rb
CHANGED
@@ -12,7 +12,7 @@ module Adyen
|
|
12
12
|
# Version constant for the Adyen plugin.
|
13
13
|
# DO NOT CHANGE THIS VALUE BY HAND. It will be updated automatically by
|
14
14
|
# the gem:release rake task.
|
15
|
-
VERSION = "1.
|
15
|
+
VERSION = "1.2.0"
|
16
16
|
|
17
17
|
# @return [Configuration] The configuration singleton.
|
18
18
|
def self.configuration
|
data/lib/adyen/api.rb
CHANGED
@@ -277,5 +277,46 @@ module Adyen
|
|
277
277
|
:recurring_detail_reference => recurring_detail_reference
|
278
278
|
}).disable
|
279
279
|
end
|
280
|
+
|
281
|
+
# Stores and tokenises the creditcard details so that recurring payments can be made in the
|
282
|
+
# future.
|
283
|
+
#
|
284
|
+
# You do *not* have to include the card's CVC, because it won't be stored anyway.
|
285
|
+
#
|
286
|
+
# # @example
|
287
|
+
# response = Adyen::API.store_recurring_token(
|
288
|
+
# { :reference => user.id, :email => user.email, :ip => '8.8.8.8' },
|
289
|
+
# { :holder_name => "Simon Hopper", :number => '4444333322221111', :expiry_month => 12, :expiry_year => 2012 }
|
290
|
+
# )
|
291
|
+
# response.stored? # => true
|
292
|
+
#
|
293
|
+
# # Now we can authorize a payment with the token.
|
294
|
+
# authorize_response = Adyen::API.authorise_recurring_payment(
|
295
|
+
# invoice.id,
|
296
|
+
# { :currency => 'EUR', :value => invoice.amount },
|
297
|
+
# { :reference => user.id, :email => user.email, :ip => '8.8.8.8' },
|
298
|
+
# response.recurring_detail_reference
|
299
|
+
# )
|
300
|
+
# authorize_response.authorised? # => true
|
301
|
+
#
|
302
|
+
# @param [Hash] shopper A hash describing the shopper.
|
303
|
+
# @param [Hash] card A hash describing the creditcard details.
|
304
|
+
#
|
305
|
+
# @option shopper [Numeric,String] :reference The shopper’s reference (ID).
|
306
|
+
# @option shopper [String] :email The shopper’s email address.
|
307
|
+
# @option shopper [String] :ip The shopper’s IP address.
|
308
|
+
#
|
309
|
+
# @option card [String] :holder_name The full name on the card.
|
310
|
+
# @option card [String] :number The card number.
|
311
|
+
# @option card [Numeric,String] :expiry_month The month in which the card expires.
|
312
|
+
# @option card [Numeric,String] :expiry_year The year in which the card expires.
|
313
|
+
#
|
314
|
+
# @return [RecurringService::StoreTokenResponse] The response object
|
315
|
+
def store_recurring_token(shopper, card)
|
316
|
+
RecurringService.new({
|
317
|
+
:shopper => shopper,
|
318
|
+
:card => card
|
319
|
+
}).store_token
|
320
|
+
end
|
280
321
|
end
|
281
322
|
end
|
@@ -31,8 +31,21 @@ module Adyen
|
|
31
31
|
call_webservice_action('disable', disable_request_body, DisableResponse)
|
32
32
|
end
|
33
33
|
|
34
|
+
# @see API.store_recurring_token
|
35
|
+
def store_token
|
36
|
+
call_webservice_action('storeToken', store_token_request_body, StoreTokenResponse)
|
37
|
+
end
|
38
|
+
|
34
39
|
private
|
35
40
|
|
41
|
+
# The card's CVC isn't needed when tokenising details, so insert `nil'.
|
42
|
+
def card_partial
|
43
|
+
validate_parameters!(:card => [:holder_name, :number, :expiry_year, :expiry_month])
|
44
|
+
card = @params[:card].values_at(:holder_name, :number, :cvc, :expiry_year)
|
45
|
+
card << @params[:card][:expiry_month].to_i
|
46
|
+
CARD_PARTIAL % card
|
47
|
+
end
|
48
|
+
|
36
49
|
def list_request_body
|
37
50
|
validate_parameters!(:merchant_account, :shopper => [:reference])
|
38
51
|
LIST_LAYOUT % [@params[:merchant_account], @params[:shopper][:reference]]
|
@@ -46,6 +59,12 @@ module Adyen
|
|
46
59
|
DISABLE_LAYOUT % [@params[:merchant_account], @params[:shopper][:reference], reference || '']
|
47
60
|
end
|
48
61
|
|
62
|
+
def store_token_request_body
|
63
|
+
validate_parameters!(:merchant_account, :shopper => [:email, :reference])
|
64
|
+
content = card_partial
|
65
|
+
STORE_TOKEN_LAYOUT % [@params[:merchant_account], @params[:shopper][:reference], @params[:shopper][:email], content]
|
66
|
+
end
|
67
|
+
|
49
68
|
class DisableResponse < Response
|
50
69
|
DISABLED_RESPONSES = %w{ [detail-successfully-disabled] [all-details-successfully-disabled] }
|
51
70
|
|
@@ -121,6 +140,26 @@ module Adyen
|
|
121
140
|
}
|
122
141
|
end
|
123
142
|
end
|
143
|
+
|
144
|
+
class StoreTokenResponse < Response
|
145
|
+
response_attrs :response, :recurring_detail_reference
|
146
|
+
|
147
|
+
def recurring_detail_reference
|
148
|
+
params[:recurring_detail_reference]
|
149
|
+
end
|
150
|
+
|
151
|
+
def success?
|
152
|
+
super && params[:response] == 'Success'
|
153
|
+
end
|
154
|
+
|
155
|
+
alias stored? success?
|
156
|
+
|
157
|
+
def params
|
158
|
+
@params ||= { :response => xml_querier.text('//recurring:storeTokenResponse/recurring:result/recurring:result'),
|
159
|
+
:reference => xml_querier.text('//recurring:storeTokenResponse/recurring:result/recurring:rechargeReference'),
|
160
|
+
:recurring_detail_reference => xml_querier.text('//recurring:storeTokenResponse/recurring:result/recurring:recurringDetailReference')}
|
161
|
+
end
|
162
|
+
end
|
124
163
|
end
|
125
164
|
end
|
126
165
|
end
|
@@ -32,6 +32,16 @@ EOS
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
+
class ServerError < StandardError
|
36
|
+
def initialize(response, action, endpoint)
|
37
|
+
@response, @action, @endpoint = response, action, endpoint
|
38
|
+
end
|
39
|
+
|
40
|
+
def message
|
41
|
+
"[#{@response.code} #{@response.message}] A server error occurred while calling SOAP action `#{@action}' on endpoint `#{@endpoint}'."
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
35
45
|
class << self
|
36
46
|
# When a response instance has been assigned, the subsequent call to
|
37
47
|
# {SimpleSOAPClient#call_webservice_action} will not make a remote call, but simply return
|
@@ -109,6 +119,7 @@ EOS
|
|
109
119
|
request.start do |http|
|
110
120
|
http_response = http.request(post)
|
111
121
|
raise ClientError.new(http_response, action, endpoint) if http_response.is_a?(Net::HTTPClientError)
|
122
|
+
raise ServerError.new(http_response, action, endpoint) if http_response.is_a?(Net::HTTPServerError)
|
112
123
|
response_class.new(http_response)
|
113
124
|
end
|
114
125
|
end
|
@@ -3,10 +3,10 @@ module Adyen
|
|
3
3
|
class RecurringService < SimpleSOAPClient
|
4
4
|
# @private
|
5
5
|
LIST_LAYOUT = <<EOS
|
6
|
-
<recurring:listRecurringDetails xmlns:recurring="http://recurring.services.adyen.com">
|
6
|
+
<recurring:listRecurringDetails xmlns:payment="http://payment.services.adyen.com" xmlns:recurring="http://recurring.services.adyen.com">
|
7
7
|
<recurring:request>
|
8
8
|
<recurring:recurring>
|
9
|
-
<
|
9
|
+
<payment:contract>RECURRING</payment:contract>
|
10
10
|
</recurring:recurring>
|
11
11
|
<recurring:merchantAccount>%s</recurring:merchantAccount>
|
12
12
|
<recurring:shopperReference>%s</recurring:shopperReference>
|
@@ -29,6 +29,31 @@ EOS
|
|
29
29
|
RECURRING_DETAIL_PARTIAL = <<EOS
|
30
30
|
<recurring:recurringDetailReference>%s</recurring:recurringDetailReference>
|
31
31
|
EOS
|
32
|
+
|
33
|
+
STORE_TOKEN_LAYOUT = <<EOS
|
34
|
+
<recurring:storeToken xmlns:recurring="http://recurring.services.adyen.com" xmlns:payment="http://payment.services.adyen.com">
|
35
|
+
<recurring:request>
|
36
|
+
<recurring:recurring>
|
37
|
+
<payment:contract>RECURRING</payment:contract>
|
38
|
+
</recurring:recurring>
|
39
|
+
<recurring:merchantAccount>%s</recurring:merchantAccount>
|
40
|
+
<recurring:shopperReference>%s</recurring:shopperReference>
|
41
|
+
<recurring:shopperEmail>%s</recurring:shopperEmail>
|
42
|
+
%s
|
43
|
+
</recurring:request>
|
44
|
+
</recurring:storeToken>
|
45
|
+
EOS
|
46
|
+
|
47
|
+
# @private
|
48
|
+
CARD_PARTIAL = <<EOS
|
49
|
+
<recurring:card>
|
50
|
+
<payment:holderName>%s</payment:holderName>
|
51
|
+
<payment:number>%s</payment:number>
|
52
|
+
<payment:cvc>%s</payment:cvc>
|
53
|
+
<payment:expiryYear>%s</payment:expiryYear>
|
54
|
+
<payment:expiryMonth>%02d</payment:expiryMonth>
|
55
|
+
</recurring:card>
|
56
|
+
EOS
|
32
57
|
end
|
33
58
|
end
|
34
59
|
end
|
data/lib/adyen/configuration.rb
CHANGED
@@ -78,6 +78,17 @@ class Adyen::Configuration
|
|
78
78
|
#
|
79
79
|
# @return [Hash]
|
80
80
|
attr_accessor :default_form_params
|
81
|
+
|
82
|
+
# Username that's set in Notification settings screen in Adyen PSP system and used by notification service to
|
83
|
+
# authenticate instant payment notification requests.
|
84
|
+
#
|
85
|
+
# @return [String]
|
86
|
+
attr_accessor :ipn_username
|
87
|
+
|
88
|
+
# Password used to authenticate notification requests together with '+ipn_username+' configuration attribute.
|
89
|
+
#
|
90
|
+
# @return [String]
|
91
|
+
attr_accessor :ipn_password
|
81
92
|
|
82
93
|
######################################################
|
83
94
|
# SKINS
|
data/lib/adyen/form.rb
CHANGED
@@ -126,7 +126,7 @@ module Adyen
|
|
126
126
|
# @param [Hash] parameters The payment parameters to include in the payment request.
|
127
127
|
# @return [String] An absolute URL to redirect to the Adyen payment system.
|
128
128
|
def redirect_url(parameters = {})
|
129
|
-
url + '?' + payment_parameters(parameters).map { |(k, v)|
|
129
|
+
url + '?' + payment_parameters(parameters).map{|k,v| [k.to_s,v] }.sort.map { |(k, v)|
|
130
130
|
"#{camelize(k)}=#{CGI.escape(v.to_s)}" }.join('&')
|
131
131
|
end
|
132
132
|
|
@@ -171,13 +171,14 @@ module Adyen
|
|
171
171
|
# @return [String] The string for which the siganture is calculated.
|
172
172
|
def calculate_signature_string(parameters)
|
173
173
|
merchant_sig_string = ""
|
174
|
-
merchant_sig_string << parameters[:payment_amount].to_s
|
175
|
-
parameters[:ship_before_date].to_s
|
176
|
-
parameters[:skin_code].to_s
|
177
|
-
parameters[:session_validity].to_s
|
178
|
-
parameters[:shopper_reference].to_s
|
179
|
-
parameters[:allowed_methods].to_s
|
180
|
-
parameters[:shopper_statement].to_s
|
174
|
+
merchant_sig_string << parameters[:payment_amount].to_s << parameters[:currency_code].to_s <<
|
175
|
+
parameters[:ship_before_date].to_s << parameters[:merchant_reference].to_s <<
|
176
|
+
parameters[:skin_code].to_s << parameters[:merchant_account].to_s <<
|
177
|
+
parameters[:session_validity].to_s << parameters[:shopper_email].to_s <<
|
178
|
+
parameters[:shopper_reference].to_s << parameters[:recurring_contract].to_s <<
|
179
|
+
parameters[:allowed_methods].to_s << parameters[:blocked_methods].to_s <<
|
180
|
+
parameters[:shopper_statement].to_s << parameters[:merchant_return_data].to_s <<
|
181
|
+
parameters[:billing_address_type].to_s << parameters[:offset].to_s
|
181
182
|
end
|
182
183
|
|
183
184
|
# Calculates the payment request signature for the given payment parameters.
|
@@ -206,7 +207,8 @@ module Adyen
|
|
206
207
|
# @param [Hash] params A hash of HTTP GET parameters for the redirect request.
|
207
208
|
# @return [String] The signature string.
|
208
209
|
def redirect_signature_string(params)
|
209
|
-
params[:authResult].to_s + params[:pspReference].to_s + params[:merchantReference].to_s +
|
210
|
+
params[:authResult].to_s + params[:pspReference].to_s + params[:merchantReference].to_s +
|
211
|
+
params[:skinCode].to_s + params[:merchantReturnData].to_s
|
210
212
|
end
|
211
213
|
|
212
214
|
# Computes the redirect signature using the request parameters, so that the
|
data/spec/api/api_spec.rb
CHANGED
@@ -120,6 +120,17 @@ describe Adyen::API do
|
|
120
120
|
@recurring.should_receive(method)
|
121
121
|
end
|
122
122
|
|
123
|
+
it "performs a `tokenize creditcard details' request" do
|
124
|
+
should_map_shortcut_to(:store_token,
|
125
|
+
:shopper => { :reference => 'user-id', :email => 's.hopper@example.com' },
|
126
|
+
:card => { :expiry_month => 12, :expiry_year => 2012, :holder_name => "Simon Hopper", :number => '4444333322221111' }
|
127
|
+
)
|
128
|
+
Adyen::API.store_recurring_token(
|
129
|
+
{ :reference => 'user-id', :email => 's.hopper@example.com' },
|
130
|
+
{ :expiry_month => 12, :expiry_year => 2012, :holder_name => "Simon Hopper", :number => '4444333322221111' }
|
131
|
+
)
|
132
|
+
end
|
133
|
+
|
123
134
|
it "preforms a `list recurring details' request" do
|
124
135
|
should_map_shortcut_to(:list, :shopper => { :reference => 'user-id' })
|
125
136
|
Adyen::API.list_recurring_details('user-id')
|
@@ -6,7 +6,29 @@ describe Adyen::API::RecurringService do
|
|
6
6
|
include APISpecHelper
|
7
7
|
|
8
8
|
before do
|
9
|
-
@params = {
|
9
|
+
@params = {
|
10
|
+
:reference => 'order-id',
|
11
|
+
:amount => {
|
12
|
+
:currency => 'EUR',
|
13
|
+
:value => '1234',
|
14
|
+
},
|
15
|
+
:shopper => {
|
16
|
+
:email => 's.hopper@example.com',
|
17
|
+
:reference => 'user-id',
|
18
|
+
:ip => '61.294.12.12',
|
19
|
+
},
|
20
|
+
:card => {
|
21
|
+
:expiry_month => 12,
|
22
|
+
:expiry_year => 2012,
|
23
|
+
:holder_name => 'Simon わくわく Hopper',
|
24
|
+
:number => '4444333322221111',
|
25
|
+
:cvc => '737',
|
26
|
+
# Maestro UK/Solo only
|
27
|
+
#:issue_number => ,
|
28
|
+
#:start_month => ,
|
29
|
+
#:start_year => ,
|
30
|
+
}
|
31
|
+
}
|
10
32
|
@recurring = @object = Adyen::API::RecurringService.new(@params)
|
11
33
|
end
|
12
34
|
|
@@ -23,7 +45,7 @@ describe Adyen::API::RecurringService do
|
|
23
45
|
end
|
24
46
|
|
25
47
|
it "includes the type of contract, which is always `RECURRING'" do
|
26
|
-
text('./recurring:recurring/
|
48
|
+
text('./recurring:recurring/payment:contract').should == 'RECURRING'
|
27
49
|
end
|
28
50
|
end
|
29
51
|
|
@@ -102,4 +124,55 @@ describe Adyen::API::RecurringService do
|
|
102
124
|
|
103
125
|
it_should_return_params_for_each_xml_backend(:response => '[detail-successfully-disabled]')
|
104
126
|
end
|
127
|
+
|
128
|
+
describe_request_body_of :store_token, '//recurring:storeToken/recurring:request' do
|
129
|
+
it_should_validate_request_parameters :merchant_account,
|
130
|
+
:shopper => [:email, :reference]
|
131
|
+
|
132
|
+
it "includes the merchant account handle" do
|
133
|
+
text('./recurring:merchantAccount').should == 'SuperShopper'
|
134
|
+
end
|
135
|
+
|
136
|
+
it "includes the shopper’s reference" do
|
137
|
+
text('./recurring:shopperReference').should == 'user-id'
|
138
|
+
end
|
139
|
+
|
140
|
+
it "includes the shopper’s email" do
|
141
|
+
text('./recurring:shopperEmail').should == 's.hopper@example.com'
|
142
|
+
end
|
143
|
+
|
144
|
+
it "includes the creditcard details" do
|
145
|
+
xpath('./recurring:card') do |card|
|
146
|
+
# there's no reason why Nokogiri should escape these characters, but as long as they're correct
|
147
|
+
card.text('./payment:holderName').should == 'Simon わくわく Hopper'
|
148
|
+
card.text('./payment:number').should == '4444333322221111'
|
149
|
+
card.text('./payment:cvc').should == '737'
|
150
|
+
card.text('./payment:expiryMonth').should == '12'
|
151
|
+
card.text('./payment:expiryYear').should == '2012'
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
it "formats the creditcard’s expiry month as a two digit number" do
|
156
|
+
@recurring.params[:card][:expiry_month] = 6
|
157
|
+
text('./recurring:card/payment:expiryMonth').should == '06'
|
158
|
+
end
|
159
|
+
|
160
|
+
it "includes the necessary recurring and one-click contract info if the `:recurring' param is truthful" do
|
161
|
+
text('./recurring:recurring/payment:contract').should == 'RECURRING'
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
describe_response_from :disable, (DISABLE_RESPONSE % '[detail-successfully-disabled]'), 'disable' do
|
166
|
+
it "returns whether or not it was disabled" do
|
167
|
+
@response.should be_success
|
168
|
+
@response.should be_disabled
|
169
|
+
|
170
|
+
stub_net_http(DISABLE_RESPONSE % '[all-details-successfully-disabled]')
|
171
|
+
@response = @recurring.disable
|
172
|
+
@response.should be_success
|
173
|
+
@response.should be_disabled
|
174
|
+
end
|
175
|
+
|
176
|
+
it_should_return_params_for_each_xml_backend(:response => '[detail-successfully-disabled]')
|
177
|
+
end
|
105
178
|
end
|
data/spec/form_spec.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
+
require 'date'
|
3
4
|
require 'spec_helper'
|
4
5
|
require 'adyen/form'
|
5
6
|
|
@@ -63,6 +64,8 @@ describe Adyen::Form do
|
|
63
64
|
|
64
65
|
it "should calculate the signature string correctly" do
|
65
66
|
Adyen::Form.redirect_signature_string(@params).should == 'AUTHORISED1211992213193029Internet Order 123454aD37dJA'
|
67
|
+
params = @params.merge(:merchantReturnData => 'testing1234')
|
68
|
+
Adyen::Form.redirect_signature_string(params).should == 'AUTHORISED1211992213193029Internet Order 123454aD37dJAtesting1234'
|
66
69
|
end
|
67
70
|
|
68
71
|
it "should calculate the signature correctly" do
|
@@ -142,9 +145,13 @@ describe Adyen::Form do
|
|
142
145
|
Adyen::Form.do_parameter_transformations!(@parameters)
|
143
146
|
end
|
144
147
|
|
145
|
-
it "should construct the signature string correctly" do
|
148
|
+
it "should construct the signature base string correctly" do
|
146
149
|
signature_string = Adyen::Form.calculate_signature_string(@parameters)
|
147
150
|
signature_string.should == "10000GBP2007-10-20Internet Order 123454aD37dJATestMerchant2007-10-11T11:00:00Z"
|
151
|
+
|
152
|
+
signature_string = Adyen::Form.calculate_signature_string(@parameters.merge(:merchant_return_data => 'testing123'))
|
153
|
+
signature_string.should == "10000GBP2007-10-20Internet Order 123454aD37dJATestMerchant2007-10-11T11:00:00Ztesting123"
|
154
|
+
|
148
155
|
end
|
149
156
|
|
150
157
|
it "should calculate the signature correctly" do
|
@@ -152,7 +159,7 @@ describe Adyen::Form do
|
|
152
159
|
signature.should == 'x58ZcRVL1H6y+XSeBGrySJ9ACVo='
|
153
160
|
end
|
154
161
|
|
155
|
-
it "should calculate the signature correctly for a recurring payment" do
|
162
|
+
it "should calculate the signature base string correctly for a recurring payment" do
|
156
163
|
# Add the required recurrent payment attributes
|
157
164
|
@parameters.merge!(:recurring_contract => 'DEFAULT', :shopper_reference => 'grasshopper52', :shopper_email => 'gras.shopper@somewhere.org')
|
158
165
|
|
data/spec/functional/api_spec.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# encoding: UTF-8
|
2
|
-
require 'spec_helper'
|
3
|
-
|
4
|
-
require 'rubygems'
|
2
|
+
require 'api/spec_helper'
|
5
3
|
require 'nokogiri'
|
6
4
|
|
7
5
|
API_SPEC_INITIALIZER = File.expand_path("../initializer.rb", __FILE__)
|
@@ -9,6 +7,7 @@ API_SPEC_INITIALIZER = File.expand_path("../initializer.rb", __FILE__)
|
|
9
7
|
if File.exist?(API_SPEC_INITIALIZER)
|
10
8
|
|
11
9
|
describe Adyen::API, "with an actual remote connection" do
|
10
|
+
|
12
11
|
before :all do
|
13
12
|
require API_SPEC_INITIALIZER
|
14
13
|
Net::HTTP.stubbing_enabled = false
|
@@ -58,6 +57,15 @@ if File.exist?(API_SPEC_INITIALIZER)
|
|
58
57
|
response.psp_reference.should_not be_empty
|
59
58
|
end
|
60
59
|
|
60
|
+
it "stores the provided creditcard details" do
|
61
|
+
response = Adyen::API.store_recurring_token(
|
62
|
+
{ :email => "#{@user_id}@example.com", :reference => @user_id },
|
63
|
+
{ :expiry_month => 12, :expiry_year => 2012, :holder_name => "Simon #{@user_id} Hopper", :number => '4111111111111111' }
|
64
|
+
)
|
65
|
+
response.should be_stored
|
66
|
+
response.recurring_detail_reference.should_not be_empty
|
67
|
+
end
|
68
|
+
|
61
69
|
it "captures a payment" do
|
62
70
|
response = Adyen::API.capture_payment(@payment_response.psp_reference, { :currency => 'EUR', :value => '1234' })
|
63
71
|
response.should be_success
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 1
|
7
|
-
-
|
7
|
+
- 2
|
8
8
|
- 0
|
9
|
-
version: 1.
|
9
|
+
version: 1.2.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Willem van Bergen
|
@@ -17,7 +17,7 @@ autorequire:
|
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
19
|
|
20
|
-
date: 2011-
|
20
|
+
date: 2011-05-12 00:00:00 -04:00
|
21
21
|
default_executable:
|
22
22
|
dependencies:
|
23
23
|
- !ruby/object:Gem::Dependency
|