adyen 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|