zaala 0.1.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.
- checksums.yaml +7 -0
- data/lib/zaala/api/client.rb +151 -0
- data/lib/zaala/api/error.rb +19 -0
- data/lib/zaala/api/types.rb +833 -0
- data/lib/zaala/api.rb +5 -0
- data/lib/zaala.rb +3 -0
- metadata +89 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 23d2b71b2a1a767732f1e981ec456ee03d30dfa9aae6da0b331d7f19aee61050
|
4
|
+
data.tar.gz: 060b17d5d44dda277f3c463358f94083dc03e8f55ae75715ea13322b37298208
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 91778343fc0ee1a12d34e217e72b6486330a4533d28fd0654a0a9ad900b12769731bcd88e453d49a48c17d7686201c148d1cb473abf46498ffb0d82186f1fa86
|
7
|
+
data.tar.gz: '085382d92b9b1e165d10e071fa1fe0fa5486c3024b8a8848b6074507ee5b775ed95e88437fda5b07e8dd34cc89a90bf58ff7aaf5f80e0b4de6c6b35cf1d02a4c'
|
@@ -0,0 +1,151 @@
|
|
1
|
+
module Zaala::API
|
2
|
+
require 'savon'
|
3
|
+
|
4
|
+
require_relative "error"
|
5
|
+
require_relative "types"
|
6
|
+
|
7
|
+
class Client
|
8
|
+
# * *Args* :
|
9
|
+
# - +wsdl+ -> URL that points to the WSDL file
|
10
|
+
# - +username+ -> Username (optional)
|
11
|
+
# - +password+ -> Password (optional)
|
12
|
+
def initialize(wsdl:, username: '', password: '', log: false, proxy: nil)
|
13
|
+
symbolize_keys = lambda { |key| key.to_sym }
|
14
|
+
params = {
|
15
|
+
wsdl: wsdl,
|
16
|
+
open_timeout: 30, # in seconds
|
17
|
+
read_timeout: 30, # in seconds
|
18
|
+
convert_response_tags_to: symbolize_keys,
|
19
|
+
log: log,
|
20
|
+
proxy: proxy
|
21
|
+
}
|
22
|
+
|
23
|
+
@kar = if username != '' && password != ''
|
24
|
+
Savon.client(params.merge({
|
25
|
+
basic_auth: [username, password],
|
26
|
+
}))
|
27
|
+
else
|
28
|
+
Savon.client(params)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Authenticate API calls
|
33
|
+
#
|
34
|
+
# * *Args* :
|
35
|
+
# - +username+ -> Username
|
36
|
+
# - +password+ -> Password
|
37
|
+
def add_login_credentials(username, password)
|
38
|
+
@kar = Savon.client(wsdl: wsdl, basic_auth: [username, password])
|
39
|
+
end
|
40
|
+
|
41
|
+
# Authorizes a reservation of funds for a future purchase.
|
42
|
+
def pre_authorize(req)
|
43
|
+
ensure_operation_exists(:pre_authorize)
|
44
|
+
raise BadRequestError.new("pre_authorize operation requires an AuthorizationRequest parameter") unless req.is_a?(AuthorizationRequest)
|
45
|
+
|
46
|
+
@kar.call(:pre_authorize) do
|
47
|
+
message(authorizationRequest: req.to_message)
|
48
|
+
end
|
49
|
+
rescue Savon::SOAPFault => e
|
50
|
+
# IS0003
|
51
|
+
# TODO: Extract error code from response body
|
52
|
+
# e.g. (The content of at least one field is invalid and did not pass the validation)
|
53
|
+
raise BadRequestError.new(e)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Authorizes a purchase transaction.
|
57
|
+
def authorize(req)
|
58
|
+
ensure_operation_exists(:authorize)
|
59
|
+
raise BadRequestError.new("authorize operation requires an AuthorizationRequest parameter") unless req.is_a?(AuthorizationRequest)
|
60
|
+
|
61
|
+
res = @kar.call(:authorize) do
|
62
|
+
message(authorizationRequest: req.to_message)
|
63
|
+
end
|
64
|
+
AuthorizationResponse.from_message(res.body[:authorizeResponse][:return])
|
65
|
+
rescue Savon::SOAPFault => e
|
66
|
+
# e.g. (The content of at least one field is invalid and did not pass the validation)
|
67
|
+
raise BadRequestError.new(e)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Cancel a previous reservation of funds.
|
71
|
+
def cancel_authorization(req)
|
72
|
+
ensure_operation_exists(:cancel_authorization)
|
73
|
+
raise BadRequestError.new("cancel_authorization operation requires a CancellationRequest parameter") unless req.is_a?(CancellationRequest)
|
74
|
+
|
75
|
+
@kar.call(:cancel_authorization) do
|
76
|
+
message(cancellationRequest: req.to_message)
|
77
|
+
end
|
78
|
+
rescue Savon::SOAPFault => e
|
79
|
+
# e.g. (The content of at least one field is invalid and did not pass the validation)
|
80
|
+
raise BadRequestError.new(e)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Perform a solvency check.
|
84
|
+
def check(req)
|
85
|
+
ensure_operation_exists(:check)
|
86
|
+
raise BadRequestError.new("check operation requires a CheckRequest parameter") unless req.is_a?(CheckRequest)
|
87
|
+
|
88
|
+
@kar.call(:check) do
|
89
|
+
message(checkRequest: req.to_message)
|
90
|
+
end
|
91
|
+
rescue Savon::SOAPFault => e
|
92
|
+
# e.g. (The content of at least one field is invalid and did not pass the validation)
|
93
|
+
raise BadRequestError.new(e)
|
94
|
+
end
|
95
|
+
|
96
|
+
# Returns available information about an authorization-ID.
|
97
|
+
def info(req)
|
98
|
+
ensure_operation_exists(:info)
|
99
|
+
raise BadRequestError.new("info operation requires an InfoRequest parameter") unless req.is_a?(InfoRequest)
|
100
|
+
|
101
|
+
@kar.call(:info) do
|
102
|
+
message(infoRequest: req.to_message)
|
103
|
+
end
|
104
|
+
rescue Savon::SOAPFault => e
|
105
|
+
# TODO: Extract error code from response body
|
106
|
+
# e.g. (The content of at least one field is invalid and did not pass the validation)
|
107
|
+
raise BadRequestError.new(e)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Verifies the given MTAN.
|
111
|
+
def verify(req)
|
112
|
+
ensure_operation_exists(:verify)
|
113
|
+
raise BadRequestError.new("info operation requires a VerifyRequest parameter") unless req.is_a?(VerifyRequest)
|
114
|
+
|
115
|
+
@kar.call(:verify) do
|
116
|
+
message(verifyRequest: req.to_message)
|
117
|
+
end
|
118
|
+
rescue Savon::SOAPFault => e
|
119
|
+
# TODO: Extract error code from response body
|
120
|
+
# e.g. (The content of at least one field is invalid and did not pass the validation)
|
121
|
+
raise BadRequestError.new(e)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Submits a purchase transaction with a previous authorization of funds.
|
125
|
+
def submit_authorization(req)
|
126
|
+
ensure_operation_exists(:submit_authorization)
|
127
|
+
raise BadRequestError.new("info operation requires a SubmissionRequest parameter") unless req.is_a?(SubmissionRequest)
|
128
|
+
|
129
|
+
res = @kar.call(:submit_authorization) do
|
130
|
+
message(submissionRequest: req.to_message)
|
131
|
+
end
|
132
|
+
SubmissionResponse.from_message(res.body[:submitAuthorizationResponse][:return])
|
133
|
+
rescue Savon::SOAPFault => e
|
134
|
+
# TODO: Extract error code from response body
|
135
|
+
# e.g. (The content of at least one field is invalid and did not pass the validation)
|
136
|
+
raise BadRequestError.new(e)
|
137
|
+
end
|
138
|
+
|
139
|
+
# Authorizes a credit transaction.
|
140
|
+
def credit_advice(req)
|
141
|
+
ensure_operation_exists(:credit_advice)
|
142
|
+
raise StandardError, 'unimplemented operation'
|
143
|
+
end
|
144
|
+
|
145
|
+
private
|
146
|
+
|
147
|
+
def ensure_operation_exists(op)
|
148
|
+
raise(UnsupportedServiceEndpoint, op) unless @kar.operations.include?(op)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Zaala::API
|
2
|
+
class MissingError < StandardError
|
3
|
+
end
|
4
|
+
class BadRequestError < StandardError
|
5
|
+
end
|
6
|
+
class PermissionError < StandardError
|
7
|
+
end
|
8
|
+
class UnauthenticatedError < StandardError
|
9
|
+
end
|
10
|
+
class ConflictError < StandardError
|
11
|
+
# TODO: Add resource
|
12
|
+
end
|
13
|
+
|
14
|
+
class UnsupportedServiceEndpoint < StandardError
|
15
|
+
def initialize(op)
|
16
|
+
super("unsupported \"#{op}\" operation. Is it the correct WSDL file? This client supports KarApiV50.")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,833 @@
|
|
1
|
+
module Zaala::API
|
2
|
+
require 'dry-types'
|
3
|
+
require 'dry-struct'
|
4
|
+
|
5
|
+
module Types
|
6
|
+
include Dry.Types()
|
7
|
+
end
|
8
|
+
|
9
|
+
# The class ClientInfoEntry represents a key-value pair holding information of the service's client (e.g. IPv4 address).
|
10
|
+
class ClientInfo < Dry::Struct
|
11
|
+
# the IP v4 address of the end customer doing the ckeckout, if available
|
12
|
+
attribute :ipv4, Types::Strict::String.optional.default(nil)
|
13
|
+
# the IP v6 address of the end customer doing the ckeckout, if available
|
14
|
+
attribute :ipv6, Types::Strict::String.optional.default(nil)
|
15
|
+
# set to true if the integration supports the verification process
|
16
|
+
attribute :feature_mtan, Types::Strict::Bool.optional.default(nil)
|
17
|
+
# set to true if the integration supports the verification process
|
18
|
+
attribute :spec_version, Types::Strict::String.optional.default(nil)
|
19
|
+
# name of the implementor / integrator, e.g. Customweb, Datatrans, Manor, ...
|
20
|
+
attribute :impl_vendor, Types::Strict::String.optional.default(nil)
|
21
|
+
# version of the KaR API client implementation, e.g. "Magento/1.25.32"
|
22
|
+
attribute :impl_version, Types::Strict::String.optional.default(nil)
|
23
|
+
end
|
24
|
+
|
25
|
+
# The class RequestIdentifier contains data to determine the origin of a web service call.
|
26
|
+
class RequestIdentifier < Dry::Struct
|
27
|
+
# ID of the web shop. Min. value: 1
|
28
|
+
attribute :web_shop_id, Types::Strict::Integer
|
29
|
+
# Authorization type of the request. Field can't be null.
|
30
|
+
attribute :authorization_type, Types::Strict::String
|
31
|
+
|
32
|
+
# ID of a previous preAuthorization. Mandatory for the following transaction request types (IF0003):
|
33
|
+
# SubmissionRequest
|
34
|
+
# CreditRequest
|
35
|
+
# CancellationRequest
|
36
|
+
# InfoRequest
|
37
|
+
# VerifyRequest
|
38
|
+
attribute :authorization_id, Types::Strict::Integer.optional.default(nil)
|
39
|
+
# Unique identifier of the POS (Point Of Sale) within the web shop. Mandatory in case of a POS sale. (IF0004)
|
40
|
+
attribute :pos_id, Types::Strict::String.optional.default(nil)
|
41
|
+
|
42
|
+
def self.from_message(h)
|
43
|
+
RequestIdentifier.new({
|
44
|
+
web_shop_id: h[:webShopId],
|
45
|
+
authorization_type: h[:authorizationType],
|
46
|
+
authorization_id: h[:authorizationId],
|
47
|
+
pos_id: h[:posId],
|
48
|
+
})
|
49
|
+
end
|
50
|
+
|
51
|
+
def to_message
|
52
|
+
m = {
|
53
|
+
webShopId: web_shop_id,
|
54
|
+
authorizationType: authorization_type
|
55
|
+
}
|
56
|
+
m[:authorizationId] = authorization_id unless authorization_id.nil?
|
57
|
+
m[:posId] = pos_id unless pos_id.nil?
|
58
|
+
m
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# The class PersonalData represents the detail information about the customer.
|
63
|
+
class PersonalData < Dry::Struct
|
64
|
+
# Type of the customer.
|
65
|
+
attribute :customer_type, Types::Strict::String
|
66
|
+
# Language of the customer.
|
67
|
+
attribute :language, Types::Strict::String
|
68
|
+
|
69
|
+
# The gender of the customer. Mandatory for country 'Private'. (IF0025)
|
70
|
+
attribute :gender, Types::Strict::String.optional.default(nil)
|
71
|
+
# Title of the customer.
|
72
|
+
attribute :title, Types::Strict::String.optional.default(nil)
|
73
|
+
# ID of the customer within the web shop.
|
74
|
+
attribute :customer_id, Types::Strict::String.optional.default(nil)
|
75
|
+
# First name of the customer. Mandatory for CustomerType 'Private'. (IF0020)
|
76
|
+
attribute :first_name, Types::Strict::String.optional.default(nil)
|
77
|
+
# Last name of the customer. Mandatory for CustomerType 'Private'. (IF0021)
|
78
|
+
attribute :name, Types::Strict::String.optional.default(nil)
|
79
|
+
# Customer's date of birth. Mandatory for CustomerType 'Private'.
|
80
|
+
# (IF0022) If so, it must contain a date between 12 and 120 years in the past. (IF0023)
|
81
|
+
attribute :date_of_birth, Types::Strict::Date.optional.default(nil)
|
82
|
+
# Fixnet phone number of the customer.
|
83
|
+
attribute :fixnet_phone_number, Types::Strict::String.optional.default(nil)
|
84
|
+
# Mobile phone number of the customer.
|
85
|
+
attribute :mobile_phone_number, Types::Strict::String.optional.default(nil)
|
86
|
+
# EMail address of the customer. Field must contain a valid email address.
|
87
|
+
attribute :email, Types::Strict::String.optional.default(nil)
|
88
|
+
# Company name. Mandatory for CustomerType 'Company'. (IF0018)
|
89
|
+
attribute :company_name, Types::Strict::String.optional.default(nil)
|
90
|
+
# Company account number.
|
91
|
+
attribute :company_number, Types::Strict::String.optional.default(nil)
|
92
|
+
# Company UID (https://www.uid.admin.ch).
|
93
|
+
attribute :company_uid, Types::Strict::String.optional.default(nil)
|
94
|
+
# Company legal form. Mandatory for CustomerType 'Company'. (IF0019)
|
95
|
+
attribute :company_legal_form, Types::Strict::String.optional.default(nil)
|
96
|
+
# Company legal form. Has to contain a value if member companyLegalForm equals 'other'.
|
97
|
+
# (IF0002) Mandatory for CustomerType 'Company'.
|
98
|
+
attribute :company_legal_form_other, Types::Strict::String.optional.default(nil)
|
99
|
+
# Company foundation date.
|
100
|
+
attribute :company_foundation_date, Types::Strict::Date.optional.default(nil)
|
101
|
+
|
102
|
+
def self.from_message(h)
|
103
|
+
PersonalData.new({
|
104
|
+
customer_type: h[:customerType],
|
105
|
+
language: h[:language],
|
106
|
+
gender: h[:gender],
|
107
|
+
title: h[:title],
|
108
|
+
customer_id: h[:customerID],
|
109
|
+
first_name: h[:firstName],
|
110
|
+
name: h[:name],
|
111
|
+
date_of_birth: h[:dateOfBirth],
|
112
|
+
fixnet_phone_number: h[:fixnetPhoneNumber],
|
113
|
+
mobile_phone_number: h[:mobilePhoneNumber],
|
114
|
+
email: h[:eMail],
|
115
|
+
company_name: h[:companyName],
|
116
|
+
company_number: h[:companyNumber],
|
117
|
+
company_uid: h[:companyUid],
|
118
|
+
company_legal_form: h[:companyLegalForm],
|
119
|
+
company_legal_form_other: h[:companyLegalFormOther],
|
120
|
+
company_foundation_date: h[:companyFoundationDate],
|
121
|
+
})
|
122
|
+
end
|
123
|
+
|
124
|
+
def to_message
|
125
|
+
m = {
|
126
|
+
customerType: customer_type,
|
127
|
+
language: language
|
128
|
+
}
|
129
|
+
m[:gender] = gender unless gender.nil?
|
130
|
+
m[:title] = title unless title.nil?
|
131
|
+
m[:customerID] = customer_id unless customer_id.nil?
|
132
|
+
m[:firstName] = first_name unless first_name.nil?
|
133
|
+
m[:name] = name unless name.nil?
|
134
|
+
m[:dateOfBirth] = date_of_birth unless date_of_birth.nil?
|
135
|
+
m[:fixnetPhoneNumber] = fixnet_phone_number unless fixnet_phone_number.nil?
|
136
|
+
m[:mobilePhoneNumber] = mobile_phone_number unless mobile_phone_number.nil?
|
137
|
+
m[:eMail] = email unless email.nil?
|
138
|
+
m[:companyName] = company_name unless company_name.nil?
|
139
|
+
m[:companyNumber] = company_number unless company_number.nil?
|
140
|
+
m[:companyUid] = company_uid unless company_uid.nil?
|
141
|
+
m[:companyLegalForm] = company_legal_form unless company_legal_form.nil?
|
142
|
+
m[:companyLegalFormOther] = company_legal_form_other unless company_legal_form_other.nil?
|
143
|
+
m[:companyFoundationDate] = company_foundation_date unless company_foundation_date.nil?
|
144
|
+
m
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# The class InvoiceAddress represents the invoice address of a purchase.
|
149
|
+
class InvoiceAddress < Dry::Struct
|
150
|
+
# Country code according to [ISO3166-1_alpha-2] Field can't be blank.
|
151
|
+
attribute :country, Types::Strict::String
|
152
|
+
# City Field can't be blank.
|
153
|
+
attribute :city, Types::Strict::String
|
154
|
+
# ZipCode Field can't be blank.
|
155
|
+
attribute :zip_code, Types::Strict::String
|
156
|
+
|
157
|
+
# Additional address information (contact person or division).
|
158
|
+
attribute :address_add_on, Types::Strict::String.optional.default(nil)
|
159
|
+
# House number
|
160
|
+
attribute :house_number, Types::Strict::String.optional.default(nil)
|
161
|
+
# Street
|
162
|
+
attribute :street, Types::Strict::String.optional.default(nil)
|
163
|
+
# Additional street information.
|
164
|
+
attribute :street_extension, Types::Strict::String.optional.default(nil)
|
165
|
+
|
166
|
+
def self.from_message(h)
|
167
|
+
InvoiceAddress.new({
|
168
|
+
country: h[:country],
|
169
|
+
city: h[:city],
|
170
|
+
zip_code: h[:zipCode],
|
171
|
+
address_add_on: h[:addressAddOn],
|
172
|
+
house_number: h[:houseNumber],
|
173
|
+
street: h[:street],
|
174
|
+
street_extension: h[:streetExtension],
|
175
|
+
})
|
176
|
+
end
|
177
|
+
|
178
|
+
def to_message
|
179
|
+
m = {
|
180
|
+
country: country,
|
181
|
+
city: city,
|
182
|
+
zipCode: zip_code
|
183
|
+
}
|
184
|
+
m[:addressAddOn] = address_add_on unless address_add_on.nil?
|
185
|
+
m[:houseNumber] = house_number unless house_number.nil?
|
186
|
+
m[:street] = street unless street.nil?
|
187
|
+
m[:streetExtension] = street_extension unless street_extension.nil?
|
188
|
+
m
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
# The class DeliveryAddress represents the delivery address of a purchase.
|
193
|
+
class DeliveryAddress < Dry::Struct
|
194
|
+
# Country code according to [ISO3166-1_alpha-2] Field can't be blank.
|
195
|
+
attribute :country, Types::Strict::String
|
196
|
+
# City Field can't be blank.
|
197
|
+
attribute :city, Types::Strict::String
|
198
|
+
# ZipCode Field can't be blank.
|
199
|
+
attribute :zip_code, Types::Strict::String
|
200
|
+
|
201
|
+
# Additional address information (contact person or division).
|
202
|
+
attribute :address_add_on, Types::Strict::String.optional.default(nil)
|
203
|
+
# House number
|
204
|
+
attribute :house_number, Types::Strict::String.optional.default(nil)
|
205
|
+
# Street
|
206
|
+
attribute :street, Types::Strict::String.optional.default(nil)
|
207
|
+
# Additional street information.
|
208
|
+
attribute :street_extension, Types::Strict::String.optional.default(nil)
|
209
|
+
# Name of the company.
|
210
|
+
attribute :company_name, Types::Strict::String.optional.default(nil)
|
211
|
+
# Title of the goods receiving customer.
|
212
|
+
attribute :title, Types::Strict::String.optional.default(nil)
|
213
|
+
# First name of the goods receiving customer.
|
214
|
+
attribute :first_name, Types::Strict::String.optional.default(nil)
|
215
|
+
# Last name of the goods receiving customer.
|
216
|
+
attribute :name, Types::Strict::String.optional.default(nil)
|
217
|
+
|
218
|
+
def self.from_message(h)
|
219
|
+
DeliveryAddress.new({
|
220
|
+
country: h[:country],
|
221
|
+
city: h[:city],
|
222
|
+
zip_code: h[:zipCode],
|
223
|
+
address_add_on: h[:addressAddOn],
|
224
|
+
house_number: h[:houseNumber],
|
225
|
+
street: h[:street],
|
226
|
+
street_extension: h[:streetExtension],
|
227
|
+
company_name: h[:companyName],
|
228
|
+
title: h[:title],
|
229
|
+
first_name: h[:firstName],
|
230
|
+
name: h[:name],
|
231
|
+
})
|
232
|
+
end
|
233
|
+
|
234
|
+
def to_message
|
235
|
+
m = {
|
236
|
+
country: country,
|
237
|
+
city: city,
|
238
|
+
zipCode: zip_code
|
239
|
+
}
|
240
|
+
m[:addressAddOn] = address_add_on unless address_add_on.nil?
|
241
|
+
m[:houseNumber] = house_number unless house_number.nil?
|
242
|
+
m[:street] = street unless street.nil?
|
243
|
+
m[:streetExtension] = street_extension unless street_extension.nil?
|
244
|
+
m[:companyName] = company_name unless company_name.nil?
|
245
|
+
m[:title] = title unless title.nil?
|
246
|
+
m[:firstName] = first_name unless first_name.nil?
|
247
|
+
m[:name] = name unless name.nil?
|
248
|
+
m
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
class DetailRecord < Dry::Struct
|
253
|
+
# Quantity ordered. Decimal places: max. = 6
|
254
|
+
attribute :quantity, Types::Strict::Float
|
255
|
+
# Total amount of the product charged to the customer.
|
256
|
+
# This amount has to consider rebatePercentage, if given.
|
257
|
+
# Amount = AmountWithoutVat + VatAmount(IF0009)
|
258
|
+
# Amount = SingleArticleAmount * Quantity * (100% - RebatePercentage) (IF0026) Decimal places: max. = 2
|
259
|
+
attribute :amount, Types::Strict::Float
|
260
|
+
# Percentage value of the VAT. Allowed values: 0, 2.5, 3.7, 3.8, 7,7 and 8 (IF0012)
|
261
|
+
attribute :vat_percent, Types::Strict::Float
|
262
|
+
# Amount of the VAT. Decimal places: max. = 2
|
263
|
+
attribute :vat_amount, Types::Strict::Float
|
264
|
+
# Total amount of the product without VAT.
|
265
|
+
# AmountWithoutVat = SingleArticleAmountWithoutVat * Quantity * (100% - RebatePercentage) (IF0008)
|
266
|
+
# AmountWithoutVat ~= Amount / (100 + VatPercent) * 100
|
267
|
+
# VatAmount ~= Amount / (100 + VatPercent) * VatPercent(IF0011) Decimal places: max. = 2
|
268
|
+
attribute :amount_without_vat, Types::Strict::Float
|
269
|
+
# Product description. Field can't be blank.
|
270
|
+
attribute :product_text, Types::Strict::String
|
271
|
+
|
272
|
+
# Unique identifier of the product (e.g. Article number).
|
273
|
+
attribute :product_id, Types::Strict::String.optional.default(nil)
|
274
|
+
# Product category.
|
275
|
+
attribute :product_category, Types::Strict::String.optional.default(nil)
|
276
|
+
# Percentage value of the rebate given for this line item.
|
277
|
+
# This percentage is already reflected in amount.
|
278
|
+
# If given, and also singleArticleAmountWithoutVat is given, the following formula
|
279
|
+
# has to apply: AmountWithoutVat = SingleArticleAmountWithoutVat * Quantity * (100% - RebatePercentage) (IF0008)
|
280
|
+
# If given, and also singleArticleAmount is given, the following formula has to apply:
|
281
|
+
# Amount = SingleArticleAmount * Quantity * (100% - RebatePercentage) (IF0026) Range: min. = 0, max. = 100
|
282
|
+
attribute :rebate_percentage, Types::Strict::Float.optional.default(nil)
|
283
|
+
# Amount of a single product including VAT. Decimal places: max. = 6
|
284
|
+
attribute :single_article_amount, Types::Strict::Float.optional.default(nil)
|
285
|
+
# Amount of a single product without VAT. Decimal places: max. = 6
|
286
|
+
attribute :single_article_amount_without_vat, Types::Strict::Float.optional.default(nil)
|
287
|
+
# Identifies the type of the detail record line. Allows to distinguish between goods, fees, other payment means etc.
|
288
|
+
attribute :type, Types::Strict::String.optional.default(nil)
|
289
|
+
# Quantity related unit of the product (Pieces, Meters, Liters etc.).
|
290
|
+
attribute :quantity_unit, Types::Strict::String.optional.default(nil)
|
291
|
+
|
292
|
+
def self.from_message(h)
|
293
|
+
DetailRecord.new({
|
294
|
+
quantity: h[:quantity],
|
295
|
+
amount: h[:amount],
|
296
|
+
vat_percent: h[:vatPercent],
|
297
|
+
vat_amount: h[:vatAmount],
|
298
|
+
amount_without_vat: h[:amountWithoutVat],
|
299
|
+
product_text: h[:productText],
|
300
|
+
product_id: h[:productId],
|
301
|
+
product_category: h[:productCategory],
|
302
|
+
rebate_percentage: h[:rebatePercentage],
|
303
|
+
single_article_amount: h[:singleArticleAmount],
|
304
|
+
single_article_amount_without_vat: h[:singleArticleAmountWithoutVat],
|
305
|
+
type: h[:type],
|
306
|
+
quantity_unit: h[:quantityUnit],
|
307
|
+
})
|
308
|
+
end
|
309
|
+
|
310
|
+
def to_message
|
311
|
+
m = {
|
312
|
+
quantity: quantity,
|
313
|
+
amount: amount,
|
314
|
+
vatPercent: vat_percent,
|
315
|
+
vatAmount: vat_amount,
|
316
|
+
amountWithoutVat: amount_without_vat,
|
317
|
+
productText: product_text
|
318
|
+
}
|
319
|
+
m[:productId] = product_id unless product_id.nil?
|
320
|
+
m[:productCategory] = product_category unless product_category.nil?
|
321
|
+
m[:rebatePercentage] = rebate_percentage unless rebate_percentage.nil?
|
322
|
+
m[:singleArticleAmount] = single_article_amount unless single_article_amount.nil?
|
323
|
+
m[:singleArticleAmountWithoutVat] = single_article_amount_without_vat unless single_article_amount_without_vat.nil?
|
324
|
+
m[:type] = type unless type.nil?
|
325
|
+
m[:quantityUnit] = quantity_unit unless quantity_unit.nil?
|
326
|
+
m
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
# The Basket class contains all financial amounts and information about its products.
|
331
|
+
class Basket < Dry::Struct
|
332
|
+
# Goods total value minus other payment amounts.
|
333
|
+
# This amount is billed towards the end customer.
|
334
|
+
# If the basket has detailRecords, the sum of their amount fields has to be
|
335
|
+
# equal to the basket's amount + otherPaymentMeansAmount, and thus also equal
|
336
|
+
# to the basket's grossAmount. (IF0006) Decimal places: max. = 2
|
337
|
+
attribute :amount, Types::Strict::Float
|
338
|
+
# Currency of all amounts in the basket.
|
339
|
+
attribute :currency, Types::Strict::String.default('CHF'.freeze)
|
340
|
+
# Collection of the basket's records with detail information.
|
341
|
+
# At least one DetailRecord is mandatory for the following transaction request types (IF0024):
|
342
|
+
# * SubmissionRequest
|
343
|
+
# * CreditRequest
|
344
|
+
attribute :detail_records, Types::Strict::Array.of(DetailRecord)
|
345
|
+
|
346
|
+
# Total value of the purchase including otherPaymentMeansAmount.
|
347
|
+
# Field is optional, if otherPaymentMeansAmount is zero or left out.
|
348
|
+
# Consequently, if otherPaymentMeansAmount is set to any non-zero value,
|
349
|
+
# grossAmount is mandatory. grossAmount = amount + otherPaymentMeansAmount(IF0007) Decimal places: max. = 2
|
350
|
+
attribute :gross_amount, Types::Strict::Float.optional.default(nil)
|
351
|
+
# Already payed amount e.g. via gift card. If not set, assumed to be 0.
|
352
|
+
# If set to any other value than zero, then also grossAmount must be set correctly. Decimal places: max. = 2
|
353
|
+
attribute :other_payment_means_amount, Types::Strict::Float.optional.default(nil)
|
354
|
+
# Order number defined by the end customer.
|
355
|
+
# Can be useful e.g. for B2B customers in order to provide a reference number to
|
356
|
+
# theorder in the customer's finance department, for easier correlation.
|
357
|
+
# Length limited to 64 chars, rest will be truncated.
|
358
|
+
attribute :customer_order_number, Types::Strict::String.optional.default(nil)
|
359
|
+
# Order number. ID of the order on merchant side. Will be printed on the invoice t othe customer,
|
360
|
+
# and reported on the merchant statement. Length limited to 30 chars, rest will be truncated.
|
361
|
+
attribute :order_number, Types::Strict::String.optional.default(nil)
|
362
|
+
|
363
|
+
def self.from_message(h)
|
364
|
+
Basket.new({
|
365
|
+
amount: h[:amount],
|
366
|
+
currency: h[:amountCurrency],
|
367
|
+
detail_records: h[:detailRecords].map { |r| DetailRecord.from_message(r) },
|
368
|
+
gross_amount: h[:grossAmount],
|
369
|
+
other_payment_means_amount: h[:otherPaymentMeansAmount],
|
370
|
+
customer_order_number: h[:customerOrderNumber],
|
371
|
+
order_number: h[:orderNumber],
|
372
|
+
})
|
373
|
+
end
|
374
|
+
|
375
|
+
def to_message
|
376
|
+
m = {
|
377
|
+
amount: amount,
|
378
|
+
amountCurrency: currency,
|
379
|
+
detailRecords: detail_records.map(&:to_message)
|
380
|
+
}
|
381
|
+
m[:grossAmount] = gross_amount unless gross_amount.nil?
|
382
|
+
m[:otherPaymentMeansAmount] = other_payment_means_amount unless other_payment_means_amount.nil?
|
383
|
+
m[:customerOrderNumber] = customer_order_number unless customer_order_number.nil?
|
384
|
+
m[:orderNumber] = order_number unless order_number.nil?
|
385
|
+
m
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
class AdditionalData < Dry::Struct
|
390
|
+
# Describes requested method of payment. Field can't be null.
|
391
|
+
attribute :requested_payment_method, Types::Strict::String
|
392
|
+
|
393
|
+
# Describes the distribution channel of a purchase.
|
394
|
+
attribute :sales_channel, Types::Strict::String.optional.default(nil)
|
395
|
+
# Date of invoice (Submission date + X days).
|
396
|
+
attribute :invoice_date, Types::Strict::Integer.optional.default(nil)
|
397
|
+
# Free text field 1.
|
398
|
+
attribute :free_text1, Types::Strict::String.optional.default(nil)
|
399
|
+
# Free text field 2.
|
400
|
+
attribute :free_text2, Types::Strict::String.optional.default(nil)
|
401
|
+
# The preferred rate model, e.g. "3x3" or "4x12".
|
402
|
+
attribute :preferred_rate_model, Types::Strict::String.optional.default(nil)
|
403
|
+
# Allows to influence the behaviour of an authorization concerning risk taker shift.
|
404
|
+
attribute :risk_taker_shift, Types::Strict::String.optional.default(nil)
|
405
|
+
# Determines the delivery channel for the invoice. Replaces physicalInvoice flag.
|
406
|
+
# If invoiceChannel is set, physicalInvoice flag will be ignored, i.e. invoiceChannel takes precedence.
|
407
|
+
attribute :invoice_channel, Types::Strict::String.optional.default(nil)
|
408
|
+
|
409
|
+
def self.from_message(h)
|
410
|
+
AdditionalData.new({
|
411
|
+
requested_payment_method: h[:requestedPaymentMethod],
|
412
|
+
sales_channel: h[:salesChannel],
|
413
|
+
invoice_date: h[:invoiceDate],
|
414
|
+
free_text1: h[:freeText1],
|
415
|
+
free_text2: h[:freeText2],
|
416
|
+
preferred_rate_model: h[:preferredRateModel],
|
417
|
+
risk_taker_shift: h[:riskTakerShift],
|
418
|
+
invoice_channel: h[:invoiceChannel],
|
419
|
+
})
|
420
|
+
end
|
421
|
+
|
422
|
+
def to_message
|
423
|
+
m = {
|
424
|
+
requestedPaymentMethod: requested_payment_method,
|
425
|
+
}
|
426
|
+
m[:salesChannel] = sales_channel unless sales_channel.nil?
|
427
|
+
m[:invoiceDate] = invoice_date unless invoice_date.nil?
|
428
|
+
m[:freeText1] = free_text1 unless free_text1.nil?
|
429
|
+
m[:freeText2] = free_text2 unless free_text2.nil?
|
430
|
+
m[:preferredRateModel] = preferred_rate_model unless preferred_rate_model.nil?
|
431
|
+
m[:riskTakerShift] = risk_taker_shift unless risk_taker_shift.nil?
|
432
|
+
m[:invoiceChannel] = invoice_channel unless invoice_channel.nil?
|
433
|
+
m
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
437
|
+
# Contains token information for authorizations with payment method ONACCOUNT.
|
438
|
+
class Token < Dry::Struct
|
439
|
+
# ID of the token. Field can't be blank.
|
440
|
+
attribute :id, Types::Strict::String
|
441
|
+
# Secret of the token. Also know as CVV. Field can't be blank.
|
442
|
+
attribute :secret, Types::Strict::String
|
443
|
+
|
444
|
+
# Expiration date of the token, in format 'YYYYMM'.
|
445
|
+
attribute :expiry_date, Types::Strict::String.optional.default(nil)
|
446
|
+
|
447
|
+
def self.from_message(h)
|
448
|
+
Token.new({
|
449
|
+
id: h[:tokenId],
|
450
|
+
secret: h[:tokenSecret],
|
451
|
+
expiry_date: h[:tokenExpiryDate],
|
452
|
+
})
|
453
|
+
end
|
454
|
+
|
455
|
+
def to_message
|
456
|
+
m = {
|
457
|
+
tokenId: id,
|
458
|
+
tokenSecret: secret,
|
459
|
+
}
|
460
|
+
m[:tokenExpiryDate] = expiry_date unless expiry_date.nil?
|
461
|
+
m
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
class Attachment < Dry::Struct
|
466
|
+
# Name of the attachment.
|
467
|
+
attribute :name, Types::Strict::String
|
468
|
+
# The mime type of the attachment.
|
469
|
+
attribute :mime_type, Types::Strict::String
|
470
|
+
# The content of the attachment (base64 encoded).
|
471
|
+
attribute :value, Types::Strict::String
|
472
|
+
|
473
|
+
def from_file
|
474
|
+
end
|
475
|
+
|
476
|
+
def self.from_message(h)
|
477
|
+
Attachment.new({
|
478
|
+
name: h[:name],
|
479
|
+
mime_type: h[:mimeType],
|
480
|
+
value: h[:value],
|
481
|
+
})
|
482
|
+
end
|
483
|
+
|
484
|
+
def to_message
|
485
|
+
{
|
486
|
+
name: name,
|
487
|
+
mimeType: mime_type,
|
488
|
+
value: value
|
489
|
+
}
|
490
|
+
end
|
491
|
+
end
|
492
|
+
|
493
|
+
class ResponseIdentifier < Dry::Struct
|
494
|
+
# Unique transaction id provided by the KaR system.
|
495
|
+
# With this id a specific request-response pair can be identified.
|
496
|
+
# This id is a valuable information for the KaR support team in case of a technical problem.
|
497
|
+
# Field can't be blank.
|
498
|
+
attribute :guardean_order_id, Types::Coercible::String
|
499
|
+
# Authorization id. Max. length of value is 30
|
500
|
+
attribute :authorization_id, Types::Coercible::Integer.optional.default(nil)
|
501
|
+
|
502
|
+
def self.from_message(h)
|
503
|
+
ResponseIdentifier.new({
|
504
|
+
guardean_order_id: h[:guardeanOrderId],
|
505
|
+
authorization_id: h[:authorizationId],
|
506
|
+
})
|
507
|
+
end
|
508
|
+
end
|
509
|
+
|
510
|
+
class Rate < Dry::Struct
|
511
|
+
# Amount of an installment.
|
512
|
+
attribute :amount, Types::Coercible::String
|
513
|
+
# Due date of the rate.
|
514
|
+
attribute :date, Types::Coercible::String
|
515
|
+
# Amount of interest.
|
516
|
+
attribute :interest_amount, Types::Coercible::String
|
517
|
+
|
518
|
+
def self.from_message(h)
|
519
|
+
Rate.new({
|
520
|
+
amount: h[:rateAmount],
|
521
|
+
date: h[:rateDate],
|
522
|
+
interest_amount: h[:interestAmount],
|
523
|
+
})
|
524
|
+
end
|
525
|
+
end
|
526
|
+
|
527
|
+
class InstallmentPlan < Dry::Struct
|
528
|
+
# Total amount of the installments including fees.
|
529
|
+
attribute :total_rate_amount, Types::Coercible::String
|
530
|
+
# Interest per annum.
|
531
|
+
attribute :interest_rate, Types::Coercible::String
|
532
|
+
# Date of the invoice.
|
533
|
+
attribute :billing_date, Types::Coercible::String
|
534
|
+
# Rate plan model, e.g. "3x3" or "4x12".
|
535
|
+
attribute :rate_model, Types::Coercible::String.optional.default(nil)
|
536
|
+
# Collection of the rates for the installments.
|
537
|
+
attribute :rates, Types::Coercible::Array.of(Rate).optional.default([].freeze)
|
538
|
+
|
539
|
+
def self.from_message(h)
|
540
|
+
InstallmentPlan.new({
|
541
|
+
total_rate_amount: h[:totalRateAmount],
|
542
|
+
interest_rate: h[:interestRate],
|
543
|
+
billing_date: h[:billingDate],
|
544
|
+
rate_model: h[:rateModel],
|
545
|
+
rates: h[:rates] ? h[:rates].map { |r| Rate.from_message(r) } : [],
|
546
|
+
})
|
547
|
+
end
|
548
|
+
end
|
549
|
+
|
550
|
+
class Info < Dry::Struct
|
551
|
+
# Current status of the transaction.
|
552
|
+
attribute :status, Types::Coercible::String.optional.default(nil)
|
553
|
+
# Current status of the transaction.
|
554
|
+
attribute :requested, Types::Coercible::String.optional.default(nil)
|
555
|
+
# Current status of the transaction.
|
556
|
+
attribute :valid_until, Types::Coercible::String.optional.default(nil)
|
557
|
+
# Current status of the transaction.
|
558
|
+
attribute :is_suitable_for_delivery, Types::Coercible::String.optional.default(nil)
|
559
|
+
# Current status of the transaction.
|
560
|
+
attribute :invoice_status, Types::Coercible::String.optional.default(nil)
|
561
|
+
# Current status of the transaction.
|
562
|
+
attribute :payment_status, Types::Coercible::String.optional.default(nil)
|
563
|
+
# Current status of the transaction.
|
564
|
+
attribute :dunning_level, Types::Coercible::String.optional.default(nil)
|
565
|
+
# Current status of the transaction.
|
566
|
+
attribute :current_balance, Types::Coercible::String.optional.default(nil)
|
567
|
+
# Current status of the transaction.
|
568
|
+
attribute :attachments, Types::Coercible::Array.of(Attachment).optional.default([].freeze)
|
569
|
+
|
570
|
+
# TODO: Enum?
|
571
|
+
|
572
|
+
def self.from_message(h)
|
573
|
+
Info.new({
|
574
|
+
status: h[:status],
|
575
|
+
requested: h[:requested],
|
576
|
+
valid_until: h[:validUntil],
|
577
|
+
is_suitable_for_delivery: h[:isSuitableForDelivery],
|
578
|
+
invoice_status: h[:invoiceStatus],
|
579
|
+
payment_status: h[:paymentStatus],
|
580
|
+
dunning_level: h[:dunningLevel],
|
581
|
+
current_balance: h[:currentBalance],
|
582
|
+
attachments: h[:attachments],
|
583
|
+
})
|
584
|
+
end
|
585
|
+
end
|
586
|
+
|
587
|
+
class Decision < Dry::Struct
|
588
|
+
# Indicates if the customer is allowed to pay its purchase by invoice.
|
589
|
+
attribute :invoice, Types::Coercible::String.optional.default(nil)
|
590
|
+
# Indicates if the customer is allowed to pay its purchase in installments.
|
591
|
+
attribute :installment, Types::Coercible::String.optional.default(nil)
|
592
|
+
# Indicates if the customer is allowed to pay its purchase by revolving account.
|
593
|
+
attribute :on_account, Types::Coercible::String.optional.default(nil)
|
594
|
+
# Indicates, who will take the financial risk of this transaction (see RiskTaker)
|
595
|
+
attribute :risk_taker, Types::Coercible::String.optional.default(nil)
|
596
|
+
# Only present in response of check operation. Indicates the result of the check.
|
597
|
+
attribute :traffic_light, Types::Coercible::String.optional.default(nil)
|
598
|
+
|
599
|
+
# TODO: Enum?
|
600
|
+
|
601
|
+
def self.from_message(h)
|
602
|
+
Decision.new({
|
603
|
+
invoice: h[:decisionInvoice],
|
604
|
+
installment: h[:decisionInstallment],
|
605
|
+
on_account: h[:decisionOnAccount],
|
606
|
+
risk_taker: h[:riskTaker],
|
607
|
+
traffic_light: h[:trafficLight],
|
608
|
+
})
|
609
|
+
end
|
610
|
+
end
|
611
|
+
|
612
|
+
# The AuthorizationRequest class represents the request parameter of the PreAuthorize and the Authorize service call.
|
613
|
+
# It contains all information needed to make a preauthorization/authorization.
|
614
|
+
class AuthorizationRequest < Dry::Struct
|
615
|
+
# Environment parameters and information to identify the caller.
|
616
|
+
attribute :identifier, Zaala::API::RequestIdentifier
|
617
|
+
# Personal data of the customer.
|
618
|
+
attribute :personal_data, Zaala::API::PersonalData
|
619
|
+
# Invoice address of the purchase.
|
620
|
+
attribute :invoice_address, Zaala::API::InvoiceAddress
|
621
|
+
# Additional purchase related information.
|
622
|
+
attribute :additional_data, Zaala::API::AdditionalData
|
623
|
+
|
624
|
+
# Key-value pairs holding information of the service's client (e.g. IPv4 address).
|
625
|
+
# attribute :client_info, Zaala::API::ClientInfo
|
626
|
+
# Requested amount of the preauthorization/authorization.
|
627
|
+
# It corresponds to the total amount, which has to be authorized.
|
628
|
+
# Mandatory if no Basket is provided in the request.
|
629
|
+
# (IF0001) If a Basket is provided in the request, this value is ignored.
|
630
|
+
attribute :requested_amount, Types::Strict::Float.optional.default(nil)
|
631
|
+
# Delivery address of the purchase.
|
632
|
+
attribute :delivery_address, Zaala::API::DeliveryAddress.optional.default(nil)
|
633
|
+
# Basket of the purchase. Mandatory if the requestdAmount is not provided in the request. (IF0001)
|
634
|
+
attribute :basket, Zaala::API::Basket.optional.default(nil)
|
635
|
+
# Token for authorizations with payment method ONACCOUNT.
|
636
|
+
# Mandatory if the the requested PaymentMethod equals ONACCOUNT. (IF0033)
|
637
|
+
attribute :token, Zaala::API::Token.optional.default(nil)
|
638
|
+
# Allows to provide additional information for the KaR process.
|
639
|
+
attribute :attachments, Types::Strict::Array.of(Zaala::API::Attachment).optional.default([].freeze)
|
640
|
+
|
641
|
+
def to_message
|
642
|
+
m = {
|
643
|
+
identifier: identifier.to_message,
|
644
|
+
personalData: personal_data.to_message,
|
645
|
+
invoiceAddress: invoice_address.to_message,
|
646
|
+
additionalData: additional_data.to_message,
|
647
|
+
}
|
648
|
+
m[:requestedAmount] = requested_amount unless requested_amount.nil?
|
649
|
+
m[:deliveryAddress] = delivery_address unless delivery_address.nil?
|
650
|
+
m[:basket] = basket unless basket.nil?
|
651
|
+
m[:token] = token unless token.nil?
|
652
|
+
m[:attachments] = attachments.map(&:to_message) unless attachments.nil?
|
653
|
+
m
|
654
|
+
end
|
655
|
+
end
|
656
|
+
|
657
|
+
class AuthorizationResponse < Dry::Struct
|
658
|
+
# Contains information to identify the authorization in a future request.
|
659
|
+
attribute :identifier, Zaala::API::ResponseIdentifier
|
660
|
+
# Contains additional information concerning the authorization.
|
661
|
+
attribute :decision, Zaala::API::Decision
|
662
|
+
|
663
|
+
# Contains the details of the payment by installments.
|
664
|
+
attribute :installment_plan, Zaala::API::InstallmentPlan.optional.default(nil)
|
665
|
+
# Contains additional information concerning the authorization.
|
666
|
+
attribute :info, Zaala::API::Info.optional.default(nil)
|
667
|
+
|
668
|
+
def self.from_message(h)
|
669
|
+
AuthorizationResponse.new({
|
670
|
+
identifier: Zaala::API::ResponseIdentifier.from_message(h[:identifier]),
|
671
|
+
decision: Zaala::API::Decision.from_message(h[:decision]),
|
672
|
+
installment_plan: h[:installmentPlan] ? Zaala::API::InstallmentPlan.from_message(h[:installmentPlan]) : nil,
|
673
|
+
info: h[:info] ? Zaala::API::Info.from_message(h[:info]) : nil,
|
674
|
+
})
|
675
|
+
end
|
676
|
+
end
|
677
|
+
|
678
|
+
# The SubmissionRequest class represents the request parameter of the SubmitAuthorization service call.
|
679
|
+
# It contains all information needed to submit a previous authorization and triggering the issuing of the invoice.
|
680
|
+
class SubmissionRequest < Dry::Struct
|
681
|
+
# Key-value pairs holding information of the service's client (e.g. IPv4 address).
|
682
|
+
# attribute :client_info, []ClientInfo
|
683
|
+
|
684
|
+
# Environment parameters and information to identify the caller.
|
685
|
+
attribute :identifier, Zaala::API::RequestIdentifier
|
686
|
+
# Basket of the purchase. Mandatory if the requestdAmount is not provided in the request. (IF0001)
|
687
|
+
attribute :basket, Zaala::API::Basket
|
688
|
+
# Additional purchase related information.
|
689
|
+
attribute :additional_data, Zaala::API::AdditionalData
|
690
|
+
# Allows to provide additional information for the KaR process.
|
691
|
+
attribute :attachments, Types::Strict::Array.of(Zaala::API::Attachment).optional.default([].freeze)
|
692
|
+
|
693
|
+
def to_message
|
694
|
+
{
|
695
|
+
identifier: identifier.to_message,
|
696
|
+
basket: basket.to_message,
|
697
|
+
additionalData: additional_data.to_message,
|
698
|
+
attachments: attachments.map(&:to_message),
|
699
|
+
}
|
700
|
+
end
|
701
|
+
end
|
702
|
+
|
703
|
+
class SubmissionResponse < Dry::Struct
|
704
|
+
# Contains information to identify the authorization in a future request.
|
705
|
+
attribute :identifier, Zaala::API::ResponseIdentifier
|
706
|
+
# Contains additional information concerning the authorization.
|
707
|
+
attribute :decision, Zaala::API::Decision
|
708
|
+
|
709
|
+
# Contains the details of the payment by installments.
|
710
|
+
attribute :installment_plan, Zaala::API::InstallmentPlan.optional.default(nil)
|
711
|
+
# Contains additional information concerning the authorization.
|
712
|
+
attribute :info, Zaala::API::Info.optional.default(nil)
|
713
|
+
|
714
|
+
def self.from_message(h)
|
715
|
+
SubmissionResponse.new({
|
716
|
+
identifier: Zaala::API::ResponseIdentifier.from_message(h[:identifier]),
|
717
|
+
decision: Zaala::API::Decision.from_message(h[:decision]),
|
718
|
+
installment_plan: h[:installmentPlan] ? Zaala::API::InstallmentPlan.from_message(h[:installmentPlan]) : nil,
|
719
|
+
info: h[:info] ? Zaala::API::Info.from_message(h[:info]) : nil,
|
720
|
+
})
|
721
|
+
end
|
722
|
+
end
|
723
|
+
|
724
|
+
# The CancellationRequest class represents the request parameter of the CancelAuthorization service call.
|
725
|
+
# It contains all information needed to cancel an previous authorization.
|
726
|
+
class CancellationRequest < Dry::Struct
|
727
|
+
# Key-value pairs holding information of the service's client (e.g. IPv4 address).
|
728
|
+
# attribute :client_info, []ClientInfo
|
729
|
+
# Environment parameters and information to identify the caller.
|
730
|
+
attribute :identifier, Zaala::API::RequestIdentifier
|
731
|
+
|
732
|
+
def to_message
|
733
|
+
{
|
734
|
+
identifier: identifier.to_message,
|
735
|
+
}
|
736
|
+
end
|
737
|
+
end
|
738
|
+
|
739
|
+
class CancellationResponse < Dry::Struct
|
740
|
+
# Contains information to identify the authorization in a future request.
|
741
|
+
attribute :identifier, Zaala::API::ResponseIdentifier
|
742
|
+
|
743
|
+
# Contains additional information concerning the authorization.
|
744
|
+
attribute :info, Zaala::API::Info.optional.default(nil)
|
745
|
+
|
746
|
+
def self.from_message(h)
|
747
|
+
CancellationResponse.new({
|
748
|
+
identifier: Zaala::API::ResponseIdentifier.from_message(h[:identifier]),
|
749
|
+
info: h[:info] ? Zaala::API::Info.from_message(h[:info]) : nil,
|
750
|
+
})
|
751
|
+
end
|
752
|
+
end
|
753
|
+
|
754
|
+
# The InfoRequest class represents the request parameter of the Info service call.
|
755
|
+
# It contains all information needed to retrieve all available information about an authorization-id.
|
756
|
+
class InfoRequest < Dry::Struct
|
757
|
+
# Key-value pairs holding information of the service's client (e.g. IPv4 address).
|
758
|
+
# attribute :client_info, []ClientInfo
|
759
|
+
# Environment parameters and information to identify the caller.
|
760
|
+
attribute :identifier, Zaala::API::RequestIdentifier
|
761
|
+
|
762
|
+
def to_message
|
763
|
+
{
|
764
|
+
identifier: identifier.to_message,
|
765
|
+
}
|
766
|
+
end
|
767
|
+
end
|
768
|
+
|
769
|
+
# The class InfoResponse represents the response of the Info service call.
|
770
|
+
class InfoResponse < Dry::Struct
|
771
|
+
# Contains information to identify the authorization in a future request.
|
772
|
+
attribute :identifier, Zaala::API::ResponseIdentifier
|
773
|
+
# Contains additional information concerning the authorization.
|
774
|
+
attribute :decision, Zaala::API::Decision
|
775
|
+
|
776
|
+
# Contains additional information concerning the authorization.
|
777
|
+
attribute :info, Zaala::API::Info.optional.default(nil)
|
778
|
+
# Contains the details of the payment by installments.
|
779
|
+
attribute :installment_plan, Zaala::API::InstallmentPlan.optional.default(nil)
|
780
|
+
|
781
|
+
def self.from_message(h)
|
782
|
+
InfoResponse.new({
|
783
|
+
identifier: Zaala::API::ResponseIdentifier.from_message(h[:identifier]),
|
784
|
+
decision: Zaala::API::Decision.from_message(h[:decision]),
|
785
|
+
installment_plan: h[:installmentPlan] ? Zaala::API::InstallmentPlan.from_message(h[:installmentPlan]) : nil,
|
786
|
+
info: h[:info] ? Zaala::API::Info.from_message(h[:info]) : nil,
|
787
|
+
})
|
788
|
+
end
|
789
|
+
end
|
790
|
+
|
791
|
+
# The VerifyRequest class represents the request parameter of the Verify service call.
|
792
|
+
# It contains all information needed to verify an authorization with an MTAN.
|
793
|
+
class VerifyRequest < Dry::Struct
|
794
|
+
# Key-value pairs holding information of the service's client (e.g. IPv4 address).
|
795
|
+
# attribute :client_info, []ClientInfo
|
796
|
+
# Environment parameters and information to identify the caller.
|
797
|
+
attribute :identifier, Zaala::API::RequestIdentifier
|
798
|
+
# Additional purchase related information.
|
799
|
+
attribute :additional_data, Zaala::API::AdditionalData
|
800
|
+
# The verificationCode value to check against.
|
801
|
+
attribute :verification_code, Types::Strict::String
|
802
|
+
|
803
|
+
def to_message
|
804
|
+
{
|
805
|
+
identifier: identifier.to_message,
|
806
|
+
additionalData: additional_data.to_message,
|
807
|
+
verificationCode: verification_code,
|
808
|
+
}
|
809
|
+
end
|
810
|
+
end
|
811
|
+
|
812
|
+
# The class VerifyResponse represents the response of the Verify service call.
|
813
|
+
class VerifyResponse < Dry::Struct
|
814
|
+
# Contains information to identify the authorization in a future request.
|
815
|
+
attribute :identifier, Zaala::API::ResponseIdentifier
|
816
|
+
# Contains additional information concerning the authorization.
|
817
|
+
attribute :decision, Zaala::API::Decision
|
818
|
+
|
819
|
+
# Contains additional information concerning the authorization.
|
820
|
+
attribute :info, Zaala::API::Info.optional.default(nil)
|
821
|
+
# Contains the details of the payment by installments.
|
822
|
+
attribute :installment_plan, Zaala::API::InstallmentPlan.optional.default(nil)
|
823
|
+
|
824
|
+
def self.from_message(h)
|
825
|
+
VerifyResponse.new({
|
826
|
+
identifier: Zaala::API::ResponseIdentifier.from_message(h[:identifier]),
|
827
|
+
decision: Zaala::API::Decision.from_message(h[:decision]),
|
828
|
+
installment_plan: h[:installmentPlan] ? Zaala::API::InstallmentPlan.from_message(h[:installmentPlan]) : nil,
|
829
|
+
info: h[:info] ? Zaala::API::Info.from_message(h[:info]) : nil,
|
830
|
+
})
|
831
|
+
end
|
832
|
+
end
|
833
|
+
end
|
data/lib/zaala/api.rb
ADDED
data/lib/zaala.rb
ADDED
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: zaala
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Denteo AG
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-10-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: dry-types
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.5.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.5.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: dry-struct
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.4.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.4.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: savon
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 2.12.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 2.12.0
|
55
|
+
description: Ruby client interacting with Zaala
|
56
|
+
email: simon@denteo.ch
|
57
|
+
executables: []
|
58
|
+
extensions: []
|
59
|
+
extra_rdoc_files: []
|
60
|
+
files:
|
61
|
+
- lib/zaala.rb
|
62
|
+
- lib/zaala/api.rb
|
63
|
+
- lib/zaala/api/client.rb
|
64
|
+
- lib/zaala/api/error.rb
|
65
|
+
- lib/zaala/api/types.rb
|
66
|
+
homepage: https://rubygems.org/gems/zaala
|
67
|
+
licenses:
|
68
|
+
- MIT
|
69
|
+
metadata: {}
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options: []
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
requirements: []
|
85
|
+
rubygems_version: 3.1.2
|
86
|
+
signing_key:
|
87
|
+
specification_version: 4
|
88
|
+
summary: Ruby client interacting with Zaala
|
89
|
+
test_files: []
|