docdata 0.0.2 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.yardopts +2 -0
- data/CHANGELOG.md +11 -0
- data/README.md +32 -16
- data/docdata.gemspec +5 -4
- data/lib/docdata.rb +19 -17
- data/lib/docdata/config.rb +6 -3
- data/lib/docdata/engine.rb +4 -2
- data/lib/docdata/payment.rb +56 -15
- data/lib/docdata/response.rb +44 -10
- data/lib/docdata/shopper.rb +3 -0
- data/lib/docdata/version.rb +1 -1
- data/lib/docdata/xml/cancel.xml.erb +1 -1
- data/lib/docdata/xml/create.xml.erb +2 -2
- data/lib/docdata/xml/status.xml.erb +1 -1
- data/spec/config_spec.rb +12 -12
- data/spec/payment_spec.rb +55 -4
- data/spec/response_spec.rb +1 -0
- metadata +33 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a577d283c7f93fc19f187e15e7582a0c2ea26936
|
4
|
+
data.tar.gz: b738e8b917421d056fc1b1e1c2e71ffecdab50ae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 963f7a409ce0eb4f3cfb2e0b7c78f319e268dca66e0d0024e41bee56f7f5a5b9cff974a769fa201490c709b205195ae3e4e4193c19fc350ac422ac1360f407ad
|
7
|
+
data.tar.gz: df5db9ad1135f3bd6801667ec005bb367dcd954b3228e17c6743023cdc03dc920afb11d716db435998c279c5a7e02036773b834d14761b003db1d26b5d53a779
|
data/.yardopts
ADDED
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
# Docdata
|
2
2
|
[![Build Status](https://secure.travis-ci.org/henkm/docdata.png)](http://travis-ci.org/henkm/docdata)
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/docdata.svg)](http://badge.fury.io/rb/docdata)
|
4
|
+
[![Dependency Status](https://gemnasium.com/henkm/docdata.svg)](https://gemnasium.com/henkm/docdata)
|
4
5
|
[![Code Climate](https://codeclimate.com/github/henkm/docdata/badges/gpa.svg)](https://codeclimate.com/github/henkm/docdata)
|
5
6
|
[![Coverage Status](https://coveralls.io/repos/henkm/docdata/badge.png?branch=master)](https://coveralls.io/r/henkm/docdata)
|
6
7
|
|
7
|
-
Docdata is a Ruby
|
8
|
+
Docdata is a Ruby implementation for using Docdata Payments.
|
8
9
|
|
9
|
-
|
10
|
+
Here you can find the [Documentation](http://rdoc.info/gems/docdata)
|
11
|
+
|
12
|
+
This gem relies on the awesom [Savon](http://savonrb.com/) gem to communicate with Docdata Payments' SOAP API.
|
10
13
|
|
11
14
|
## Installation
|
12
15
|
|
@@ -61,12 +64,15 @@ All the payment details that Docdata Payments requires, are - obviously - also r
|
|
61
64
|
| amount | Integer (amount in cents) | Yes |
|
62
65
|
| currency | String (ISO currency code) | Yes |
|
63
66
|
| order_reference | String (your own unique reference) | Yes |
|
67
|
+
| description | String | No |
|
64
68
|
| profile | String (name of your Docdata Payment profile)| Yes |
|
65
69
|
| shopper | Docdata::Shopper | Yes |
|
66
70
|
| line_items | Array (of Docdata::LineItem objects) | No |
|
67
71
|
| bank_id | String | No |
|
68
72
|
| prefered_payment_method | String | No |
|
69
|
-
|
|
73
|
+
| default_act | Boolean (should consumer skip docdata page?) | No |
|
74
|
+
| key | String (is available after successful 'create') | readonly |
|
75
|
+
| url | String (redirect URI is available after 'create') | readonly |
|
70
76
|
|
71
77
|
|
72
78
|
## Default values
|
@@ -76,8 +82,9 @@ If you use `GIROPAY`, `SEPA` and `AFTERPAY` this is the case. (Maybe also in oth
|
|
76
82
|
|
77
83
|
## Example usage in Rails application
|
78
84
|
The example below assumes you have your application set up with a Order model, which contains the information needed for this transaction (amount, name, etc.).
|
85
|
+
|
79
86
|
```ruby
|
80
|
-
|
87
|
+
|
81
88
|
def start_transaction
|
82
89
|
# find the order from your database
|
83
90
|
@order = Order.find(params[:id])
|
@@ -106,6 +113,7 @@ def start_transaction
|
|
106
113
|
# TODO: Display the error and warn the user that something went wrong.
|
107
114
|
end
|
108
115
|
end
|
116
|
+
|
109
117
|
```
|
110
118
|
|
111
119
|
## Ideal
|
@@ -115,8 +123,9 @@ For transactions in the Netherlands, iDeal is the most common option. To redirec
|
|
115
123
|
In `Docdata::Payment` you can set `bank_id` to any value. If you do, the redirect URI will redirect your user directly to the bank page.
|
116
124
|
|
117
125
|
Example code:
|
126
|
+
|
118
127
|
```ruby
|
119
|
-
|
128
|
+
|
120
129
|
def ideal_checkout
|
121
130
|
@order = Order.find(params[:order_id])
|
122
131
|
@banks = Docdata::Ideal.banks
|
@@ -151,17 +160,20 @@ def start_ideal_transaction
|
|
151
160
|
# TODO: Display the error and warn the user that something went wrong.
|
152
161
|
end
|
153
162
|
end
|
163
|
+
|
154
164
|
```
|
155
165
|
|
156
166
|
View template (ideal_checkout.html.erb):
|
157
167
|
|
158
|
-
```
|
168
|
+
```html
|
169
|
+
|
159
170
|
<h2>Choose your bank</h2>
|
160
171
|
<%= form_tag start_ideal_transaction_path, method: :post, target: "_blank" do %>
|
161
172
|
<%= select_tag "bank_id", options_from_collection_for_select(@banks, "id", "name") %>
|
162
173
|
<%= hidden_field_tag :order_id, @order.id %>
|
163
174
|
<%= submit_tag "Proceed to checkout" %>
|
164
175
|
<% end %>
|
176
|
+
|
165
177
|
```
|
166
178
|
|
167
179
|
## Tips and samples
|
@@ -170,26 +182,30 @@ View template (ideal_checkout.html.erb):
|
|
170
182
|
When making a new `Docdata::Payment`, use the `default_act` parameter to redirect consumers directly to the acquirers website. Example:
|
171
183
|
|
172
184
|
```ruby
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
185
|
+
|
186
|
+
@payment = Docdata::Payment.new(
|
187
|
+
amount: @order.total,
|
188
|
+
currency: @order.currency,
|
189
|
+
shopper: shopper,
|
190
|
+
profile: "My Default Profile",
|
191
|
+
order_reference: "order ##{@order.id}",
|
192
|
+
bank_id: params[:bank_id],
|
193
|
+
default_act: true # redirect directly to the bank, skipping the Docdata web menu
|
194
|
+
)
|
195
|
+
|
182
196
|
```
|
183
197
|
|
184
198
|
#### Retrieve a list of iDeal banks to show
|
185
199
|
`Docata::Ideal.banks` returns an Array.
|
186
200
|
|
187
201
|
## Contributing
|
202
|
+
Want to contribute? Greate!
|
203
|
+
|
188
204
|
|
189
205
|
1. Fork it
|
190
206
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
191
207
|
3. Make changes, document them and add tests (rspec)
|
192
|
-
4. Run the entire test suite and make sure all tests pass
|
208
|
+
4. Run the entire test suite and make sure all tests pass (`rake`)
|
193
209
|
5. Commit your changes (`git commit -am 'Add some feature'`)
|
194
210
|
6. Push to the branch (`git push origin my-new-feature`)
|
195
211
|
7. Create new Pull Request
|
data/docdata.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
-
spec.add_development_dependency "bundler"
|
21
|
+
spec.add_development_dependency "bundler"
|
22
22
|
spec.add_development_dependency "rake"
|
23
23
|
spec.add_development_dependency "rspec"
|
24
24
|
spec.add_development_dependency "vcr"
|
@@ -26,12 +26,13 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.add_development_dependency "coveralls"
|
27
27
|
spec.add_development_dependency "simplecov"
|
28
28
|
spec.add_development_dependency "yard"
|
29
|
-
spec.add_development_dependency "
|
29
|
+
spec.add_development_dependency "redcarpet", "~> 1" # for documentation
|
30
|
+
spec.add_development_dependency "github-markup"
|
30
31
|
|
31
|
-
# spec.add_runtime_dependency 'savon', git: 'savonrb/savon'
|
32
32
|
spec.add_dependency 'savon', '~> 2.0'
|
33
33
|
spec.add_dependency 'nori'
|
34
34
|
spec.add_dependency 'veto'
|
35
|
+
spec.add_dependency 'rubyntlm'
|
35
36
|
spec.add_dependency 'nokogiri'
|
36
|
-
spec.add_dependency
|
37
|
+
spec.add_dependency 'railties'
|
37
38
|
end
|
data/lib/docdata.rb
CHANGED
@@ -11,6 +11,8 @@ require 'veto'
|
|
11
11
|
|
12
12
|
# Files
|
13
13
|
require "docdata/version"
|
14
|
+
require "docdata/config"
|
15
|
+
require "docdata/engine" if defined?(Rails) && Rails::VERSION::MAJOR.to_i >= 3
|
14
16
|
require "docdata/docdata_error"
|
15
17
|
require "docdata/shopper"
|
16
18
|
require "docdata/payment"
|
@@ -27,22 +29,22 @@ include Savon
|
|
27
29
|
module Docdata
|
28
30
|
API_VERSION = 1
|
29
31
|
|
30
|
-
# @return [String] Your DocData username
|
31
|
-
# @note The is a required parameter.
|
32
|
-
mattr_accessor :username
|
33
|
-
@@username = nil
|
32
|
+
# # @return [String] Your DocData username
|
33
|
+
# # @note The is a required parameter.
|
34
|
+
# mattr_accessor :username
|
35
|
+
# @@username = nil
|
34
36
|
|
35
|
-
# @return [String] Your DocData password
|
36
|
-
mattr_accessor :password
|
37
|
-
@@password = nil
|
37
|
+
# # @return [String] Your DocData password
|
38
|
+
# mattr_accessor :password
|
39
|
+
# @@password = nil
|
38
40
|
|
39
|
-
# @return [Boolean] Test mode switch
|
40
|
-
mattr_accessor :test_mode
|
41
|
-
@@test_mode = true
|
41
|
+
# # @return [Boolean] Test mode switch
|
42
|
+
# mattr_accessor :test_mode
|
43
|
+
# @@test_mode = true
|
42
44
|
|
43
|
-
# @param [String] Set the url of your website where docdata can send messages to
|
44
|
-
mattr_accessor :return_url
|
45
|
-
@@return_url = nil
|
45
|
+
# # @param [String] Set the url of your website where docdata can send messages to
|
46
|
+
# mattr_accessor :return_url
|
47
|
+
# @@return_url = nil
|
46
48
|
|
47
49
|
# returns the version number
|
48
50
|
def self.version
|
@@ -55,7 +57,7 @@ module Docdata
|
|
55
57
|
end
|
56
58
|
|
57
59
|
def self.url
|
58
|
-
if test_mode
|
60
|
+
if Docdata::Config.test_mode
|
59
61
|
"https://test.docdatapayments.com/ps/services/paymentservice/1_1?wsdl"
|
60
62
|
else
|
61
63
|
"https://www.docdatapayments.com/ps/services/paymentservice/1_1?wsdl"
|
@@ -66,9 +68,9 @@ module Docdata
|
|
66
68
|
# in environment variables to make the tests pass with your test
|
67
69
|
# credentials.
|
68
70
|
def self.set_credentials_from_environment
|
69
|
-
|
70
|
-
|
71
|
-
|
71
|
+
Docdata::Config.password = ENV["DOCDATA_PASSWORD"]
|
72
|
+
Docdata::Config.username = ENV["DOCDATA_USERNAME"]
|
73
|
+
Docdata::Config.return_url = ENV["DOCDATA_RETURN_URL"]
|
72
74
|
end
|
73
75
|
|
74
76
|
def self.client
|
data/lib/docdata/config.rb
CHANGED
@@ -10,15 +10,18 @@ module Docdata::Config
|
|
10
10
|
attr_accessor :password
|
11
11
|
# @return [Boolean] Test mode switch
|
12
12
|
attr_accessor :test_mode
|
13
|
+
# @return [String] Base return URL
|
14
|
+
attr_accessor :return_url
|
13
15
|
|
14
16
|
|
15
17
|
# Set's the default value's to nil and false
|
16
18
|
# @return [Hash] configuration options
|
17
19
|
def init!
|
18
20
|
@defaults = {
|
19
|
-
:@username
|
20
|
-
:@password
|
21
|
-
:@test_mode
|
21
|
+
:@username => nil,
|
22
|
+
:@password => nil,
|
23
|
+
:@test_mode => true,
|
24
|
+
:@return_url => nil
|
22
25
|
}
|
23
26
|
end
|
24
27
|
|
data/lib/docdata/engine.rb
CHANGED
@@ -5,9 +5,11 @@ module Docdata
|
|
5
5
|
#
|
6
6
|
# @example default
|
7
7
|
# # /config/environments/development.rb
|
8
|
-
#
|
8
|
+
# config.docata.username = "myapp_com"
|
9
|
+
# config.docata.password = "pa55w0rd"
|
10
|
+
# config.docata.test_mode = "true"
|
9
11
|
#
|
10
12
|
class Engine < Rails::Engine
|
11
|
-
config.docdata = Docdata
|
13
|
+
config.docdata = Docdata::Config
|
12
14
|
end
|
13
15
|
end
|
data/lib/docdata/payment.rb
CHANGED
@@ -53,7 +53,7 @@ module Docdata
|
|
53
53
|
attr_accessor :line_items
|
54
54
|
attr_accessor :key
|
55
55
|
attr_accessor :default_act
|
56
|
-
|
56
|
+
attr_accessor :canceled
|
57
57
|
|
58
58
|
|
59
59
|
#
|
@@ -84,23 +84,42 @@ module Docdata
|
|
84
84
|
# if there are any line items, they should all be valid.
|
85
85
|
validate_line_items
|
86
86
|
|
87
|
-
# puts
|
88
|
-
|
89
87
|
# make the SOAP API call
|
90
|
-
response = Docdata.client.call(:create, xml:
|
88
|
+
response = Docdata.client.call(:create, xml: create_xml)
|
91
89
|
response_object = Docdata::Response.parse(:create, response)
|
92
90
|
if response_object.success?
|
93
91
|
self.key = response_object.key
|
94
92
|
end
|
93
|
+
|
94
|
+
# set `self` as the value of the `payment` attribute in the response object
|
95
|
+
response_object.payment = self
|
96
|
+
response_object.url = redirect_url
|
97
|
+
|
95
98
|
return response_object
|
96
99
|
end
|
97
100
|
|
98
|
-
#
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
101
|
+
#
|
102
|
+
# This calls the 'cancel' method of the SOAP API
|
103
|
+
# It cancels the payment and returns a Docdata::Response object
|
104
|
+
def cancel
|
105
|
+
# make the SOAP API call
|
106
|
+
response = Docdata.client.call(:cancel, xml: cancel_xml)
|
107
|
+
response_object = Docdata::Response.parse(:cancel, response)
|
108
|
+
if response_object.success?
|
109
|
+
self.key = response_object.key
|
110
|
+
end
|
111
|
+
|
112
|
+
# set `self` as the value of the `payment` attribute in the response object
|
113
|
+
response_object.payment = self
|
114
|
+
self.canceled = true
|
115
|
+
return true
|
116
|
+
end
|
117
|
+
|
118
|
+
# This method makes it possible to find and cancel a payment with only the key
|
119
|
+
# It combines
|
120
|
+
def self.cancel(api_key)
|
121
|
+
p = self.find(api_key)
|
122
|
+
p.cancel
|
104
123
|
end
|
105
124
|
|
106
125
|
# Initialize a Payment object with the key set
|
@@ -135,15 +154,15 @@ module Docdata
|
|
135
154
|
def redirect_url
|
136
155
|
url = {}
|
137
156
|
|
138
|
-
base_url = Docdata.return_url
|
139
|
-
if Docdata.test_mode
|
157
|
+
base_url = Docdata::Config.return_url
|
158
|
+
if Docdata::Config.test_mode
|
140
159
|
redirect_base_url = 'https://test.docdatapayments.com/ps/menu'
|
141
160
|
else
|
142
161
|
redirect_base_url = 'https://secure.docdatapayments.com/ps/menu'
|
143
162
|
end
|
144
163
|
url[:command] = "show_payment_cluster"
|
145
164
|
url[:payment_cluster_key] = key
|
146
|
-
url[:merchant_name] = Docdata.username
|
165
|
+
url[:merchant_name] = Docdata::Config.username
|
147
166
|
# only include return URL if present
|
148
167
|
if base_url.present?
|
149
168
|
url[:return_url_success] = "#{base_url}/success?key=#{url[:payment_cluster_key]}"
|
@@ -151,9 +170,11 @@ module Docdata
|
|
151
170
|
url[:return_url_canceled] = "#{base_url}/canceled?key=#{url[:payment_cluster_key]}"
|
152
171
|
url[:return_url_error] = "#{base_url}/error?key=#{url[:payment_cluster_key]}"
|
153
172
|
end
|
154
|
-
|
173
|
+
if shopper && shopper.language_code
|
174
|
+
url[:client_language] = shopper.language_code
|
175
|
+
end
|
155
176
|
if default_act
|
156
|
-
url[:default_act] =
|
177
|
+
url[:default_act] = "yes"
|
157
178
|
end
|
158
179
|
if bank_id.present?
|
159
180
|
url[:ideal_issuer_id] = bank_id
|
@@ -162,10 +183,30 @@ module Docdata
|
|
162
183
|
params = URI.encode_www_form(url)
|
163
184
|
uri = "#{redirect_base_url}?#{params}"
|
164
185
|
end
|
186
|
+
alias_method :url, :redirect_url
|
165
187
|
|
166
188
|
|
167
189
|
private
|
168
190
|
|
191
|
+
|
192
|
+
# @return [String] the xml to send in the SOAP API
|
193
|
+
def create_xml
|
194
|
+
xml_file = "#{File.dirname(__FILE__)}/xml/create.xml.erb"
|
195
|
+
template = File.read(xml_file)
|
196
|
+
namespace = OpenStruct.new(payment: self, shopper: shopper)
|
197
|
+
xml = ERB.new(template).result(namespace.instance_eval { binding })
|
198
|
+
end
|
199
|
+
|
200
|
+
|
201
|
+
# @return [String] the xml to send in the SOAP API
|
202
|
+
def cancel_xml
|
203
|
+
xml_file = "#{File.dirname(__FILE__)}/xml/cancel.xml.erb"
|
204
|
+
template = File.read(xml_file)
|
205
|
+
namespace = OpenStruct.new(payment: self)
|
206
|
+
xml = ERB.new(template).result(namespace.instance_eval { binding })
|
207
|
+
end
|
208
|
+
|
209
|
+
|
169
210
|
# In case there are any line_items, validate them all and
|
170
211
|
# raise an error for the first invalid LineItem
|
171
212
|
def validate_line_items
|
data/lib/docdata/response.rb
CHANGED
@@ -28,6 +28,23 @@ module Docdata
|
|
28
28
|
# @return [String] The raw XML returned by the API
|
29
29
|
attr_accessor :xml
|
30
30
|
|
31
|
+
# @return [Boolean]
|
32
|
+
attr_accessor :paid
|
33
|
+
|
34
|
+
# @return [Integer] the captured amount in cents
|
35
|
+
attr_accessor :amount
|
36
|
+
|
37
|
+
# @return [String] the status of this response (capture response)
|
38
|
+
attr_accessor :status
|
39
|
+
|
40
|
+
# @return [String] Currency ("EUR", "GBP", "USD", etc.)
|
41
|
+
attr_accessor :currency
|
42
|
+
|
43
|
+
# @return [Docdata::Payment] object
|
44
|
+
attr_accessor :payment
|
45
|
+
|
46
|
+
# @return [String] the return URL
|
47
|
+
attr_accessor :url
|
31
48
|
|
32
49
|
#
|
33
50
|
# Initializer to transform a +Hash+ into an Response object
|
@@ -41,6 +58,13 @@ module Docdata
|
|
41
58
|
end
|
42
59
|
end
|
43
60
|
|
61
|
+
# Set the attributes based on the API response
|
62
|
+
def set_attributes
|
63
|
+
self.paid = is_paid?
|
64
|
+
self.amount = report[:payment][:authorization][:amount].to_i if report && report[:payment] && report[:payment][:authorization]
|
65
|
+
self.status = capture_status if capture_status
|
66
|
+
self.currency = currency_to_set
|
67
|
+
end
|
44
68
|
|
45
69
|
#
|
46
70
|
# Parses the returned response hash and turns it
|
@@ -59,6 +83,7 @@ module Docdata
|
|
59
83
|
if m[:report]
|
60
84
|
r.report = m[:report]
|
61
85
|
end
|
86
|
+
r.set_attributes
|
62
87
|
return r
|
63
88
|
end
|
64
89
|
end
|
@@ -95,7 +120,11 @@ module Docdata
|
|
95
120
|
|
96
121
|
# @return [String] the status string provided by the API. One of [AUTHORIZED, CANCELED]
|
97
122
|
def payment_status
|
98
|
-
report[:payment]
|
123
|
+
if report[:payment]
|
124
|
+
report[:payment][:authorization][:status]
|
125
|
+
else
|
126
|
+
nil
|
127
|
+
end
|
99
128
|
end
|
100
129
|
|
101
130
|
# @return [Boolean] true/false, depending wether this payment is considered paid.
|
@@ -105,7 +134,7 @@ module Docdata
|
|
105
134
|
# a different 'paid'.
|
106
135
|
# @note This method is never 100% reliable. If you need to finetune this, please implement your own method, using
|
107
136
|
# the available data (total_captured, total_registered, etc.)
|
108
|
-
def
|
137
|
+
def is_paid?
|
109
138
|
if payment_method
|
110
139
|
case payment_method
|
111
140
|
# ideal (dutch)
|
@@ -136,23 +165,28 @@ module Docdata
|
|
136
165
|
|
137
166
|
# @return [Boolean]
|
138
167
|
def canceled
|
139
|
-
payment_status == "CANCELED" ||
|
168
|
+
(payment_status && payment_status == "CANCELED") ||
|
169
|
+
(capture_status && capture_status == "CANCELED")
|
140
170
|
end
|
141
171
|
alias_method :canceled?, :canceled
|
142
172
|
|
143
173
|
# @return [String] the status of the capture, if exists
|
144
174
|
def capture_status
|
145
|
-
report[:payment][:authorization][:
|
175
|
+
if report && report[:payment] && report[:payment][:authorization] && report[:payment][:authorization][:capture]
|
176
|
+
report[:payment][:authorization][:capture][:status]
|
177
|
+
else
|
178
|
+
nil
|
179
|
+
end
|
146
180
|
end
|
147
181
|
|
148
|
-
# @return [Integer] the caputred amount in cents
|
149
|
-
def amount
|
150
|
-
report[:payment][:authorization][:amount].to_i
|
151
|
-
end
|
152
182
|
|
153
183
|
# @return [String] the currency if this transaction
|
154
|
-
def
|
155
|
-
status_xml.xpath("//amount").
|
184
|
+
def currency_to_set
|
185
|
+
if status_xml && status_xml.xpath("//amount").any?
|
186
|
+
status_xml.xpath("//amount").first.attributes["currency"].value
|
187
|
+
else
|
188
|
+
nil
|
189
|
+
end
|
156
190
|
end
|
157
191
|
|
158
192
|
# @return [Nokogiri::XML::Document] object
|
data/lib/docdata/shopper.rb
CHANGED
@@ -29,6 +29,7 @@ module Docdata
|
|
29
29
|
# @param format [String] The shopper ID
|
30
30
|
# @param format [String] Shopper first name
|
31
31
|
# @param format [String] Shopper last name
|
32
|
+
# @param format [String] Gender ['M','F']
|
32
33
|
# @param format [String] Shopper street address
|
33
34
|
# @param format [String] Shopper house number
|
34
35
|
# @param format [String] Shopper postal code
|
@@ -43,6 +44,7 @@ module Docdata
|
|
43
44
|
attr_accessor :id
|
44
45
|
attr_accessor :first_name
|
45
46
|
attr_accessor :last_name
|
47
|
+
attr_accessor :gender
|
46
48
|
attr_accessor :street
|
47
49
|
attr_accessor :house_number
|
48
50
|
attr_accessor :postal_code
|
@@ -87,6 +89,7 @@ module Docdata
|
|
87
89
|
@city = "City"
|
88
90
|
@country_code = "NL"
|
89
91
|
@language_code = "nl"
|
92
|
+
@gender = "M"
|
90
93
|
@email = "random@example.com"
|
91
94
|
end
|
92
95
|
|
data/lib/docdata/version.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
<soapenv:Header/>
|
3
3
|
<soapenv:Body>
|
4
4
|
<_1:cancelRequest version="1.1">
|
5
|
-
<_1:merchant name="<%=Docdata.username%>" password="Docdata.password"/>
|
5
|
+
<_1:merchant name="<%=Docdata::Config.username%>" password="<%= Docdata::Config.password%>"/>
|
6
6
|
<_1:paymentOrderKey><%= payment.key %></_1:paymentOrderKey>
|
7
7
|
</_1:cancelRequest>
|
8
8
|
</soapenv:Body>
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<soapenv:Header/>
|
3
3
|
<soapenv:Body>
|
4
4
|
<_1:createRequest version="1.1">
|
5
|
-
<_1:merchant name="<%= Docdata.username %>" password="<%= Docdata.password %>"/>
|
5
|
+
<_1:merchant name="<%= Docdata::Config.username %>" password="<%= Docdata::Config.password %>"/>
|
6
6
|
<_1:merchantOrderReference><%= payment.order_reference %></_1:merchantOrderReference>
|
7
7
|
<_1:paymentPreferences>
|
8
8
|
<_1:profile><%= payment.profile %></_1:profile>
|
@@ -16,7 +16,7 @@
|
|
16
16
|
</_1:name>
|
17
17
|
<_1:email><%= shopper.email %></_1:email>
|
18
18
|
<_1:language code="<%= shopper.language_code %>"/>
|
19
|
-
<_1:gender
|
19
|
+
<_1:gender><%= shopper.gender.upcase %></_1:gender>
|
20
20
|
|
21
21
|
</_1:shopper>
|
22
22
|
<_1:totalGrossAmount currency="<%= payment.currency %>"><%= payment.amount %></_1:totalGrossAmount>
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<soapenv:Header/>
|
3
3
|
<soapenv:Body>
|
4
4
|
<_1:statusRequest version="1.1">
|
5
|
-
<_1:merchant name="<%=Docdata.username%>" password="<%= Docdata.password %>"/>
|
5
|
+
<_1:merchant name="<%=Docdata::Config.username%>" password="<%= Docdata::Config.password %>"/>
|
6
6
|
<_1:paymentOrderKey><%= payment.key %></_1:paymentOrderKey>
|
7
7
|
</_1:statusRequest>
|
8
8
|
</soapenv:Body>
|
data/spec/config_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Docdata do
|
4
4
|
before(:each) do
|
5
|
-
Docdata.test_mode = true
|
5
|
+
Docdata::Config.test_mode = true
|
6
6
|
end
|
7
7
|
|
8
8
|
it "returns correct version number" do
|
@@ -11,30 +11,30 @@ describe Docdata do
|
|
11
11
|
|
12
12
|
context "settings" do
|
13
13
|
it "is in test mode by default" do
|
14
|
-
expect(Docdata.test_mode).to eq(true)
|
14
|
+
expect(Docdata::Config.test_mode).to eq(true)
|
15
15
|
end
|
16
16
|
|
17
17
|
# it "should have the correct default values" do
|
18
|
-
# expect(Docdata.test_mode).to be_truthy
|
19
|
-
# expect(Docdata.username).to be_nil
|
20
|
-
# expect(Docdata.password).to be_nil
|
18
|
+
# expect(Docdata::Config.test_mode).to be_truthy
|
19
|
+
# expect(Docdata::Config.username).to be_nil
|
20
|
+
# expect(Docdata::Config.password).to be_nil
|
21
21
|
# end
|
22
22
|
|
23
23
|
it "is able to update and set settings" do
|
24
|
-
Docdata.test_mode = false
|
25
|
-
Docdata.username = "abcd"
|
26
|
-
Docdata.password = "321zyx12"
|
24
|
+
Docdata::Config.test_mode = false
|
25
|
+
Docdata::Config.username = "abcd"
|
26
|
+
Docdata::Config.password = "321zyx12"
|
27
27
|
|
28
|
-
expect(Docdata.test_mode).to be_falsey
|
29
|
-
expect(Docdata.username).to match "abcd"
|
30
|
-
expect(Docdata.password).to match "321zyx12"
|
28
|
+
expect(Docdata::Config.test_mode).to be_falsey
|
29
|
+
expect(Docdata::Config.username).to match "abcd"
|
30
|
+
expect(Docdata::Config.password).to match "321zyx12"
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
34
|
context "SOAP configuration" do
|
35
35
|
|
36
36
|
it "should have the proper test URL" do
|
37
|
-
expect(Docdata.test_mode).to eq(true)
|
37
|
+
expect(Docdata::Config.test_mode).to eq(true)
|
38
38
|
expect(Docdata.url).to eq("https://test.docdatapayments.com/ps/services/paymentservice/1_1?wsdl")
|
39
39
|
end
|
40
40
|
|
data/spec/payment_spec.rb
CHANGED
@@ -6,7 +6,7 @@ describe Docdata::Payment do
|
|
6
6
|
@payment = Docdata::Payment.new
|
7
7
|
@payment.amount = 500
|
8
8
|
@payment.profile = ENV["DOCDATA_PAYMENT_PROFILE"]
|
9
|
-
@payment.order_reference = rand(500)
|
9
|
+
@payment.order_reference = rand(500) + Time.now.to_i
|
10
10
|
@payment.currency = "EUR"
|
11
11
|
@payment.description = "Description of my order"
|
12
12
|
@payment.shopper = @shopper
|
@@ -45,20 +45,21 @@ describe Docdata::Payment do
|
|
45
45
|
expect(@payment.shopper).to be_kind_of(Docdata::Shopper)
|
46
46
|
expect(@payment.shopper.first_name).to eq("John")
|
47
47
|
end
|
48
|
+
|
48
49
|
end
|
49
50
|
|
50
51
|
describe "#create" do
|
51
52
|
|
52
53
|
it "raises error when credentials are wrong" do
|
53
54
|
# puts @payment.xml
|
54
|
-
Docdata.password = "1234"
|
55
|
+
Docdata::Config.password = "1234"
|
55
56
|
VCR.use_cassette("payments-xml-create-without-credentials") do
|
56
57
|
expect { @payment.create }.to raise_error(DocdataError, "Login failed.")
|
57
58
|
end
|
58
59
|
end
|
59
60
|
|
60
61
|
it "raises error when password is blank" do
|
61
|
-
Docdata.password = ""
|
62
|
+
Docdata::Config.password = ""
|
62
63
|
VCR.use_cassette("payments-xml-create-without-password") do
|
63
64
|
expect { @payment.create }.to raise_error(DocdataError, /The value '' of attribute 'password' on element '_1:merchant' is not valid with respect to its type/)
|
64
65
|
end
|
@@ -87,6 +88,26 @@ describe Docdata::Payment do
|
|
87
88
|
end
|
88
89
|
end
|
89
90
|
|
91
|
+
it "has a payment" do
|
92
|
+
Docdata.set_credentials_from_environment
|
93
|
+
VCR.use_cassette("payments-successful-create") do
|
94
|
+
@response = @payment.create
|
95
|
+
end
|
96
|
+
expect(@response.payment).to be_kind_of(Docdata::Payment)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "has a `url` property" do
|
100
|
+
Docdata.set_credentials_from_environment
|
101
|
+
VCR.use_cassette("payments-successful-create") do
|
102
|
+
@response = @payment.create
|
103
|
+
end
|
104
|
+
# puts @payment.redirect_url
|
105
|
+
# puts @payment.inspect
|
106
|
+
# puts @response.payment.inspect
|
107
|
+
# puts @response.url
|
108
|
+
expect(@response.url).to be_present
|
109
|
+
end
|
110
|
+
|
90
111
|
it "redirect directly to the bank if bank_id && default_act is given" do
|
91
112
|
Docdata.set_credentials_from_environment
|
92
113
|
@payment.bank_id = "0031" # ABN AMRO
|
@@ -94,7 +115,7 @@ describe Docdata::Payment do
|
|
94
115
|
VCR.use_cassette("payments-successful-create") do
|
95
116
|
@payment.create
|
96
117
|
# puts @payment.redirect_url
|
97
|
-
expect(@payment.redirect_url).to include("&default_act=
|
118
|
+
expect(@payment.redirect_url).to include("&default_act=yes&ideal_issuer_id=0031&default_pm=IDEAL")
|
98
119
|
end
|
99
120
|
end
|
100
121
|
|
@@ -159,4 +180,34 @@ describe Docdata::Payment do
|
|
159
180
|
expect(@payment).to be_kind_of(Docdata::Payment)
|
160
181
|
end
|
161
182
|
end
|
183
|
+
|
184
|
+
describe "#cancel" do
|
185
|
+
before(:each) do
|
186
|
+
Docdata.set_credentials_from_environment
|
187
|
+
VCR.use_cassette("payments-successful-create") do
|
188
|
+
@payment.create
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
it "returns a response object" do
|
193
|
+
VCR.use_cassette("payments-successful-cancel") do
|
194
|
+
@response = @payment.cancel
|
195
|
+
end
|
196
|
+
expect(@response).to be(true)
|
197
|
+
end
|
198
|
+
|
199
|
+
it "has attribute 'canceled' to true" do
|
200
|
+
VCR.use_cassette("payments-successful-cancel") do
|
201
|
+
@response = @payment.cancel
|
202
|
+
end
|
203
|
+
expect(@payment.canceled).to eq(true)
|
204
|
+
end
|
205
|
+
|
206
|
+
it "combines find and cancel in one call" do
|
207
|
+
|
208
|
+
VCR.use_cassette("payments-find-and-cancel") do
|
209
|
+
@payment = Docdata::Payment.cancel(@payment.key)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
162
213
|
end
|
data/spec/response_spec.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: docdata
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Henk Meijer
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-08-
|
12
|
+
date: 2014-08-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -124,7 +124,21 @@ dependencies:
|
|
124
124
|
- !ruby/object:Gem::Version
|
125
125
|
version: '0'
|
126
126
|
- !ruby/object:Gem::Dependency
|
127
|
-
name:
|
127
|
+
name: redcarpet
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ~>
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '1'
|
133
|
+
type: :development
|
134
|
+
prerelease: false
|
135
|
+
version_requirements: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ~>
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '1'
|
140
|
+
- !ruby/object:Gem::Dependency
|
141
|
+
name: github-markup
|
128
142
|
requirement: !ruby/object:Gem::Requirement
|
129
143
|
requirements:
|
130
144
|
- - '>='
|
@@ -179,6 +193,20 @@ dependencies:
|
|
179
193
|
- - '>='
|
180
194
|
- !ruby/object:Gem::Version
|
181
195
|
version: '0'
|
196
|
+
- !ruby/object:Gem::Dependency
|
197
|
+
name: rubyntlm
|
198
|
+
requirement: !ruby/object:Gem::Requirement
|
199
|
+
requirements:
|
200
|
+
- - '>='
|
201
|
+
- !ruby/object:Gem::Version
|
202
|
+
version: '0'
|
203
|
+
type: :runtime
|
204
|
+
prerelease: false
|
205
|
+
version_requirements: !ruby/object:Gem::Requirement
|
206
|
+
requirements:
|
207
|
+
- - '>='
|
208
|
+
- !ruby/object:Gem::Version
|
209
|
+
version: '0'
|
182
210
|
- !ruby/object:Gem::Dependency
|
183
211
|
name: nokogiri
|
184
212
|
requirement: !ruby/object:Gem::Requirement
|
@@ -217,6 +245,8 @@ files:
|
|
217
245
|
- .coveralls.yml
|
218
246
|
- .gitignore
|
219
247
|
- .travis.yml
|
248
|
+
- .yardopts
|
249
|
+
- CHANGELOG.md
|
220
250
|
- Gemfile
|
221
251
|
- LICENSE
|
222
252
|
- README.md
|