adyen 0.3.8 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.kick +35 -0
- data/LICENSE +3 -2
- data/README.rdoc +8 -4
- data/Rakefile +10 -0
- data/TODO +14 -4
- data/adyen.gemspec +9 -15
- data/lib/adyen.rb +10 -59
- data/lib/adyen/api.rb +281 -0
- data/lib/adyen/api/cacert.pem +3509 -0
- data/lib/adyen/api/payment_service.rb +258 -0
- data/lib/adyen/api/recurring_service.rb +126 -0
- data/lib/adyen/api/response.rb +54 -0
- data/lib/adyen/api/simple_soap_client.rb +118 -0
- data/lib/adyen/api/templates/payment_service.rb +103 -0
- data/lib/adyen/api/templates/recurring_service.rb +34 -0
- data/lib/adyen/api/test_helpers.rb +133 -0
- data/lib/adyen/api/xml_querier.rb +94 -0
- data/lib/adyen/configuration.rb +139 -0
- data/lib/adyen/form.rb +37 -109
- data/lib/adyen/formatter.rb +0 -10
- data/lib/adyen/matchers.rb +1 -1
- data/lib/adyen/notification_generator.rb +30 -0
- data/lib/adyen/railtie.rb +13 -0
- data/lib/adyen/templates/notification_migration.rb +29 -0
- data/lib/adyen/templates/notification_model.rb +70 -0
- data/spec/adyen_spec.rb +3 -45
- data/spec/api/api_spec.rb +139 -0
- data/spec/api/payment_service_spec.rb +439 -0
- data/spec/api/recurring_service_spec.rb +105 -0
- data/spec/api/response_spec.rb +35 -0
- data/spec/api/simple_soap_client_spec.rb +91 -0
- data/spec/api/spec_helper.rb +417 -0
- data/spec/api/test_helpers_spec.rb +83 -0
- data/spec/form_spec.rb +27 -23
- data/spec/functional/api_spec.rb +90 -0
- data/spec/functional/initializer.rb.sample +3 -0
- data/spec/spec_helper.rb +5 -5
- data/tasks/github-gem.rake +49 -55
- data/yard_extensions.rb +16 -0
- metadata +63 -82
- data/init.rb +0 -1
- data/lib/adyen/notification.rb +0 -151
- data/lib/adyen/soap.rb +0 -649
- data/spec/notification_spec.rb +0 -97
- data/spec/soap_spec.rb +0 -340
data/yard_extensions.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
class ResponseAttrHandler < YARD::Handlers::Ruby::Legacy::Base
|
2
|
+
handles 'response_attrs'
|
3
|
+
namespace_only
|
4
|
+
|
5
|
+
def process
|
6
|
+
statement.tokens[1..-1].each do |token|
|
7
|
+
next unless token.text =~ /^:?(\w+)/
|
8
|
+
name = $1
|
9
|
+
object = YARD::CodeObjects::MethodObject.new(namespace, name)
|
10
|
+
register(object)
|
11
|
+
object.dynamic = true
|
12
|
+
object.docstring = "@return [String] Returns +:#{name}+ from the {#params}."
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: adyen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
|
+
- 1
|
7
8
|
- 0
|
8
|
-
-
|
9
|
-
|
10
|
-
version: 0.3.8
|
9
|
+
- 0
|
10
|
+
version: 1.0.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Willem van Bergen
|
@@ -18,7 +18,7 @@ autorequire:
|
|
18
18
|
bindir: bin
|
19
19
|
cert_chain: []
|
20
20
|
|
21
|
-
date:
|
21
|
+
date: 2011-01-22 00:00:00 -05:00
|
22
22
|
default_executable:
|
23
23
|
dependencies:
|
24
24
|
- !ruby/object:Gem::Dependency
|
@@ -41,88 +41,44 @@ dependencies:
|
|
41
41
|
requirement: &id002 !ruby/object:Gem::Requirement
|
42
42
|
none: false
|
43
43
|
requirements:
|
44
|
-
- -
|
44
|
+
- - ~>
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
hash:
|
46
|
+
hash: 3
|
47
47
|
segments:
|
48
|
-
-
|
49
|
-
-
|
50
|
-
|
51
|
-
version: 1.1.4
|
48
|
+
- 2
|
49
|
+
- 0
|
50
|
+
version: "2.0"
|
52
51
|
type: :development
|
53
52
|
version_requirements: *id002
|
54
53
|
- !ruby/object:Gem::Dependency
|
55
|
-
name:
|
54
|
+
name: nokogiri
|
56
55
|
prerelease: false
|
57
56
|
requirement: &id003 !ruby/object:Gem::Requirement
|
58
57
|
none: false
|
59
58
|
requirements:
|
60
59
|
- - ">="
|
61
60
|
- !ruby/object:Gem::Version
|
62
|
-
hash:
|
61
|
+
hash: 3
|
63
62
|
segments:
|
64
|
-
- 1
|
65
|
-
- 1
|
66
63
|
- 0
|
67
|
-
version:
|
64
|
+
version: "0"
|
68
65
|
type: :development
|
69
66
|
version_requirements: *id003
|
70
67
|
- !ruby/object:Gem::Dependency
|
71
|
-
name:
|
68
|
+
name: rails
|
72
69
|
prerelease: false
|
73
70
|
requirement: &id004 !ruby/object:Gem::Requirement
|
74
71
|
none: false
|
75
72
|
requirements:
|
76
73
|
- - ">="
|
77
74
|
- !ruby/object:Gem::Version
|
78
|
-
hash:
|
75
|
+
hash: 5
|
79
76
|
segments:
|
80
|
-
-
|
81
|
-
|
77
|
+
- 2
|
78
|
+
- 3
|
79
|
+
version: "2.3"
|
82
80
|
type: :development
|
83
81
|
version_requirements: *id004
|
84
|
-
- !ruby/object:Gem::Dependency
|
85
|
-
name: activerecord
|
86
|
-
prerelease: false
|
87
|
-
requirement: &id005 !ruby/object:Gem::Requirement
|
88
|
-
none: false
|
89
|
-
requirements:
|
90
|
-
- - ">="
|
91
|
-
- !ruby/object:Gem::Version
|
92
|
-
hash: 3
|
93
|
-
segments:
|
94
|
-
- 0
|
95
|
-
version: "0"
|
96
|
-
type: :development
|
97
|
-
version_requirements: *id005
|
98
|
-
- !ruby/object:Gem::Dependency
|
99
|
-
name: handsoap
|
100
|
-
prerelease: false
|
101
|
-
requirement: &id006 !ruby/object:Gem::Requirement
|
102
|
-
none: false
|
103
|
-
requirements:
|
104
|
-
- - ">="
|
105
|
-
- !ruby/object:Gem::Version
|
106
|
-
hash: 3
|
107
|
-
segments:
|
108
|
-
- 0
|
109
|
-
version: "0"
|
110
|
-
type: :development
|
111
|
-
version_requirements: *id006
|
112
|
-
- !ruby/object:Gem::Dependency
|
113
|
-
name: nokogiri
|
114
|
-
prerelease: false
|
115
|
-
requirement: &id007 !ruby/object:Gem::Requirement
|
116
|
-
none: false
|
117
|
-
requirements:
|
118
|
-
- - ">="
|
119
|
-
- !ruby/object:Gem::Version
|
120
|
-
hash: 3
|
121
|
-
segments:
|
122
|
-
- 0
|
123
|
-
version: "0"
|
124
|
-
type: :development
|
125
|
-
version_requirements: *id007
|
126
82
|
description: " Package to simplify including the Adyen payments services into a Ruby on Rails application.\n The package provides functionality to create payment forms, handling and storing notifications \n sent by Adyen and consuming the SOAP services provided by Adyen. Moreover, it contains helper\n methods, mocks and matchers to simpify writing tests/specsfor your code.\n"
|
127
83
|
email:
|
128
84
|
- willem@vanbergen.org
|
@@ -136,28 +92,49 @@ extensions: []
|
|
136
92
|
extra_rdoc_files:
|
137
93
|
- README.rdoc
|
138
94
|
files:
|
139
|
-
- spec/spec_helper.rb
|
140
|
-
- spec/adyen_spec.rb
|
141
|
-
- lib/adyen/form.rb
|
142
95
|
- .gitignore
|
143
|
-
-
|
144
|
-
- lib/adyen/soap.rb
|
96
|
+
- .kick
|
145
97
|
- LICENSE
|
146
|
-
- spec/soap_spec.rb
|
147
|
-
- init.rb
|
148
|
-
- adyen.gemspec
|
149
|
-
- Rakefile
|
150
|
-
- spec/form_spec.rb
|
151
98
|
- README.rdoc
|
152
|
-
-
|
153
|
-
- lib/adyen/formatter.rb
|
154
|
-
- tasks/github-gem.rake
|
155
|
-
- lib/adyen/encoding.rb
|
99
|
+
- Rakefile
|
156
100
|
- TODO
|
157
|
-
-
|
101
|
+
- adyen.gemspec
|
158
102
|
- lib/adyen.rb
|
103
|
+
- lib/adyen/api.rb
|
104
|
+
- lib/adyen/api/cacert.pem
|
105
|
+
- lib/adyen/api/payment_service.rb
|
106
|
+
- lib/adyen/api/recurring_service.rb
|
107
|
+
- lib/adyen/api/response.rb
|
108
|
+
- lib/adyen/api/simple_soap_client.rb
|
109
|
+
- lib/adyen/api/templates/payment_service.rb
|
110
|
+
- lib/adyen/api/templates/recurring_service.rb
|
111
|
+
- lib/adyen/api/test_helpers.rb
|
112
|
+
- lib/adyen/api/xml_querier.rb
|
113
|
+
- lib/adyen/configuration.rb
|
114
|
+
- lib/adyen/encoding.rb
|
115
|
+
- lib/adyen/form.rb
|
116
|
+
- lib/adyen/formatter.rb
|
117
|
+
- lib/adyen/matchers.rb
|
118
|
+
- lib/adyen/notification_generator.rb
|
119
|
+
- lib/adyen/railtie.rb
|
120
|
+
- lib/adyen/templates/notification_migration.rb
|
121
|
+
- lib/adyen/templates/notification_model.rb
|
122
|
+
- spec/adyen_spec.rb
|
123
|
+
- spec/api/api_spec.rb
|
124
|
+
- spec/api/payment_service_spec.rb
|
125
|
+
- spec/api/recurring_service_spec.rb
|
126
|
+
- spec/api/response_spec.rb
|
127
|
+
- spec/api/simple_soap_client_spec.rb
|
128
|
+
- spec/api/spec_helper.rb
|
129
|
+
- spec/api/test_helpers_spec.rb
|
130
|
+
- spec/form_spec.rb
|
131
|
+
- spec/functional/api_spec.rb
|
132
|
+
- spec/functional/initializer.rb.sample
|
133
|
+
- spec/spec_helper.rb
|
134
|
+
- tasks/github-gem.rake
|
135
|
+
- yard_extensions.rb
|
159
136
|
has_rdoc: true
|
160
|
-
homepage: http://
|
137
|
+
homepage: http://github.com/wvanbergen/adyen/wiki
|
161
138
|
licenses: []
|
162
139
|
|
163
140
|
post_install_message:
|
@@ -189,8 +166,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
189
166
|
- 0
|
190
167
|
version: "0"
|
191
168
|
requirements:
|
192
|
-
-
|
193
|
-
- ActiveRecord is required for storing the notifications in your database.
|
169
|
+
- Having Nokogiri installed will speed up XML handling when using the SOAP API.
|
194
170
|
rubyforge_project:
|
195
171
|
rubygems_version: 1.3.7
|
196
172
|
signing_key:
|
@@ -198,6 +174,11 @@ specification_version: 3
|
|
198
174
|
summary: Integrate Adyen payment services in your Ruby on Rails application.
|
199
175
|
test_files:
|
200
176
|
- spec/adyen_spec.rb
|
201
|
-
- spec/
|
202
|
-
- spec/
|
177
|
+
- spec/api/api_spec.rb
|
178
|
+
- spec/api/payment_service_spec.rb
|
179
|
+
- spec/api/recurring_service_spec.rb
|
180
|
+
- spec/api/response_spec.rb
|
181
|
+
- spec/api/simple_soap_client_spec.rb
|
182
|
+
- spec/api/test_helpers_spec.rb
|
203
183
|
- spec/form_spec.rb
|
184
|
+
- spec/functional/api_spec.rb
|
data/init.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require 'adyen'
|
data/lib/adyen/notification.rb
DELETED
@@ -1,151 +0,0 @@
|
|
1
|
-
require 'active_record'
|
2
|
-
|
3
|
-
module Adyen
|
4
|
-
|
5
|
-
# The +Adyen::Notification+ class handles notifications sent by Adyen to your servers.
|
6
|
-
#
|
7
|
-
# Because notifications contain important payment status information, you should store
|
8
|
-
# these notifications in your database. For this reason, +Adyen::Notification+ inherits
|
9
|
-
# from +ActiveRecord::Base+, and a migration is included to simply create a suitable table
|
10
|
-
# to store the notifications in.
|
11
|
-
#
|
12
|
-
# Adyen can either send notifications to you via HTTP POST requests, or SOAP requests.
|
13
|
-
# Because SOAP is not really well supported in Rails and setting up a SOAP server is
|
14
|
-
# not trivial, only handling HTTP POST notifications is currently supported.
|
15
|
-
#
|
16
|
-
# @example
|
17
|
-
# @notification = Adyen::Notification::HttpPost.log(request)
|
18
|
-
# if @notification.successful_authorisation?
|
19
|
-
# @invoice = Invoice.find(@notification.merchant_reference)
|
20
|
-
# @invoice.set_paid!
|
21
|
-
# end
|
22
|
-
#
|
23
|
-
# @see Adyen::Notification::HttpPost.log
|
24
|
-
class Notification < ActiveRecord::Base
|
25
|
-
|
26
|
-
# The default table name to use for the notifications table.
|
27
|
-
DEFAULT_TABLE_NAME = :adyen_notifications
|
28
|
-
set_table_name(DEFAULT_TABLE_NAME)
|
29
|
-
|
30
|
-
# A notification should always include an event_code
|
31
|
-
validates_presence_of :event_code
|
32
|
-
|
33
|
-
# A notification should always include a psp_reference
|
34
|
-
validates_presence_of :psp_reference
|
35
|
-
|
36
|
-
# A notification should be unique using the composed key of
|
37
|
-
# [:psp_reference, :event_code, :success]
|
38
|
-
validates_uniqueness_of :success, :scope => [:psp_reference, :event_code]
|
39
|
-
|
40
|
-
# Make sure we don't end up with an original_reference with an empty string
|
41
|
-
before_validation { |notification| notification.original_reference = nil if notification.original_reference.blank? }
|
42
|
-
|
43
|
-
# Logs an incoming notification into the database.
|
44
|
-
#
|
45
|
-
# @param [Hash] params The notification parameters that should be stored in the database.
|
46
|
-
# @return [Adyen::Notification] The initiated and persisted notification instance.
|
47
|
-
# @raise This method will raise an exception if the notification cannot be stored.
|
48
|
-
# @see Adyen::Notification::HttpPost.log
|
49
|
-
def self.log(params)
|
50
|
-
converted_params = {}
|
51
|
-
# Convert each attribute from CamelCase notation to under_score notation
|
52
|
-
# For example, merchantReference will be converted to merchant_reference
|
53
|
-
params.each do |key, value|
|
54
|
-
field_name = key.to_s.underscore
|
55
|
-
converted_params[field_name] = value if self.column_names.include?(field_name)
|
56
|
-
end
|
57
|
-
self.create!(converted_params)
|
58
|
-
end
|
59
|
-
|
60
|
-
# Returns true if this notification is an AUTHORISATION notification
|
61
|
-
# @return [true, false] true iff event_code == 'AUTHORISATION'
|
62
|
-
# @see Adyen.notification#successful_authorisation?
|
63
|
-
def authorisation?
|
64
|
-
event_code == 'AUTHORISATION'
|
65
|
-
end
|
66
|
-
|
67
|
-
alias :authorization? :authorisation?
|
68
|
-
|
69
|
-
# Returns true if this notification is an AUTHORISATION notification and
|
70
|
-
# the success status indicates that the authorization was successfull.
|
71
|
-
# @return [true, false] true iff the notification is an authorization
|
72
|
-
# and the authorization was successful according to the success field.
|
73
|
-
def successful_authorisation?
|
74
|
-
event_code == 'AUTHORISATION' && success?
|
75
|
-
end
|
76
|
-
|
77
|
-
alias :successful_authorization? :successful_authorisation?
|
78
|
-
|
79
|
-
# Collect a payment using the recurring contract that was initiated with
|
80
|
-
# this notification. The payment is collected using a SOAP call to the
|
81
|
-
# Adyen SOAP service for recurring payments.
|
82
|
-
# @param [Hash] options The payment parameters.
|
83
|
-
# @see Adyen::SOAP::RecurringService#submit
|
84
|
-
def collect_payment_for_recurring_contract!(options)
|
85
|
-
# Make sure we convert the value to cents
|
86
|
-
options[:value] = Adyen::Formatter::Price.in_cents(options[:value])
|
87
|
-
raise "This is not a recurring contract!" unless event_code == 'RECURRING_CONTRACT'
|
88
|
-
Adyen::SOAP::RecurringService.submit(options.merge(:recurring_reference => self.psp_reference))
|
89
|
-
end
|
90
|
-
|
91
|
-
# Deactivates the recurring contract that was initiated with this notification.
|
92
|
-
# The contract is deactivated by sending a SOAP call to the Adyen SOAP service for
|
93
|
-
# recurring contracts.
|
94
|
-
# @param [Hash] options The recurring contract parameters.
|
95
|
-
# @see Adyen::SOAP::RecurringService#deactivate
|
96
|
-
def deactivate_recurring_contract!(options)
|
97
|
-
raise "This is not a recurring contract!" unless event_code == 'RECURRING_CONTRACT'
|
98
|
-
Adyen::SOAP::RecurringService.deactivate(options.merge(:recurring_reference => self.psp_reference))
|
99
|
-
end
|
100
|
-
|
101
|
-
class HttpPost < Notification
|
102
|
-
|
103
|
-
def self.log(request)
|
104
|
-
super(request.params)
|
105
|
-
end
|
106
|
-
|
107
|
-
def live=(value)
|
108
|
-
super([true, 1, '1', 'true'].include?(value))
|
109
|
-
end
|
110
|
-
|
111
|
-
def success=(value)
|
112
|
-
super([true, 1, '1', 'true'].include?(value))
|
113
|
-
end
|
114
|
-
|
115
|
-
def value=(value)
|
116
|
-
super(Adyen::Formatter::Price.from_cents(value)) unless value.blank?
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
# An ActiveRecord migration that can be used to create a suitable table
|
121
|
-
# to store Adyen::Notification instances for your application.
|
122
|
-
class Migration < ActiveRecord::Migration
|
123
|
-
|
124
|
-
def self.up(table_name = Adyen::Notification::DEFAULT_TABLE_NAME)
|
125
|
-
create_table(table_name) do |t|
|
126
|
-
t.boolean :live, :null => false, :default => false
|
127
|
-
t.string :event_code, :null => false
|
128
|
-
t.string :psp_reference, :null => false
|
129
|
-
t.string :original_reference, :null => true
|
130
|
-
t.string :merchant_reference, :null => false
|
131
|
-
t.string :merchant_account_code, :null => false
|
132
|
-
t.datetime :event_date, :null => false
|
133
|
-
t.boolean :success, :null => false, :default => false
|
134
|
-
t.string :payment_method, :null => true
|
135
|
-
t.string :operations, :null => true
|
136
|
-
t.text :reason
|
137
|
-
t.string :currency, :null => false, :limit => 3
|
138
|
-
t.decimal :value, :null => true, :precision => 9, :scale => 2
|
139
|
-
t.boolean :processed, :null => false, :default => false
|
140
|
-
t.timestamps
|
141
|
-
end
|
142
|
-
add_index table_name, [:psp_reference, :event_code, :success], :unique => true, :name => 'adyen_notification_uniqueness'
|
143
|
-
end
|
144
|
-
|
145
|
-
def self.down(table_name = Adyen::Notification::DEFAULT_TABLE_NAME)
|
146
|
-
remove_index(table_name, :name => 'adyen_notification_uniqueness')
|
147
|
-
drop_table(table_name)
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
data/lib/adyen/soap.rb
DELETED
@@ -1,649 +0,0 @@
|
|
1
|
-
begin
|
2
|
-
require "handsoap"
|
3
|
-
rescue LoadError
|
4
|
-
$stderr.puts "The handsoap gem (>= 1.4.1) is required to use the SOAP clients:"
|
5
|
-
$stderr.puts "$ (sudo) gem install handsoap --source http://gemcutter.org"
|
6
|
-
end
|
7
|
-
|
8
|
-
module Adyen
|
9
|
-
|
10
|
-
# The SOAP module contains classes that interact with the Adyen SOAP
|
11
|
-
# services. The clients are based on the +handsoap+ library and requires at
|
12
|
-
# least version 1.4.1 of this gem.
|
13
|
-
#
|
14
|
-
# Note that you'll need an Adyen notification PSP reference for most SOAP
|
15
|
-
# calls. Because of this, store all notifications that Adyen sends to you.
|
16
|
-
# (e.g. using the {Adyen::Notification} ActiveRecord class). Moreover, most
|
17
|
-
# SOAP calls do not respond that they were successful immediately, but a
|
18
|
-
# notifications to indicate that will be sent later on.
|
19
|
-
#
|
20
|
-
# You'll need to provide a username and password to interact with the Adyen
|
21
|
-
# SOAP services:
|
22
|
-
#
|
23
|
-
# Adyen::SOAP.username = 'ws@Company.MyAccount'
|
24
|
-
# Adyen::SOAP.password = 'very$ecret'
|
25
|
-
#
|
26
|
-
# You can setup default parameters that will be used by every SOAP call by
|
27
|
-
# using {Adyen::SOAP.default_arguments}. You can override these default
|
28
|
-
# values by passing another value as parameter to the actual call.
|
29
|
-
#
|
30
|
-
# Adyen::SOAP.default_arguments[:merchant_account] = 'MyMerchant'
|
31
|
-
#
|
32
|
-
# All SOAP clients are based on the {Adyen::SOAP::Base} class, which sets up
|
33
|
-
# the Handsoap library to work with the Adyen SOAP services and implements
|
34
|
-
# shared functionality. Based on this class, the following services are available:
|
35
|
-
#
|
36
|
-
# * {Adyen::SOAP::RecurringService} - SOAP service for handling recurring payments.
|
37
|
-
# * {Adyen::SOAP::PaymentService} - SOAP service for modification to payments. Currently,
|
38
|
-
# this class is just a stub. Feel free to implement it as you need it.
|
39
|
-
module SOAP
|
40
|
-
|
41
|
-
class << self
|
42
|
-
|
43
|
-
# Username for the HTTP Basic Authentication that Adyen uses. Your username
|
44
|
-
# should be something like +ws@Company.MyAccount+
|
45
|
-
# @return [String]
|
46
|
-
attr_accessor :username
|
47
|
-
|
48
|
-
# Password for the HTTP Basic Authentication that Adyen uses. You can choose
|
49
|
-
# your password yourself in the user management tool of the merchant area.
|
50
|
-
# @return [String]
|
51
|
-
attr_accessor :password
|
52
|
-
|
53
|
-
# Default arguments that will be used for every SOAP call.
|
54
|
-
# @return [Hash]
|
55
|
-
attr_accessor :default_arguments
|
56
|
-
end
|
57
|
-
|
58
|
-
self.default_arguments = {} # Set default value
|
59
|
-
|
60
|
-
# The base class sets up XML namespaces and the HTTP client
|
61
|
-
# for all the Adyen SOAP services.
|
62
|
-
class Base < Handsoap::Service
|
63
|
-
|
64
|
-
# Basic setup for the SOAP endpoint when creating a subclass.
|
65
|
-
#
|
66
|
-
# The version must be set to construct the request envelopes, the URI
|
67
|
-
# wil be set later using the correct {Adyen.environment} value. For now,
|
68
|
-
# use a bogus value so handsoap will not complain.
|
69
|
-
def self.inherited(klass) # :nodoc:
|
70
|
-
klass.endpoint :version => 1, :uri => 'bogus'
|
71
|
-
end
|
72
|
-
|
73
|
-
# Setup some CURL options to handle redirects correctly.
|
74
|
-
def on_after_create_http_client(http_client) # :nodoc:
|
75
|
-
http_client.follow_location = true
|
76
|
-
http_client.max_redirects = 2
|
77
|
-
end
|
78
|
-
|
79
|
-
# Setup basic authentication for SOAP requests
|
80
|
-
# @see Adyen::SOAP.username
|
81
|
-
# @see Adyen::SOAP.password
|
82
|
-
def on_after_create_http_request(http_request) # :nodoc:
|
83
|
-
debug { |logger| logger.puts "Authorization: #{Adyen::SOAP.username}:#{Adyen::SOAP.password}..." }
|
84
|
-
http_request.set_auth Adyen::SOAP.username, Adyen::SOAP.password
|
85
|
-
end
|
86
|
-
|
87
|
-
# Sets up XML namespaces for composing the SOAP request body.
|
88
|
-
def on_create_document(doc) # :nodoc:
|
89
|
-
doc.alias 'payment', 'http://payment.services.adyen.com'
|
90
|
-
doc.alias 'recurring', 'http://recurring.services.adyen.com'
|
91
|
-
doc.alias 'common', 'http://common.services.adyen.com'
|
92
|
-
end
|
93
|
-
|
94
|
-
# Sets up the XML namespaces for parsing the SOAP response.
|
95
|
-
def on_response_document(doc) # :nodoc:
|
96
|
-
doc.add_namespace 'payment', 'http://payment.services.adyen.com'
|
97
|
-
doc.add_namespace 'recurring', 'http://recurring.services.adyen.com'
|
98
|
-
doc.add_namespace 'common', 'http://common.services.adyen.com'
|
99
|
-
end
|
100
|
-
|
101
|
-
# Set endpoint URI before dispatch, so that changes in environment
|
102
|
-
# are reflected correctly.
|
103
|
-
def on_before_dispatch
|
104
|
-
self.class.endpoint(:uri => self.class::ENDPOINT_URI % Adyen.environment.to_s, :version => 1)
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
# SOAP client to interact with the payment modification service of Adyen. This client
|
109
|
-
# implements the following calls:
|
110
|
-
#
|
111
|
-
# * +authorise+ to list recurring contracts for a shopper, using {Adyen::SOAP::PaymentService#authorise}.
|
112
|
-
# * +cancelOrRefund+ to cancel a payment (or refund if it has been captured), using
|
113
|
-
# {Adyen::SOAP::PaymentService#cancel_or_refund}.
|
114
|
-
#
|
115
|
-
# Before using this service, make sure to set the SOAP username and
|
116
|
-
# password (see {Adyen::SOAP.username} and {Adyen::SOAP.password}).
|
117
|
-
class PaymentService < Base
|
118
|
-
|
119
|
-
ENDPOINT_URI = 'https://pal-%s.adyen.com/pal/servlet/soap/Payment'
|
120
|
-
|
121
|
-
# Submits a recurring payment for authorisation.
|
122
|
-
#
|
123
|
-
# @example
|
124
|
-
# Adyen::SOAP::PaymentService.authorise(
|
125
|
-
# :merchant_account => 'MyAccount', :selected_recurring_detail_reference => 'LATEST',
|
126
|
-
# :shopper_reference => user.id, :shopper_email => user.email,
|
127
|
-
# :reference => invoice.id, :currency => invoice.currency, :value => invoice.amount)
|
128
|
-
#
|
129
|
-
# @param [Hash] args The paramaters to use for this call. These will be merged by any default
|
130
|
-
# parameters set using {Adyen::SOAP.default_arguments}. Note that every option defined below
|
131
|
-
# is required by the Adyen SOAP service, so please provide a value for all options.
|
132
|
-
# @option args [String] :selected_recurring_detail_reference ('LATEST') This is the
|
133
|
-
# recurringDetailReference you want to use for this payment. You can use the
|
134
|
-
# value "LATEST" to select the most recently used recurring detail, which is the default.
|
135
|
-
# @option args [String] :merchant_account The merchant account you want to process this payment
|
136
|
-
# with.
|
137
|
-
# @option args [String] :currency The currency code (EUR, GBP, USD, etc).
|
138
|
-
# @option args [Integer] :value The value of the payment in cents.
|
139
|
-
# @option args [String] :reference Your reference for this payment. This (merchant) reference
|
140
|
-
# will be used in all communication to you about the status of the payment.
|
141
|
-
# Although it is a good idea to make sure it is unique, this is not a requirement.
|
142
|
-
# @option args [String] :shopper_email The email address of the shopper. This does not have to
|
143
|
-
# match the email address supplied with the initial payment, since it may have
|
144
|
-
# changed in the mean time.
|
145
|
-
# @option args [String] :shopper_reference The reference of the shopper. This should be
|
146
|
-
# the same as the reference that was used to create the recurring contract.
|
147
|
-
# @option args [Integer] :fraud_offset (optional) An integer that is added to normal fraud score.
|
148
|
-
# The value can be either positive or negative.
|
149
|
-
# @option args [String] :shopper_ip (optional) The IP address of the shopper. Used in various risk
|
150
|
-
# checks (number of payment attempts, location based checks), so it is a good idea to supply
|
151
|
-
# this.
|
152
|
-
#
|
153
|
-
# @return [nil] This action returns nothing of interest. The result of the authorization
|
154
|
-
# will be communicated using a {Adyen::Notification notification}.
|
155
|
-
#
|
156
|
-
# @see https://support.adyen.com/index.php?_m=downloads&_a=viewdownload&downloaditemid=1
|
157
|
-
# The Adyen integration manual
|
158
|
-
# @see https://support.adyen.com/index.php?_m=downloads&_a=viewdownload&downloaditemid=7&nav=0,3
|
159
|
-
# The Adyen recurring payments manual.
|
160
|
-
def authorise(args = {})
|
161
|
-
invoke_args = Adyen::SOAP.default_arguments.merge(args)
|
162
|
-
invoke_args[:selected_recurring_detail_reference] ||= 'LATEST'
|
163
|
-
|
164
|
-
response = invoke('payment:authorise') do |message|
|
165
|
-
message.add('payment:paymentRequest') do |req|
|
166
|
-
req.add('payment:selectedRecurringDetailReference', invoke_args[:selected_recurring_detail_reference])
|
167
|
-
req.add('payment:recurring') do |recurring|
|
168
|
-
recurring.add('payment:contract', 'RECURRING')
|
169
|
-
end
|
170
|
-
req.add('payment:merchantAccount', invoke_args[:merchant_account])
|
171
|
-
req.add('payment:amount') do |amount|
|
172
|
-
amount.add('common:currency', invoke_args[:currency])
|
173
|
-
amount.add('common:value', invoke_args[:value])
|
174
|
-
end
|
175
|
-
req.add('payment:reference', invoke_args[:reference])
|
176
|
-
req.add('payment:shopperEmail', invoke_args[:shopper_email])
|
177
|
-
req.add('payment:shopperReference', invoke_args[:shopper_reference])
|
178
|
-
req.add('payment:shopperInteraction', 'ContAuth')
|
179
|
-
|
180
|
-
# optional fields
|
181
|
-
req.add('payment:fraudOffset', invoke_args[:fraud_offset]) if(invoke_args[:fraud_offset])
|
182
|
-
req.add('payment:shopperIP', invoke_args[:shopper_ip]) if(invoke_args[:shopper_ip])
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
parse_authorise(response)
|
187
|
-
end
|
188
|
-
|
189
|
-
# Submits a direct debit recurring payment.
|
190
|
-
#
|
191
|
-
# @example
|
192
|
-
# Adyen::SOAP::PaymentService.directdebit(
|
193
|
-
# :merchant_account => 'MyAccount', :selected_recurring_detail_reference => 'LATEST',
|
194
|
-
# :shopper_reference => user.id, :shopper_email => user.email,
|
195
|
-
# :reference => invoice.id, :currency => invoice.currency, :value => invoice.amount)
|
196
|
-
#
|
197
|
-
# @param [Hash] args The paramaters to use for this call. These will be merged by any default
|
198
|
-
# parameters set using {Adyen::SOAP.default_arguments}. Note that every option defined below
|
199
|
-
# is required by the Adyen SOAP service, so please provide a value for all options.
|
200
|
-
# @option args [String] :selected_recurring_detail_reference ('LATEST') This is the
|
201
|
-
# recurringDetailReference you want to use for this payment. You can use the
|
202
|
-
# value "LATEST" to select the most recently used recurring detail, which is the default.
|
203
|
-
# @option args [String] :merchant_account The merchant account you want to process this payment
|
204
|
-
# with.
|
205
|
-
# @option args [String] :currency The currency code (EUR, GBP, USD, etc).
|
206
|
-
# @option args [Integer] :value The value of the payment in cents.
|
207
|
-
# @option args [String] :reference Your reference for this payment. This (merchant) reference
|
208
|
-
# will be used in all communication to you about the status of the payment.
|
209
|
-
# Although it is a good idea to make sure it is unique, this is not a requirement.
|
210
|
-
# @option args [String] :shopper_email The email address of the shopper. This does not have to
|
211
|
-
# match the email address supplied with the initial payment, since it may have
|
212
|
-
# changed in the mean time.
|
213
|
-
# @option args [String] :shopper_reference The reference of the shopper. This should be
|
214
|
-
# the same as the reference that was used to create the recurring contract.
|
215
|
-
# @option args [String] :shopper_ip (optional) The IP address of the shopper. Used in various risk
|
216
|
-
# checks (number of payment attempts, location based checks), so it is a good idea to supply
|
217
|
-
# this.
|
218
|
-
#
|
219
|
-
# @return [nil] This action returns nothing of interest. The result of the authorization
|
220
|
-
# will be communicated using a {Adyen::Notification notification}.
|
221
|
-
#
|
222
|
-
# @see https://support.adyen.com/index.php?_m=downloads&_a=viewdownload&downloaditemid=1
|
223
|
-
# The Adyen integration manual
|
224
|
-
# @see https://support.adyen.com/index.php?_m=downloads&_a=viewdownload&downloaditemid=7&nav=0,3
|
225
|
-
# The Adyen recurring payments manual.
|
226
|
-
def directdebit(args = {})
|
227
|
-
invoke_args = Adyen::SOAP.default_arguments.merge(args)
|
228
|
-
invoke_args[:selected_recurring_detail_reference] ||= 'LATEST'
|
229
|
-
|
230
|
-
response = invoke('payment:directdebit') do |message|
|
231
|
-
message.add('payment:request') do |req|
|
232
|
-
req.add('payment:selectedRecurringDetailReference', invoke_args[:selected_recurring_detail_reference])
|
233
|
-
req.add('payment:recurring') do |recurring|
|
234
|
-
recurring.add('payment:contract', 'RECURRING')
|
235
|
-
end
|
236
|
-
req.add('payment:merchantAccount', invoke_args[:merchant_account])
|
237
|
-
req.add('payment:amount') do |amount|
|
238
|
-
amount.add('common:currency', invoke_args[:currency])
|
239
|
-
amount.add('common:value', invoke_args[:value])
|
240
|
-
end
|
241
|
-
req.add('payment:reference', invoke_args[:reference])
|
242
|
-
req.add('payment:shopperEmail', invoke_args[:shopper_email])
|
243
|
-
req.add('payment:shopperReference', invoke_args[:shopper_reference])
|
244
|
-
req.add('payment:shopperInteraction', 'ContAuth')
|
245
|
-
req.add('payment:shopperIP', invoke_args[:shopper_ip]) if(invoke_args[:shopper_ip])
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
|
-
parse_directdebit(response)
|
250
|
-
end
|
251
|
-
|
252
|
-
# Capture a payment.
|
253
|
-
#
|
254
|
-
# @param [Hash] args The paramaters to use for this call. These will be merged by any default
|
255
|
-
# parameters set using {Adyen::SOAP.default_arguments}. Note that every option defined below
|
256
|
-
# is required by the Adyen SOAP service, so please provide a value for all options.
|
257
|
-
# @option args [String] :merchant_account The merchant account to file this payment under.
|
258
|
-
# @option args [String] :currency The currency code (EUR, GBP, USD, etc).
|
259
|
-
# @option args [Integer] :value The value of the payment in cents.
|
260
|
-
# @option args [String] :original_reference The psp_reference of the payment to capture.
|
261
|
-
#
|
262
|
-
# @return [nil] This action returns nothing of interest.
|
263
|
-
#
|
264
|
-
# @see https://support.adyen.com/index.php?_m=downloads&_a=viewdownload&downloaditemid=1
|
265
|
-
# The Adyen integration manual
|
266
|
-
#
|
267
|
-
# @todo Parse response object and return something useful
|
268
|
-
def capture(args = {})
|
269
|
-
invoke_args = Adyen::SOAP.default_arguments.merge(args)
|
270
|
-
response = invoke('payment:capture') do |message|
|
271
|
-
message.add('payment:modificationRequest') do |req|
|
272
|
-
req.add('payment:merchantAccount', invoke_args[:merchant_account])
|
273
|
-
req.add('payment:modificationAmount') do |amount|
|
274
|
-
amount.add('common:currency', invoke_args[:currency])
|
275
|
-
amount.add('common:value', invoke_args[:value])
|
276
|
-
end
|
277
|
-
req.add('payment:originalReference', invoke_args[:original_reference])
|
278
|
-
end
|
279
|
-
end
|
280
|
-
|
281
|
-
parse_capture(response)
|
282
|
-
end
|
283
|
-
|
284
|
-
# Cancel a payment.
|
285
|
-
#
|
286
|
-
# @param [Hash] args The paramaters to use for this call. These will be merged by any default
|
287
|
-
# parameters set using {Adyen::SOAP.default_arguments}. Note that every option defined below
|
288
|
-
# is required by the Adyen SOAP service, so please provide a value for all options.
|
289
|
-
# @option args [String] :merchant_account The merchant account to file this payment under.
|
290
|
-
# @option args [String] :original_reference The psp_reference of the payment to cancel.
|
291
|
-
#
|
292
|
-
# @return [nil] This action returns nothing of interest.
|
293
|
-
#
|
294
|
-
# @see https://support.adyen.com/index.php?_m=downloads&_a=viewdownload&downloaditemid=1
|
295
|
-
# The Adyen integration manual
|
296
|
-
#
|
297
|
-
# @todo Parse response object and return something useful
|
298
|
-
def cancel(args = {})
|
299
|
-
invoke_args = Adyen::SOAP.default_arguments.merge(args)
|
300
|
-
response = invoke('payment:cancel') do |message|
|
301
|
-
message.add('payment:modificationRequest') do |req|
|
302
|
-
req.add('payment:merchantAccount', invoke_args[:merchant_account])
|
303
|
-
req.add('payment:originalReference', invoke_args[:original_reference])
|
304
|
-
end
|
305
|
-
end
|
306
|
-
|
307
|
-
parse_cancel(response)
|
308
|
-
end
|
309
|
-
|
310
|
-
# Refund a payment.
|
311
|
-
#
|
312
|
-
# @param [Hash] args The paramaters to use for this call. These will be merged by any default
|
313
|
-
# parameters set using {Adyen::SOAP.default_arguments}. Note that every option defined below
|
314
|
-
# is required by the Adyen SOAP service, so please provide a value for all options.
|
315
|
-
# @option args [String] :merchant_account The merchant account to file this payment under.
|
316
|
-
# @option args [String] :currency The currency code (EUR, GBP, USD, etc).
|
317
|
-
# @option args [Integer] :value The value of the refund in cents.
|
318
|
-
# @option args [String] :original_reference The psp_reference of the payment to refund.
|
319
|
-
#
|
320
|
-
# @return [nil] This action returns nothing of interest.
|
321
|
-
#
|
322
|
-
# @see https://support.adyen.com/index.php?_m=downloads&_a=viewdownload&downloaditemid=1
|
323
|
-
# The Adyen integration manual
|
324
|
-
#
|
325
|
-
# @todo Parse response object and return something useful
|
326
|
-
def refund(args = {})
|
327
|
-
invoke_args = Adyen::SOAP.default_arguments.merge(args)
|
328
|
-
response = invoke('payment:refund') do |message|
|
329
|
-
message.add('payment:modificationRequest') do |req|
|
330
|
-
req.add('payment:merchantAccount', invoke_args[:merchant_account])
|
331
|
-
req.add('payment:modificationAmount') do |amount|
|
332
|
-
amount.add('common:currency', invoke_args[:currency])
|
333
|
-
amount.add('common:value', invoke_args[:value])
|
334
|
-
end
|
335
|
-
req.add('payment:originalReference', invoke_args[:original_reference])
|
336
|
-
end
|
337
|
-
end
|
338
|
-
|
339
|
-
parse_refund(response)
|
340
|
-
end
|
341
|
-
|
342
|
-
# Cancel or refund a payment.
|
343
|
-
#
|
344
|
-
# @param [Hash] args The paramaters to use for this call. These will be merged by any default
|
345
|
-
# parameters set using {Adyen::SOAP.default_arguments}. Note that every option defined below
|
346
|
-
# is required by the Adyen SOAP service, so please provide a value for all options.
|
347
|
-
# @option args [String] :merchant_account The merchant account to file this payment under.
|
348
|
-
# @option args [String] :original_reference The psp_reference of the payment to cancel or refund.
|
349
|
-
#
|
350
|
-
# @return [nil] This action returns nothing of interest.
|
351
|
-
#
|
352
|
-
# @see https://support.adyen.com/index.php?_m=downloads&_a=viewdownload&downloaditemid=1
|
353
|
-
# The Adyen integration manual
|
354
|
-
#
|
355
|
-
# @todo Parse response object and return something useful
|
356
|
-
def cancel_or_refund(args = {})
|
357
|
-
invoke_args = Adyen::SOAP.default_arguments.merge(args)
|
358
|
-
response = invoke('payment:cancelOrRefund') do |message|
|
359
|
-
message.add('payment:modificationRequest') do |req|
|
360
|
-
req.add('payment:merchantAccount', invoke_args[:merchant_account])
|
361
|
-
req.add('payment:originalReference', invoke_args[:original_reference])
|
362
|
-
end
|
363
|
-
end
|
364
|
-
|
365
|
-
parse_cancel_or_refund(response)
|
366
|
-
end
|
367
|
-
|
368
|
-
private
|
369
|
-
|
370
|
-
def parse_authorise(response)
|
371
|
-
response = response.xpath('//payment:authoriseResponse/payment:paymentResult')
|
372
|
-
{
|
373
|
-
:psp_reference => response.xpath('./payment:pspReference/text()').to_s,
|
374
|
-
:result_code => response.xpath('./payment:resultCode/text()').to_s,
|
375
|
-
:auth_code => response.xpath('./payment:authCode/text()').to_s,
|
376
|
-
:refusal_reason => response.xpath('./payment:refusalReason/text()').to_s
|
377
|
-
}
|
378
|
-
end
|
379
|
-
|
380
|
-
def parse_directdebit(response)
|
381
|
-
response = response.xpath('//payment:directdebitResponse/payment:response')
|
382
|
-
{
|
383
|
-
:psp_reference => response.xpath('./payment:pspReference/text()').to_s,
|
384
|
-
:result_code => response.xpath('./payment:resultCode/text()').to_s,
|
385
|
-
:auth_code => response.xpath('./payment:authCode/text()').to_s,
|
386
|
-
:refusal_reason => response.xpath('./payment:refusalReason/text()').to_s
|
387
|
-
}
|
388
|
-
end
|
389
|
-
|
390
|
-
def parse_capture(response)
|
391
|
-
response = response.xpath('//payment:captureResponse/payment:captureResult')
|
392
|
-
{
|
393
|
-
:psp_reference => response.xpath('./payment:pspReference/text()').to_s,
|
394
|
-
:response => response.xpath('./payment:response/text()').to_s
|
395
|
-
}
|
396
|
-
end
|
397
|
-
|
398
|
-
def parse_cancel(response)
|
399
|
-
response = response.xpath('//payment:cancelResponse/payment:cancelResult')
|
400
|
-
{
|
401
|
-
:psp_reference => response.xpath('./payment:pspReference/text()').to_s,
|
402
|
-
:response => response.xpath('./payment:response/text()').to_s
|
403
|
-
}
|
404
|
-
end
|
405
|
-
|
406
|
-
def parse_refund(response)
|
407
|
-
response = response.xpath('//payment:refundResponse/payment:refundResult')
|
408
|
-
{
|
409
|
-
:psp_reference => response.xpath('./payment:pspReference/text()').to_s,
|
410
|
-
:response => response.xpath('./payment:response/text()').to_s
|
411
|
-
}
|
412
|
-
end
|
413
|
-
|
414
|
-
def parse_cancel_or_refund(response)
|
415
|
-
response = response.xpath('//payment:cancelOrRefundResponse/payment:cancelOrRefundResult')
|
416
|
-
{
|
417
|
-
:psp_reference => response.xpath('./payment:pspReference/text()').to_s,
|
418
|
-
:response => response.xpath('./payment:response/text()').to_s
|
419
|
-
}
|
420
|
-
end
|
421
|
-
|
422
|
-
end
|
423
|
-
|
424
|
-
# SOAP client to interact with the recurring payment service of Adyen. This clients
|
425
|
-
# implements the following calls:
|
426
|
-
#
|
427
|
-
# * +listRecurring+ to list recurring contracts for a shopper, using {Adyen::SOAP::RecurringService#list}.
|
428
|
-
# * +submitRecurring+ to submit a recurring payment for a shopper, using {Adyen::SOAP::RecurringService#submit}.
|
429
|
-
# * +deactivateRecurring+ to cancel a recurring contract, using {Adyen::SOAP::RecurringService#deactivate}.
|
430
|
-
#
|
431
|
-
# Before using this service, make sure to set the SOAP username and
|
432
|
-
# password (see {Adyen::SOAP.username} and {Adyen::SOAP.password}).
|
433
|
-
#
|
434
|
-
# The recurring service requires shoppers to have a recurring contract.
|
435
|
-
# Such a contract can be set up when creating the initial payment using
|
436
|
-
# the {Adyen::Form} methods. After the payment has been authorized, a
|
437
|
-
# {Adyen::Notification RECURRING_CONTRACT notification} will be sent. The
|
438
|
-
# PSP reference of this notification should be used as
|
439
|
-
# +:recurring_reference+ parameters in these calls.
|
440
|
-
#
|
441
|
-
# @see https://support.adyen.com/index.php?_m=downloads&_a=viewdownload&downloaditemid=7&nav=0,3
|
442
|
-
# The Adyen recurring payments manual.
|
443
|
-
class RecurringService < Base
|
444
|
-
|
445
|
-
# The endpoint URI for this SOAP service, in which test or live should be filled in as
|
446
|
-
# environment.
|
447
|
-
# @see Adyen.environment
|
448
|
-
ENDPOINT_URI = 'https://pal-%s.adyen.com/pal/servlet/soap/Recurring'
|
449
|
-
|
450
|
-
# Submits a recurring payment for a recurring contract to Adyen.
|
451
|
-
#
|
452
|
-
# @deprecated This method has been replaced by {Adyen::SOAP::PaymentService.authorise}.
|
453
|
-
#
|
454
|
-
# @example
|
455
|
-
# Adyen::SOAP::RecurringService.submit(
|
456
|
-
# :merchant_account => 'MyAccount',
|
457
|
-
# :shopper_reference => user.id, :shopper_email => user.email,
|
458
|
-
# :recurring_reference => user.contract_notification.psp_reference,
|
459
|
-
# :reference => invoice.id, :currency => invoice.currency, :value => invoice.amount)
|
460
|
-
#
|
461
|
-
# @param [Hash] args The paramaters to use for this call. These will be merged by any default
|
462
|
-
# parameters set using {Adyen::SOAP.default_arguments}. Note that every option defined below
|
463
|
-
# is required by the Adyen SOAP service, so please provide a value for all options.
|
464
|
-
# @option args [String] :merchant_account The merchant account to file this payment under.
|
465
|
-
# @option args [String] :currency The currency code (EUR, GBP, USD, etc).
|
466
|
-
# @option args [Integer] :value The value of the payment in cents.
|
467
|
-
# @option args [Integer] :recurring_reference The psp_reference of the RECURRING_CONTRACT
|
468
|
-
# notification that was sent after the initial payment.
|
469
|
-
# @option args [String] :reference Your reference for this payment. This (merchant) reference
|
470
|
-
# will be used in all communication to you about the status of the payment.
|
471
|
-
# Although it is a good idea to make sure it is unique, this is not a requirement.
|
472
|
-
# @option args [String] :shopper_email The email address of the shopper. This does not have to
|
473
|
-
# match the email address supplied with the initial payment, since it may have
|
474
|
-
# changed in the mean time.
|
475
|
-
# @option args [String] :shopper_reference The reference of the shopper. This should be
|
476
|
-
# the same as the reference that was used to create the recurring contract.
|
477
|
-
#
|
478
|
-
# @return [nil] This method does not return anything. The result of the payment request will
|
479
|
-
# be communicated with an {Adyen::Notification}.
|
480
|
-
# @see Adyen::Notification#collect_payment_for_recurring_contract!
|
481
|
-
def submit(args = {})
|
482
|
-
invoke_args = Adyen::SOAP.default_arguments.merge(args)
|
483
|
-
response = invoke('recurring:submitRecurring') do |message|
|
484
|
-
message.add('recurring:recurringRequest') do |req|
|
485
|
-
req.add('recurring:amount') do |amount|
|
486
|
-
amount.add('common:currency', invoke_args[:currency])
|
487
|
-
amount.add('common:value', invoke_args[:value])
|
488
|
-
end
|
489
|
-
req.add('recurring:merchantAccount', invoke_args[:merchant_account])
|
490
|
-
req.add('recurring:recurringReference', invoke_args[:recurring_reference])
|
491
|
-
req.add('recurring:reference', invoke_args[:reference])
|
492
|
-
req.add('recurring:shopperEmail', invoke_args[:shopper_email])
|
493
|
-
req.add('recurring:shopperReference', invoke_args[:shopper_reference])
|
494
|
-
end
|
495
|
-
end
|
496
|
-
end
|
497
|
-
|
498
|
-
# Retrieves the recurring contracts for a shopper.
|
499
|
-
#
|
500
|
-
# @param [Hash] args The paramaters to use for this call. These will be merged by any default
|
501
|
-
# parameters set using {Adyen::SOAP.default_arguments}. Note that every option defined below
|
502
|
-
# is required by the Adyen SOAP service, so please provide a value for all options.
|
503
|
-
# @option args [String] :merchant_account The merchant account to file this payment under.
|
504
|
-
# @option args [String] :shopper_reference The refrence of the shopper. This should be
|
505
|
-
# the same as the reference that was used to create the recurring contract.
|
506
|
-
#
|
507
|
-
# @return [Hash] This method returns a hash representation of the
|
508
|
-
# listRecurringDetailsResponse.
|
509
|
-
#
|
510
|
-
def list(args = {})
|
511
|
-
invoke_args = Adyen::SOAP.default_arguments.merge(args)
|
512
|
-
response = invoke('recurring:listRecurringDetails') do |message|
|
513
|
-
message.add('recurring:request') do |req|
|
514
|
-
req.add('recurring:recurring') do |recurring|
|
515
|
-
recurring.add('recurring:contract', 'RECURRING')
|
516
|
-
end
|
517
|
-
req.add('recurring:merchantAccount', invoke_args[:merchant_account])
|
518
|
-
req.add('recurring:shopperReference', invoke_args[:shopper_reference])
|
519
|
-
end
|
520
|
-
end
|
521
|
-
|
522
|
-
parse_list_recurring_details(response)
|
523
|
-
end
|
524
|
-
|
525
|
-
# Disables a recurring payment contract. Requires the following arguments:
|
526
|
-
#
|
527
|
-
# @example
|
528
|
-
# Adyen::SOAP::RecurringService.disable(
|
529
|
-
# :merchant_account => 'MyAccount', :shopper_reference => user.id,
|
530
|
-
# :recurring_detail_reference => user.contract_notification.psp_reference)
|
531
|
-
#
|
532
|
-
# @param [Hash] args The paramaters to use for this call. These will be merged by any default
|
533
|
-
# parameters set using {Adyen::SOAP.default_arguments}. Note that every option defined below
|
534
|
-
# is required by the Adyen SOAP service, so please provide a value for all options.
|
535
|
-
# @option args [String] :merchant_account Your merchant account.
|
536
|
-
# @option args [String] :shopper_reference The reference to the shopper. This shopperReference
|
537
|
-
# must be the same as the shopperReference used in the initial payment.
|
538
|
-
# @option args [String] :recurring_detail_reference The recurringDetailReference of the
|
539
|
-
# details you wish to disable. If you do not supply this field, all details for the shopper
|
540
|
-
# will be disabled, including the contract! This means that you can not add new details
|
541
|
-
# anymore.
|
542
|
-
def disable(args = {})
|
543
|
-
invoke_args = Adyen::SOAP.default_arguments.merge(args)
|
544
|
-
response = invoke('recurring:disable') do |message|
|
545
|
-
message.add('recurring:request') do |req|
|
546
|
-
req.add('recurring:merchantAccount', invoke_args[:merchant_account])
|
547
|
-
req.add('recurring:shopperReference', invoke_args[:shopper_reference])
|
548
|
-
req.add('recurring:recurringDetailReference', invoke_args[:recurring_detail_reference])
|
549
|
-
end
|
550
|
-
end
|
551
|
-
|
552
|
-
parse_disable(response)
|
553
|
-
end
|
554
|
-
|
555
|
-
# Deactivates a recurring payment contract. Requires the following arguments:
|
556
|
-
#
|
557
|
-
# @deprecated This method has been replaced by the {#disable} method.
|
558
|
-
#
|
559
|
-
# @example
|
560
|
-
# Adyen::SOAP::RecurringService.deactivate(
|
561
|
-
# :merchant_account => 'MyAccount', :shopper_reference => user.id,
|
562
|
-
# :recurring_reference => user.contract_notification.psp_reference,
|
563
|
-
# :reference => "Terminated account #{user.account.id}")
|
564
|
-
#
|
565
|
-
# @param [Hash] args The paramaters to use for this call. These will be merged by any default
|
566
|
-
# parameters set using {Adyen::SOAP.default_arguments}. Note that every option defined below
|
567
|
-
# is required by the Adyen SOAP service, so please provide a value for all options.
|
568
|
-
# @option args [String] :merchant_account The merchant account to file this payment under.
|
569
|
-
# @option args [String] :shopper_reference The refrence of the shopper. This should be
|
570
|
-
# the same as the reference that was used to create the recurring contract.
|
571
|
-
# @option args [Integer] :recurring_reference The psp_reference of the RECURRING_CONTRACT
|
572
|
-
# notification that was sent after the initial payment.
|
573
|
-
# @option args [String] :reference The (merchant) reference for this contract deactivation.
|
574
|
-
# Use any string you like that helps you identify this contract deactivation.
|
575
|
-
#
|
576
|
-
# @return [nil] This method does not return anything.
|
577
|
-
# @see Adyen::Notification#deactivate_recurring_contract!
|
578
|
-
def deactivate(args = {})
|
579
|
-
invoke_args = Adyen::SOAP.default_arguments.merge(args)
|
580
|
-
response = invoke('recurring:deactivateRecurring') do |message|
|
581
|
-
message.add('recurring:recurringRequest') do |req|
|
582
|
-
req.add('recurring:merchantAccount', invoke_args[:merchant_account])
|
583
|
-
req.add('recurring:recurringReference', invoke_args[:recurring_reference])
|
584
|
-
req.add('recurring:reference', invoke_args[:reference])
|
585
|
-
req.add('recurring:shopperReference', invoke_args[:shopper_reference])
|
586
|
-
end
|
587
|
-
end
|
588
|
-
end
|
589
|
-
|
590
|
-
private
|
591
|
-
|
592
|
-
def parse_list_recurring_details(response)
|
593
|
-
response = response.xpath('//recurring:listRecurringDetailsResponse/recurring:result')
|
594
|
-
{
|
595
|
-
:creation_date => response.xpath('./recurring:creationDate/text()').to_date,
|
596
|
-
:details => response.xpath('.//recurring:RecurringDetail').map { |node| parse_recurring_detail(node) },
|
597
|
-
:last_known_shopper_email => response.xpath('./recurring:lastKnownShopperEmail/text()').to_s,
|
598
|
-
:shopper_reference => response.xpath('./recurring:shopperReference/text()').to_s
|
599
|
-
}
|
600
|
-
end
|
601
|
-
|
602
|
-
# @todo add support for elv
|
603
|
-
def parse_recurring_detail(node)
|
604
|
-
result = if(not node.xpath('./recurring:card').to_s.nil?)
|
605
|
-
parse_card(node)
|
606
|
-
elsif(not node.xpath('./recurring:bank').to_s.nil?)
|
607
|
-
parse_bank(node)
|
608
|
-
end
|
609
|
-
|
610
|
-
result.merge({
|
611
|
-
:recurring_detail_reference => node.xpath('./recurring:recurringDetailReference/text()').to_s,
|
612
|
-
:variant => node.xpath('./recurring:variant/text()').to_s,
|
613
|
-
:creation_date => node.xpath('./recurring:creationDate/text()').to_date
|
614
|
-
})
|
615
|
-
end
|
616
|
-
|
617
|
-
def parse_card(node)
|
618
|
-
{
|
619
|
-
:card => {
|
620
|
-
:expiry_date => Date.new(node.xpath('./recurring:card/payment:expiryYear/text()').to_i, node.xpath('recurring:card/payment:expiryMonth').to_i, -1),
|
621
|
-
:holder_name => node.xpath('./recurring:card/payment:holderName/text()').to_s,
|
622
|
-
:number => node.xpath('./recurring:card/payment:number/text()').to_s
|
623
|
-
}
|
624
|
-
}
|
625
|
-
end
|
626
|
-
|
627
|
-
def parse_bank(node)
|
628
|
-
{
|
629
|
-
:bank => {
|
630
|
-
:bank_account_number => node.xpath('./recurring:bank/payment:bankAccountNumber/text()').to_s,
|
631
|
-
:bank_location_id => node.xpath('./recurring:bank/payment:bankLocationId/text()').to_s,
|
632
|
-
:bank_name => node.xpath('./recurring:bank/payment:bankName/text()').to_s,
|
633
|
-
:bic => node.xpath('./recurring:bank/payment:bic/text()').to_s,
|
634
|
-
:country_code => node.xpath('./recurring:bank/payment:countryCode/text()').to_s,
|
635
|
-
:iban => node.xpath('./recurring:bank/payment:iban/text()').to_s,
|
636
|
-
:owner_name => node.xpath('./recurring:bank/payment:ownerName/text()').to_s
|
637
|
-
}
|
638
|
-
}
|
639
|
-
end
|
640
|
-
|
641
|
-
def parse_disable(response)
|
642
|
-
response = response.xpath('//recurring:disableResponse/recurring:result')
|
643
|
-
{
|
644
|
-
:response => response.xpath('./recurring:response/text()').to_s
|
645
|
-
}
|
646
|
-
end
|
647
|
-
end
|
648
|
-
end
|
649
|
-
end
|