docdata-order 1.0.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/.gitignore +15 -0
- data/.rspec +2 -0
- data/.rubocop.yml +38 -0
- data/.travis.yml +7 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +21 -0
- data/README.md +134 -0
- data/Rakefile +10 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/docdata-order.gemspec +32 -0
- data/lib/docdata/order.rb +11 -0
- data/lib/docdata/order/client.rb +71 -0
- data/lib/docdata/order/exception.rb +8 -0
- data/lib/docdata/order/gender.rb +11 -0
- data/lib/docdata/order/ideal.rb +20 -0
- data/lib/docdata/order/payment_method.rb +14 -0
- data/lib/docdata/order/request.rb +282 -0
- data/lib/docdata/order/response.rb +328 -0
- data/lib/docdata/order/urls.rb +15 -0
- data/lib/docdata/order/version.rb +7 -0
- metadata +148 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 1504b4d5df07a35ae4e4b403776da567d2bab632
|
|
4
|
+
data.tar.gz: '079dfe209ce3bc7a99f1040721a5290f2ac29c9b'
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 9d0d115f0d0427605c95c3d1d128e0f8f1e8f2667789b95366fd9a97ea887fbed2a1e6cbcc733b91b7226e7ec4e20a70a6ad186344b19e16f945e0c912d1810a
|
|
7
|
+
data.tar.gz: 69f6a2e859992879043497eb3d27f76e3e373e1bc965aab1e4ebfd87159d5912b97a1ecce6c388b21ccc5dfe738f4add1d39f2c9ca5ab4f3f5a35c2eeff86f63
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Docdata-order RuboCop configuration
|
|
2
|
+
|
|
3
|
+
AllCops:
|
|
4
|
+
TargetRubyVersion: 2.3
|
|
5
|
+
DisplayCopNames: true
|
|
6
|
+
DisplayStyleGuide: true
|
|
7
|
+
|
|
8
|
+
Metrics/AbcSize:
|
|
9
|
+
Max: 53
|
|
10
|
+
|
|
11
|
+
Metrics/BlockLength:
|
|
12
|
+
Exclude:
|
|
13
|
+
- 'spec/**/*.rb'
|
|
14
|
+
|
|
15
|
+
Metrics/ClassLength:
|
|
16
|
+
Enabled: false
|
|
17
|
+
|
|
18
|
+
Metrics/LineLength:
|
|
19
|
+
Enabled: false
|
|
20
|
+
|
|
21
|
+
Metrics/MethodLength:
|
|
22
|
+
Enabled: false
|
|
23
|
+
|
|
24
|
+
Style/BlockDelimiters:
|
|
25
|
+
Exclude:
|
|
26
|
+
- 'spec/**/*.rb'
|
|
27
|
+
|
|
28
|
+
Style/GuardClause:
|
|
29
|
+
Enabled: false
|
|
30
|
+
|
|
31
|
+
Style/SafeNavigation:
|
|
32
|
+
Enabled: false
|
|
33
|
+
|
|
34
|
+
Style/StringLiterals:
|
|
35
|
+
Enabled: false
|
|
36
|
+
|
|
37
|
+
Style/SymbolArray:
|
|
38
|
+
Enabled: false
|
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017 Peter Postma
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Docdata::Order
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/rb/docdata-order)
|
|
4
|
+
[](https://travis-ci.org/KentaaNL/docdata-order)
|
|
5
|
+
[](https://codeclimate.com/github/KentaaNL/docdata-order)
|
|
6
|
+
|
|
7
|
+
Docdata::Order is a Ruby client for the Docdata Order API version 1.3.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
Add this line to your application's Gemfile:
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
gem 'docdata-order'
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
And then execute:
|
|
18
|
+
|
|
19
|
+
$ bundle
|
|
20
|
+
|
|
21
|
+
Or install it yourself as:
|
|
22
|
+
|
|
23
|
+
$ gem install docdata-order
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
### Initialization
|
|
28
|
+
|
|
29
|
+
Create a Docdata Order client and configure it with your merchant name and password:
|
|
30
|
+
|
|
31
|
+
```ruby
|
|
32
|
+
order = Docdata::Order::Client.new("name", "password")
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The client is configured in live mode by default. To put the client in test mode, use `test: true` as third parameter.
|
|
36
|
+
|
|
37
|
+
### Create an order
|
|
38
|
+
|
|
39
|
+
Create a new order with the `create` method. You need to provide the following parameters to create the order:
|
|
40
|
+
|
|
41
|
+
```ruby
|
|
42
|
+
options = {
|
|
43
|
+
amount: "12.50",
|
|
44
|
+
order_reference: "12345",
|
|
45
|
+
description: "Test order",
|
|
46
|
+
profile: "profile",
|
|
47
|
+
shopper: {
|
|
48
|
+
first_name: "John",
|
|
49
|
+
last_name: "Doe",
|
|
50
|
+
email: "john.doe@example.com",
|
|
51
|
+
language: "en",
|
|
52
|
+
gender: Docdata::Order::Gender::MALE
|
|
53
|
+
},
|
|
54
|
+
address: {
|
|
55
|
+
street: "Jansbuitensingel",
|
|
56
|
+
house_number: "29",
|
|
57
|
+
postal_code: "6811AD",
|
|
58
|
+
city: "Arnhem",
|
|
59
|
+
country: "NL"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
response = order.create(options)
|
|
64
|
+
|
|
65
|
+
if response.success?
|
|
66
|
+
puts response.order_key
|
|
67
|
+
puts response.redirect_url
|
|
68
|
+
else
|
|
69
|
+
puts response.error_message
|
|
70
|
+
end
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The `redirect_url` in the response will redirect the user to the Docdata Payment Menu (One Page Checkout).
|
|
74
|
+
|
|
75
|
+
To create an order and automatically redirect to the bank using iDEAL as payment method, use the parameters above including:
|
|
76
|
+
|
|
77
|
+
```ruby
|
|
78
|
+
response = order.create(options.merge(
|
|
79
|
+
payment_method: Docdata::Order::PaymentMethod::IDEAL,
|
|
80
|
+
issuer_id: Docdata::Order::Ideal::ISSUERS.first[0],
|
|
81
|
+
return_url: "http://yourwebshop.nl/payment_return"
|
|
82
|
+
))
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Start a payment order
|
|
86
|
+
|
|
87
|
+
When using Webdirect, you can use `start` to start a payment order.
|
|
88
|
+
|
|
89
|
+
```ruby
|
|
90
|
+
options = {
|
|
91
|
+
order_key: "12345",
|
|
92
|
+
payment_method: Docdata::Order::PaymentMethod::SEPA_DIRECT_DEBIT,
|
|
93
|
+
account_name: "Onderheuvel",
|
|
94
|
+
account_iban: "NL44RABO0123456789"
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
response = order.start(options)
|
|
98
|
+
|
|
99
|
+
if response.success?
|
|
100
|
+
puts response.payment_id
|
|
101
|
+
else
|
|
102
|
+
puts response.error_message
|
|
103
|
+
end
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Retrieve status of an order
|
|
107
|
+
|
|
108
|
+
To retrieve the status of an order, use `status` with the order key:
|
|
109
|
+
|
|
110
|
+
```ruby
|
|
111
|
+
response = order.status(order_key: "12345")
|
|
112
|
+
|
|
113
|
+
if response.success?
|
|
114
|
+
puts response.paid?
|
|
115
|
+
else
|
|
116
|
+
puts response.error_message
|
|
117
|
+
end
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Development
|
|
121
|
+
|
|
122
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
123
|
+
|
|
124
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
125
|
+
|
|
126
|
+
## Contributing
|
|
127
|
+
|
|
128
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/KentaaNL/docdata-order.
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
## License
|
|
132
|
+
|
|
133
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
|
134
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "bundler/setup"
|
|
5
|
+
require "docdata/order"
|
|
6
|
+
|
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
|
9
|
+
|
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
11
|
+
# require "pry"
|
|
12
|
+
# Pry.start
|
|
13
|
+
|
|
14
|
+
require "irb"
|
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
|
+
require 'docdata/order/version'
|
|
6
|
+
|
|
7
|
+
Gem::Specification.new do |spec|
|
|
8
|
+
spec.name = "docdata-order"
|
|
9
|
+
spec.version = Docdata::Order::VERSION
|
|
10
|
+
spec.authors = ["Kentaa"]
|
|
11
|
+
spec.email = ["support@kentaa.nl"]
|
|
12
|
+
|
|
13
|
+
spec.summary = "Ruby client for the Docdata Order API"
|
|
14
|
+
spec.homepage = "https://github.com/KentaaNL/docdata-order"
|
|
15
|
+
spec.license = "MIT"
|
|
16
|
+
|
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
|
19
|
+
end
|
|
20
|
+
spec.bindir = "exe"
|
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
22
|
+
spec.require_paths = ["lib"]
|
|
23
|
+
|
|
24
|
+
spec.required_ruby_version = ">= 2.0.0"
|
|
25
|
+
|
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.14"
|
|
27
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
|
28
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
|
29
|
+
spec.add_development_dependency "webmock", "~> 2.3", ">= 2.3.2"
|
|
30
|
+
|
|
31
|
+
spec.add_dependency "savon", ">= 2.0", "< 3.0"
|
|
32
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "docdata/order/client"
|
|
4
|
+
require "docdata/order/exception"
|
|
5
|
+
require "docdata/order/gender"
|
|
6
|
+
require "docdata/order/ideal"
|
|
7
|
+
require "docdata/order/payment_method"
|
|
8
|
+
require "docdata/order/request"
|
|
9
|
+
require "docdata/order/response"
|
|
10
|
+
require "docdata/order/urls"
|
|
11
|
+
require "docdata/order/version"
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "savon"
|
|
4
|
+
|
|
5
|
+
module Docdata
|
|
6
|
+
module Order
|
|
7
|
+
# Client for the Docdata Order API.
|
|
8
|
+
class Client
|
|
9
|
+
XMLNS_DDP = "http://www.docdatapayments.com/services/paymentservice/1_3/"
|
|
10
|
+
DDP_VERSION = "1.3"
|
|
11
|
+
|
|
12
|
+
def initialize(name, password, options = {})
|
|
13
|
+
@options = options.merge(merchant: { name: name, password: password })
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def create(options = {})
|
|
17
|
+
params = @options.merge(options)
|
|
18
|
+
|
|
19
|
+
response = client.call(:create, message: CreateRequest.new(params), attributes: { xmlns: XMLNS_DDP, version: DDP_VERSION })
|
|
20
|
+
|
|
21
|
+
raise Exception, response unless response.success?
|
|
22
|
+
|
|
23
|
+
CreateResponse.new(params, response)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def start(options = {})
|
|
27
|
+
params = @options.merge(options)
|
|
28
|
+
|
|
29
|
+
response = client.call(:start, message: StartRequest.new(params), attributes: { xmlns: XMLNS_DDP, version: DDP_VERSION })
|
|
30
|
+
|
|
31
|
+
raise Exception, response unless response.success?
|
|
32
|
+
|
|
33
|
+
StartResponse.new(params, response)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def status(options = {})
|
|
37
|
+
params = @options.merge(options)
|
|
38
|
+
|
|
39
|
+
response = client.call(:status_extended, message: ExtendedStatusRequest.new(params), attributes: { xmlns: XMLNS_DDP, version: DDP_VERSION })
|
|
40
|
+
|
|
41
|
+
raise Exception, response unless response.success?
|
|
42
|
+
|
|
43
|
+
ExtendedStatusResponse.new(params, response)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def client
|
|
49
|
+
@client ||= begin
|
|
50
|
+
params = { wsdl: wsdl_url, raise_errors: false, namespace_identifier: nil, namespaces: { "xmlns:ddp" => XMLNS_DDP } }
|
|
51
|
+
|
|
52
|
+
if @options[:debug]
|
|
53
|
+
params.merge!(log: true, log_level: :debug, pretty_print_xml: true)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
params[:logger] = Rails.logger if defined?(Rails)
|
|
57
|
+
|
|
58
|
+
Savon.client(params)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def wsdl_url
|
|
63
|
+
if @options[:test]
|
|
64
|
+
Urls::WSDL_TEST_URL
|
|
65
|
+
else
|
|
66
|
+
Urls::WSDL_LIVE_URL
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Docdata
|
|
4
|
+
module Order
|
|
5
|
+
module Ideal
|
|
6
|
+
ISSUERS = {
|
|
7
|
+
"ABNANL2A" => "ABN AMRO",
|
|
8
|
+
"ASNBNL21" => "ASN Bank",
|
|
9
|
+
"BUNQNL2A" => "Bunq",
|
|
10
|
+
"INGBNL2A" => "ING",
|
|
11
|
+
"KNABNL2H" => "Knab bank",
|
|
12
|
+
"RABONL2U" => "Rabobank",
|
|
13
|
+
"RBRBNL21" => "RegioBank",
|
|
14
|
+
"SNSBNL2A" => "SNS Bank",
|
|
15
|
+
"TRIONL2U" => "Triodos Bank",
|
|
16
|
+
"FVLBNL22" => "Van Lanschot"
|
|
17
|
+
}.freeze
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Docdata
|
|
4
|
+
module Order
|
|
5
|
+
module PaymentMethod
|
|
6
|
+
IDEAL = "IDEAL"
|
|
7
|
+
VISA = "VISA"
|
|
8
|
+
MASTER_CARD = "MASTERCARD"
|
|
9
|
+
AMERICAN_EXPRESS = "AMEX"
|
|
10
|
+
PAYPAL = "PAYPAL_EXPRESS_CHECKOUT"
|
|
11
|
+
SEPA_DIRECT_DEBIT = "SEPA_DIRECT_DEBIT"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "builder/xmlmarkup"
|
|
4
|
+
require "bigdecimal"
|
|
5
|
+
require "securerandom"
|
|
6
|
+
|
|
7
|
+
module Docdata
|
|
8
|
+
module Order
|
|
9
|
+
# Base class for XML requests to Docdata.
|
|
10
|
+
class Request
|
|
11
|
+
attr_reader :options
|
|
12
|
+
|
|
13
|
+
def initialize(options = {})
|
|
14
|
+
@options = options
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def to_s
|
|
18
|
+
builder = Builder::XmlMarkup.new
|
|
19
|
+
|
|
20
|
+
# Merchant credentials.
|
|
21
|
+
builder.merchant(name: merchant_name, password: merchant_password)
|
|
22
|
+
|
|
23
|
+
build_request(builder)
|
|
24
|
+
|
|
25
|
+
# This element contains information about the application contacting the webservice.
|
|
26
|
+
# This info is useful when debugging troubleshooting technical integration issues.
|
|
27
|
+
builder.integrationInfo do |integration|
|
|
28
|
+
# The name of the plugin used to contact this webservice.
|
|
29
|
+
integration.webshopPlugin("docdata-order")
|
|
30
|
+
# The version of the plugin used to contact this webservice.
|
|
31
|
+
integration.webshopPluginVersion(Docdata::Order::VERSION)
|
|
32
|
+
# The name of the plugin creator used to contact this webservice.
|
|
33
|
+
integration.integratorName("Kentaa")
|
|
34
|
+
# The programming language used to contact this webservice.
|
|
35
|
+
integration.programmingLanguage("Ruby #{RUBY_VERSION}")
|
|
36
|
+
# The operating system from which this webservice is contacted.
|
|
37
|
+
integration.operatingSystem(RUBY_PLATFORM)
|
|
38
|
+
# The full version number (including minor e.q. 1.3.0)
|
|
39
|
+
# of the xsd which is used during integration. DDP can make minor
|
|
40
|
+
# (non-breaking) changes to the xsd. These are reflected in a minor
|
|
41
|
+
# version number. It can therefore be useful to know if a different
|
|
42
|
+
# minor version of the xsd was used during merchant development than
|
|
43
|
+
# the one currently active in production.
|
|
44
|
+
integration.ddpXsdVersion(Docdata::Order::Client::DDP_VERSION)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
builder.target!
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def merchant_name
|
|
53
|
+
options.fetch(:merchant).fetch(:name)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def merchant_password
|
|
57
|
+
options.fetch(:merchant).fetch(:password)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def build_request
|
|
61
|
+
raise NotImplementedError
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Create an Order in the Docdata system.
|
|
66
|
+
class CreateRequest < Request
|
|
67
|
+
def build_request(builder)
|
|
68
|
+
# Unique merchant reference to this order.
|
|
69
|
+
builder.merchantOrderReference(order_reference)
|
|
70
|
+
|
|
71
|
+
# Preferences to use for this payment.
|
|
72
|
+
builder.paymentPreferences do |preferences|
|
|
73
|
+
# The profile that is used to select the payment methods that can be used to pay this order.
|
|
74
|
+
preferences.profile(profile)
|
|
75
|
+
preferences.numberOfDaysToPay(14)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Information concerning the shopper who placed the order.
|
|
79
|
+
builder.shopper(id: shopper_id) do |shopper|
|
|
80
|
+
# Shopper's full name.
|
|
81
|
+
shopper.name do |name|
|
|
82
|
+
# The first given name.
|
|
83
|
+
name.first(shopper_first_name)
|
|
84
|
+
# Any subsequent given name or names. May also be used as middle initial.
|
|
85
|
+
name.middle(shopper_infix) if shopper_infix
|
|
86
|
+
# The family or inherited name(s).
|
|
87
|
+
name.last(shopper_last_name)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Shopper's e-mail address.
|
|
91
|
+
shopper.email(shopper_email)
|
|
92
|
+
# Shopper's preferred language. Language code according to ISO 639.
|
|
93
|
+
shopper.language(code: shopper_language)
|
|
94
|
+
# Shopper's gender.
|
|
95
|
+
shopper.gender(shopper_gender)
|
|
96
|
+
# Ip address of the shopper. Will be used in the future for riskchecks. Can be ipv4 or ipv6.
|
|
97
|
+
shopper.ipAddress(shopper_ip_address) if shopper_ip_address
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Total order gross amount. The amount in the minor unit for the given currency.
|
|
101
|
+
# (E.g. for EUR in cents)
|
|
102
|
+
builder.totalGrossAmount(amount, currency: currency)
|
|
103
|
+
|
|
104
|
+
# Name and address to use for billing.
|
|
105
|
+
builder.billTo do |bill|
|
|
106
|
+
bill.name do |name|
|
|
107
|
+
# The first given name.
|
|
108
|
+
name.first(shopper_first_name)
|
|
109
|
+
# Any subsequent given name or names. May also be used as middle initial.
|
|
110
|
+
name.middle(shopper_infix) if shopper_infix
|
|
111
|
+
# The family or inherited name(s).
|
|
112
|
+
name.last(shopper_last_name)
|
|
113
|
+
end
|
|
114
|
+
# Address of the destination.
|
|
115
|
+
bill.address do |address|
|
|
116
|
+
# Address lines must be filled as specific as possible using the house number
|
|
117
|
+
# and optionally the house number addition field.
|
|
118
|
+
address.street(address_street)
|
|
119
|
+
# The house number.
|
|
120
|
+
address.houseNumber(address_house_number)
|
|
121
|
+
address.postalCode(address_postal_code)
|
|
122
|
+
address.city(address_city)
|
|
123
|
+
# Country code according to ISO 3166.
|
|
124
|
+
address.country(code: address_country)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# The description of the order.
|
|
129
|
+
builder.description(description)
|
|
130
|
+
|
|
131
|
+
# The description that is used by payment providers on shopper statements.
|
|
132
|
+
builder.receiptText(receipt_text)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
private
|
|
136
|
+
|
|
137
|
+
def amount
|
|
138
|
+
decimal = BigDecimal.new(options.fetch(:amount).to_s)
|
|
139
|
+
decimal *= 100 # to cents
|
|
140
|
+
decimal.to_i
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def order_reference
|
|
144
|
+
options.fetch(:order_reference)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def profile
|
|
148
|
+
options.fetch(:profile)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def shopper_id
|
|
152
|
+
options.fetch(:shopper)[:id] || SecureRandom.hex
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def shopper_first_name
|
|
156
|
+
options.fetch(:shopper).fetch(:first_name)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def shopper_infix
|
|
160
|
+
options.fetch(:shopper)[:infix]
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def shopper_last_name
|
|
164
|
+
options.fetch(:shopper).fetch(:last_name)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def shopper_email
|
|
168
|
+
options.fetch(:shopper).fetch(:email)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def shopper_language
|
|
172
|
+
options.fetch(:shopper).fetch(:language)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def shopper_gender
|
|
176
|
+
options.fetch(:shopper).fetch(:gender)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def shopper_ip_address
|
|
180
|
+
options.fetch(:shopper)[:ip_address]
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def address_street
|
|
184
|
+
options.fetch(:address).fetch(:street)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def address_house_number
|
|
188
|
+
options.fetch(:address).fetch(:house_number)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def address_postal_code
|
|
192
|
+
options.fetch(:address).fetch(:postal_code)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def address_city
|
|
196
|
+
options.fetch(:address).fetch(:city)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def address_country
|
|
200
|
+
options.fetch(:address).fetch(:country)
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def currency
|
|
204
|
+
options[:currency] || "EUR"
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def description
|
|
208
|
+
options.fetch(:description)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def receipt_text
|
|
212
|
+
options.fetch(:description)[0, 49]
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
# Start a payment order (Webdirect).
|
|
217
|
+
class StartRequest < Request
|
|
218
|
+
def build_request(builder)
|
|
219
|
+
# Payment order key belonging to the order for which a transaction needs to be started.
|
|
220
|
+
builder.paymentOrderKey(order_key)
|
|
221
|
+
|
|
222
|
+
builder.payment do |payment|
|
|
223
|
+
payment.paymentMethod(payment_method)
|
|
224
|
+
|
|
225
|
+
case payment_method
|
|
226
|
+
when PaymentMethod::IDEAL
|
|
227
|
+
payment.iDealPaymentInput do |input|
|
|
228
|
+
input.issuerId(issuer_id)
|
|
229
|
+
end
|
|
230
|
+
when PaymentMethod::SEPA_DIRECT_DEBIT
|
|
231
|
+
payment.directDebitPaymentInput do |input|
|
|
232
|
+
input.holderName(account_name)
|
|
233
|
+
input.iban(account_iban)
|
|
234
|
+
input.bic(account_bic) if account_bic
|
|
235
|
+
end
|
|
236
|
+
else
|
|
237
|
+
raise ArgumentError, "Payment method not supported: #{payment_method}"
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
private
|
|
243
|
+
|
|
244
|
+
def order_key
|
|
245
|
+
options.fetch(:order_key)
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def payment_method
|
|
249
|
+
options.fetch(:payment_method)
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def issuer_id
|
|
253
|
+
options.fetch(:issuer_id)
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
def account_name
|
|
257
|
+
options.fetch(:account_name)
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def account_iban
|
|
261
|
+
options.fetch(:account_iban)
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
def account_bic
|
|
265
|
+
options[:account_bic]
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
# Retrieve additional status information of an Order.
|
|
270
|
+
class ExtendedStatusRequest < Request
|
|
271
|
+
def build_request(builder)
|
|
272
|
+
builder.paymentOrderKey(order_key)
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
private
|
|
276
|
+
|
|
277
|
+
def order_key
|
|
278
|
+
options.fetch(:order_key)
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
end
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "uri"
|
|
4
|
+
|
|
5
|
+
module Docdata
|
|
6
|
+
module Order
|
|
7
|
+
# Base class for responses.
|
|
8
|
+
class Response
|
|
9
|
+
attr_reader :options, :response
|
|
10
|
+
|
|
11
|
+
def initialize(options, response)
|
|
12
|
+
@options = options
|
|
13
|
+
@response = response
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def body
|
|
17
|
+
response.body
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def error_message
|
|
21
|
+
errors[:error] if errors
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def error_code
|
|
25
|
+
errors[:error].attributes["code"] if errors
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Response to a create operation.
|
|
30
|
+
class CreateResponse < Response
|
|
31
|
+
def data
|
|
32
|
+
body[:create_response]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def success?
|
|
36
|
+
data.key?(:create_success)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def error?
|
|
40
|
+
data.key?(:create_errors)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def errors
|
|
44
|
+
data[:create_errors]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def order_key
|
|
48
|
+
data[:create_success][:key]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def redirect_url
|
|
52
|
+
params = {
|
|
53
|
+
command: "show_payment_cluster",
|
|
54
|
+
merchant_name: merchant_name,
|
|
55
|
+
client_language: client_language,
|
|
56
|
+
payment_cluster_key: order_key
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if payment_method
|
|
60
|
+
params[:default_pm] = payment_method
|
|
61
|
+
|
|
62
|
+
case payment_method
|
|
63
|
+
when PaymentMethod::IDEAL
|
|
64
|
+
params[:default_act] = true
|
|
65
|
+
params[:ideal_issuer_id] = issuer_id if issuer_id
|
|
66
|
+
when PaymentMethod::PAYPAL
|
|
67
|
+
params[:default_act] = true
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
if return_url
|
|
72
|
+
params.merge!(
|
|
73
|
+
return_url_success: build_return_url("success"),
|
|
74
|
+
return_url_canceled: build_return_url("cancelled"),
|
|
75
|
+
return_url_pending: build_return_url("pending"),
|
|
76
|
+
return_url_error: build_return_url("error")
|
|
77
|
+
)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
uri = URI.parse(redirect_base_url)
|
|
81
|
+
uri.query = URI.encode_www_form(params)
|
|
82
|
+
uri.to_s
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
private
|
|
86
|
+
|
|
87
|
+
def redirect_base_url
|
|
88
|
+
if options[:test]
|
|
89
|
+
Urls::MENU_TEST_URL
|
|
90
|
+
else
|
|
91
|
+
Urls::MENU_LIVE_URL
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def merchant_name
|
|
96
|
+
options.fetch(:merchant).fetch(:name)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def client_language
|
|
100
|
+
options.fetch(:shopper).fetch(:language)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def payment_method
|
|
104
|
+
options[:payment_method]
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def issuer_id
|
|
108
|
+
options[:issuer_id]
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def return_url
|
|
112
|
+
options[:return_url]
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def build_return_url(status)
|
|
116
|
+
uri = URI.parse(return_url)
|
|
117
|
+
query = URI.decode_www_form(uri.query || "") << ["status", status]
|
|
118
|
+
uri.query = URI.encode_www_form(query)
|
|
119
|
+
uri.to_s
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Response to a start operation.
|
|
124
|
+
class StartResponse < Response
|
|
125
|
+
def data
|
|
126
|
+
body[:start_response]
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def success?
|
|
130
|
+
data.key?(:start_success)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def error?
|
|
134
|
+
data.key?(:start_errors)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def errors
|
|
138
|
+
data[:start_errors]
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def payment_response
|
|
142
|
+
data[:start_success][:payment_response]
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def payment_success
|
|
146
|
+
payment_response[:payment_success] if payment_response
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def payment_id
|
|
150
|
+
payment_success[:id] if payment_success
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Response to a extended status operation.
|
|
155
|
+
class ExtendedStatusResponse < Response
|
|
156
|
+
def data
|
|
157
|
+
body[:extended_status_response]
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def success?
|
|
161
|
+
data.key?(:status_success)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def error?
|
|
165
|
+
data.key?(:status_errors)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def errors
|
|
169
|
+
data[:status_errors]
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def report
|
|
173
|
+
data[:status_success][:report]
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def payment
|
|
177
|
+
payment = report[:payment]
|
|
178
|
+
|
|
179
|
+
# When multiple payments are found, return the payment with the newest ID.
|
|
180
|
+
if payment.is_a?(Array)
|
|
181
|
+
payment.sort_by { |key, _value| key[:id] }.last
|
|
182
|
+
else
|
|
183
|
+
payment
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def payment_id
|
|
188
|
+
payment[:id] if payment
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def payment_method
|
|
192
|
+
payment[:payment_method] if payment
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def authorization
|
|
196
|
+
payment[:authorization] if payment
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# The state of the authorization. Current known values:
|
|
200
|
+
# NEW This is a new payment without any actions performed on it yet.
|
|
201
|
+
# RISK_CHECK_OK For this payment the risk check was okay.
|
|
202
|
+
# RISK_CHECK_FAILED The risk check for this payment triggered.
|
|
203
|
+
# STARTED The user has provided details and is authenticated.
|
|
204
|
+
# START_ERROR The payment system could not start the payment due to a technical error.
|
|
205
|
+
# AUTHENTICATED The shopper is authenticated by the acquirer.
|
|
206
|
+
# REDIRECTED_FOR_AUTHENTICATION The shopper is redirected to the acquirer web-site for authentication.
|
|
207
|
+
# AUTHENTICATION_FAILED The shopper is not authenticated by the acquirer.
|
|
208
|
+
# AUTHENTICATION_ERROR Unable to do the authentication of the shopper by the acquirer.
|
|
209
|
+
# AUTHORIZED This payment is authorized.
|
|
210
|
+
# REDIRECTED_FOR_AUTHORIZATION The shopper is redirected to the acquirer web-site for authorization.
|
|
211
|
+
# AUTHORIZATION_REQUESTED Requested authorization for this payment, waiting for a notification from acquirer.
|
|
212
|
+
# AUTHORIZATION_FAILED The payment was not authorized due to a functional error.
|
|
213
|
+
# AUTHORIZATION_ERROR Unable to do the payment authorization due to a technical error.
|
|
214
|
+
# CANCELED The payment is canceled.
|
|
215
|
+
# CANCEL_FAILED Payment is not canceled, due to functional error.
|
|
216
|
+
# CANCEL_ERROR Payment is not canceled, due to technical error.
|
|
217
|
+
# CANCEL_REQUESTED A cancel request sent to acquirer.
|
|
218
|
+
def authorization_status
|
|
219
|
+
authorization[:status] if authorization
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def approximate_totals
|
|
223
|
+
report[:approximate_totals]
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def total_registered
|
|
227
|
+
to_decimal(approximate_totals[:total_registered])
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def total_shopper_pending
|
|
231
|
+
to_decimal(approximate_totals[:total_shopper_pending])
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def total_acquirer_pending
|
|
235
|
+
to_decimal(approximate_totals[:total_acquirer_pending])
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def total_acquirer_approved
|
|
239
|
+
to_decimal(approximate_totals[:total_acquirer_approved])
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def total_captured
|
|
243
|
+
to_decimal(approximate_totals[:total_captured])
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def total_refunded
|
|
247
|
+
to_decimal(approximate_totals[:total_refunded])
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def total_reversed
|
|
251
|
+
to_decimal(approximate_totals[:total_chargedback])
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def total_charged_back
|
|
255
|
+
to_decimal(approximate_totals[:total_chargedback])
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
def paid?
|
|
259
|
+
(total_registered == total_captured) || (total_registered == total_acquirer_approved)
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def refunded?
|
|
263
|
+
total_registered == total_refunded
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def charged_back?
|
|
267
|
+
total_registered == total_charged_back
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def reversed?
|
|
271
|
+
total_registered == total_reversed
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
def started?
|
|
275
|
+
(authorization_status == "NEW" || authorization_status == "STARTED" ||
|
|
276
|
+
(total_captured.zero? && total_acquirer_approved.zero?)) && authorization_status != "CANCELED"
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
def cancelled?
|
|
280
|
+
authorization_status == "CANCELED"
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def account_iban
|
|
284
|
+
case payment_method
|
|
285
|
+
when PaymentMethod::IDEAL
|
|
286
|
+
payment_info = payment[:extended][:i_deal_payment_info]
|
|
287
|
+
payment_info[:shopper_bank_account][:iban] if payment_info && payment_info[:shopper_bank_account]
|
|
288
|
+
when PaymentMethod::SEPA_DIRECT_DEBIT
|
|
289
|
+
payment_info = payment[:extended][:sepa_direct_debit_payment_info]
|
|
290
|
+
payment_info[:iban] if payment_info
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
def account_bic
|
|
295
|
+
case payment_method
|
|
296
|
+
when PaymentMethod::IDEAL
|
|
297
|
+
payment_info = payment[:extended][:i_deal_payment_info]
|
|
298
|
+
payment_info[:shopper_bank_account][:bic] if payment_info && payment_info[:shopper_bank_account]
|
|
299
|
+
when PaymentMethod::SEPA_DIRECT_DEBIT
|
|
300
|
+
payment_info = payment[:extended][:sepa_direct_debit_payment_info]
|
|
301
|
+
payment_info[:bic] if payment_info
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
def account_name
|
|
306
|
+
if payment_method == PaymentMethod::IDEAL
|
|
307
|
+
payment_info = payment[:extended][:i_deal_payment_info]
|
|
308
|
+
payment_info[:holder_name] if payment_info
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
def mandate_number
|
|
313
|
+
if payment_method == PaymentMethod::SEPA_DIRECT_DEBIT
|
|
314
|
+
payment_info = payment[:extended][:sepa_direct_debit_payment_info]
|
|
315
|
+
payment_info[:mandate_number] if payment_info
|
|
316
|
+
end
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
private
|
|
320
|
+
|
|
321
|
+
def to_decimal(cents)
|
|
322
|
+
total = BigDecimal.new(cents)
|
|
323
|
+
total /= 100.0
|
|
324
|
+
total
|
|
325
|
+
end
|
|
326
|
+
end
|
|
327
|
+
end
|
|
328
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Docdata
|
|
4
|
+
module Order
|
|
5
|
+
module Urls
|
|
6
|
+
# WSDL location, see Order API 1.3.
|
|
7
|
+
WSDL_LIVE_URL = "https://secure.docdatapayments.com/ps/services/paymentservice/1_3?wsdl"
|
|
8
|
+
WSDL_TEST_URL = "https://test.docdatapayments.com/ps/services/paymentservice/1_3?wsdl"
|
|
9
|
+
|
|
10
|
+
# Payment Menu base URL, see Functional API.
|
|
11
|
+
MENU_LIVE_URL = "https://secure.docdatapayments.com/ps/menu"
|
|
12
|
+
MENU_TEST_URL = "https://test.docdatapayments.com/ps/menu"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: docdata-order
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Kentaa
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2018-02-09 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: bundler
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '1.14'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.14'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rake
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '10.0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '10.0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rspec
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '3.0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '3.0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: webmock
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '2.3'
|
|
62
|
+
- - ">="
|
|
63
|
+
- !ruby/object:Gem::Version
|
|
64
|
+
version: 2.3.2
|
|
65
|
+
type: :development
|
|
66
|
+
prerelease: false
|
|
67
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
68
|
+
requirements:
|
|
69
|
+
- - "~>"
|
|
70
|
+
- !ruby/object:Gem::Version
|
|
71
|
+
version: '2.3'
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: 2.3.2
|
|
75
|
+
- !ruby/object:Gem::Dependency
|
|
76
|
+
name: savon
|
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '2.0'
|
|
82
|
+
- - "<"
|
|
83
|
+
- !ruby/object:Gem::Version
|
|
84
|
+
version: '3.0'
|
|
85
|
+
type: :runtime
|
|
86
|
+
prerelease: false
|
|
87
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
88
|
+
requirements:
|
|
89
|
+
- - ">="
|
|
90
|
+
- !ruby/object:Gem::Version
|
|
91
|
+
version: '2.0'
|
|
92
|
+
- - "<"
|
|
93
|
+
- !ruby/object:Gem::Version
|
|
94
|
+
version: '3.0'
|
|
95
|
+
description:
|
|
96
|
+
email:
|
|
97
|
+
- support@kentaa.nl
|
|
98
|
+
executables: []
|
|
99
|
+
extensions: []
|
|
100
|
+
extra_rdoc_files: []
|
|
101
|
+
files:
|
|
102
|
+
- ".gitignore"
|
|
103
|
+
- ".rspec"
|
|
104
|
+
- ".rubocop.yml"
|
|
105
|
+
- ".travis.yml"
|
|
106
|
+
- CHANGELOG.md
|
|
107
|
+
- Gemfile
|
|
108
|
+
- LICENSE.txt
|
|
109
|
+
- README.md
|
|
110
|
+
- Rakefile
|
|
111
|
+
- bin/console
|
|
112
|
+
- bin/setup
|
|
113
|
+
- docdata-order.gemspec
|
|
114
|
+
- lib/docdata/order.rb
|
|
115
|
+
- lib/docdata/order/client.rb
|
|
116
|
+
- lib/docdata/order/exception.rb
|
|
117
|
+
- lib/docdata/order/gender.rb
|
|
118
|
+
- lib/docdata/order/ideal.rb
|
|
119
|
+
- lib/docdata/order/payment_method.rb
|
|
120
|
+
- lib/docdata/order/request.rb
|
|
121
|
+
- lib/docdata/order/response.rb
|
|
122
|
+
- lib/docdata/order/urls.rb
|
|
123
|
+
- lib/docdata/order/version.rb
|
|
124
|
+
homepage: https://github.com/KentaaNL/docdata-order
|
|
125
|
+
licenses:
|
|
126
|
+
- MIT
|
|
127
|
+
metadata: {}
|
|
128
|
+
post_install_message:
|
|
129
|
+
rdoc_options: []
|
|
130
|
+
require_paths:
|
|
131
|
+
- lib
|
|
132
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
133
|
+
requirements:
|
|
134
|
+
- - ">="
|
|
135
|
+
- !ruby/object:Gem::Version
|
|
136
|
+
version: 2.0.0
|
|
137
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
138
|
+
requirements:
|
|
139
|
+
- - ">="
|
|
140
|
+
- !ruby/object:Gem::Version
|
|
141
|
+
version: '0'
|
|
142
|
+
requirements: []
|
|
143
|
+
rubyforge_project:
|
|
144
|
+
rubygems_version: 2.6.14
|
|
145
|
+
signing_key:
|
|
146
|
+
specification_version: 4
|
|
147
|
+
summary: Ruby client for the Docdata Order API
|
|
148
|
+
test_files: []
|