docdata 0.0.1 → 0.0.2

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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.coveralls.yml +2 -0
  3. data/.gitignore +4 -1
  4. data/.travis.yml +10 -0
  5. data/LICENSE +1 -1
  6. data/README.md +173 -7
  7. data/Rakefile +8 -0
  8. data/docdata.gemspec +18 -11
  9. data/lib/docdata.rb +74 -1
  10. data/lib/docdata/bank.rb +27 -0
  11. data/lib/docdata/config.rb +41 -0
  12. data/lib/docdata/docdata_error.rb +8 -0
  13. data/lib/docdata/engine.rb +13 -0
  14. data/lib/docdata/ideal.rb +40 -0
  15. data/lib/docdata/line_item.rb +99 -0
  16. data/lib/docdata/payment.rb +196 -0
  17. data/lib/docdata/response.rb +173 -0
  18. data/lib/docdata/shopper.rb +112 -0
  19. data/lib/docdata/version.rb +1 -1
  20. data/lib/docdata/xml/bank-list.xml +39 -0
  21. data/lib/docdata/xml/cancel.xml.erb +9 -0
  22. data/lib/docdata/xml/create.xml.erb +98 -0
  23. data/lib/docdata/xml/start.xml.erb +67 -0
  24. data/lib/docdata/xml/status.xml.erb +9 -0
  25. data/php-example/create.xml.erb +140 -0
  26. data/php-example/index.html +78 -0
  27. data/php-example/process.php +182 -0
  28. data/php-example/return.php +36 -0
  29. data/php-example/soap.rb +21 -0
  30. data/spec/config_spec.rb +53 -0
  31. data/spec/ideal_spec.rb +19 -0
  32. data/spec/line_item_spec.rb +55 -0
  33. data/spec/payment_spec.rb +162 -0
  34. data/spec/response_spec.rb +206 -0
  35. data/spec/shopper_spec.rb +50 -0
  36. data/spec/spec_helper.rb +36 -0
  37. data/spec/xml/status-canceled-creditcard.xml +34 -0
  38. data/spec/xml/status-canceled-ideal.xml +29 -0
  39. data/spec/xml/status-new.xml +20 -0
  40. data/spec/xml/status-paid-creditcard.xml +33 -0
  41. data/spec/xml/status-paid-ideal.xml +33 -0
  42. data/spec/xml/status-paid-sofort.xml +33 -0
  43. metadata +145 -13
  44. data/LICENSE.txt +0 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 092c89afd8ea21f98293b06c1dc41204c606290f
4
- data.tar.gz: 18726ea6de8213826d69d7d916172a841e52aba0
3
+ metadata.gz: c5ff4754891764a2fadf457caa3103234ab0ff66
4
+ data.tar.gz: 4a88eccbd3b38ca964800661cbff4f8caa01d856
5
5
  SHA512:
6
- metadata.gz: 269ff144bf374c38aafc9037ddd8ee089a05084e282362b28072d54462a5eb85691d684763acfb3f3e5a56fb98a67fa26dbeb9420b03993e06517a0469eb3402
7
- data.tar.gz: bc7586ee50bc8150d76002065aaf0e78d9a719aadcc7270cd5d1c9f279f6d87c3bc293211f14c81f8bd8fd7cfde8e160d9f08df2b134438ac6177943cec406b1
6
+ metadata.gz: 14bb38e8034b1b17ce035e0e2a49637491622a699556b1886aa803bedd78e52685de32fa2cb4110c975cea5c8bb52d29d7e46af219b200f0ad1f4e0911042ab3
7
+ data.tar.gz: bf6a93bb98864ffb8a576bf6c9e4ef07e6832fc3221d1cd5805302dcd21bc0fd0da042f11ef17dcdff66b25d9ee3017775ec4dfcfd7328cbe24c04e9be7cbff7
data/.coveralls.yml ADDED
@@ -0,0 +1,2 @@
1
+ service_name: travis-pro
2
+ repo_token: 6imlOxW82jtN0x1uQsfPlrn9BbJaouXdI
data/.gitignore CHANGED
@@ -1,5 +1,6 @@
1
1
  *.gem
2
2
  *.rbc
3
+ .DS_Store
3
4
  .bundle
4
5
  .config
5
6
  .yardoc
@@ -7,11 +8,13 @@ Gemfile.lock
7
8
  InstalledFiles
8
9
  _yardoc
9
10
  coverage
10
- doc/
11
11
  lib/bundler/man
12
12
  pkg
13
+ doc
13
14
  rdoc
14
15
  spec/reports
15
16
  test/tmp
16
17
  test/version_tmp
17
18
  tmp
19
+ spec/vcr_cassettes
20
+ test-credentials.yaml
data/.travis.yml ADDED
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ script: bundle exec rake --trace
3
+ rvm:
4
+ - '2.0'
5
+ env:
6
+ global:
7
+ - secure: TIDimYgwlRDIMSeNUDsc3Bwb1dCSdfyF89clBbGssrolmxDSOMCWEkKg+XVeiR8ZTaprule80X35rw8xqoNqpYuZedH0Z6owu1JQ6C3XkUW9TXVhcIQ3WF7KF8YVXwSLYTf9W4F9j8KNW8azb2PmmuLbDqmqAhBxMsG+i1hgPaw=
8
+ - secure: ZrkG1/8uInY6xiP8xD7HhjDxgxmvbxRHdmzveN/qh9CIsOjCAESfgjd9WjiP8IiW2/G5tYRkVeqYijDLnTkWuyn2lsiWRjE+CflwqTo8XHQCKLCKGbLJzR13i+ulos5ByjUV7OVPTZ241Lxaaw7JBgUgFP3BUqA0127pX8mxpm0=
9
+ - secure: MQLynyivQIoClPKv3mA62S3E3SVR1ho/8rQ3xs43fsT4PNClwftOO+fRiH0djkmZ4dzJSAD5H70ikcAJoOQ3dAul2+xA5uPAt4AUBk0sindcT2PeEnjPIH9rt/AxLYG67MWZihTr2xcQ38xh6nNJZslyFSglntCTFPmyBy3D0KM=
10
+ - secure: FrWAE8ZvvBnI6+VwxdBZIHQwQPQKOqFMP9g3XVMyJOPCF4HWlzBor1e5MZ9UquVYaL+/2OL0aDxhgN33y0YsX3/2c5Z25cPGglzE3VsPzRdzDqarwPEz/tEzTYG/bKKPIEI9q+cKQNnSBuMtk4EELBmOJ9iA8jPD0OCNgRedlRw=
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2014 Henk Meijer
3
+ Copyright (c) 2014 Henk Meijer, Eseks Media
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,6 +1,12 @@
1
- # DocData
1
+ # Docdata
2
+ [![Build Status](https://secure.travis-ci.org/henkm/docdata.png)](http://travis-ci.org/henkm/docdata)
3
+ [![Gem Version](https://badge.fury.io/rb/docdata.svg)](http://badge.fury.io/rb/docdata)
4
+ [![Code Climate](https://codeclimate.com/github/henkm/docdata/badges/gpa.svg)](https://codeclimate.com/github/henkm/docdata)
5
+ [![Coverage Status](https://coveralls.io/repos/henkm/docdata/badge.png?branch=master)](https://coveralls.io/r/henkm/docdata)
2
6
 
3
- DocData is a Ruby binder for DocData payments. Current status: in progress, not stable.
7
+ Docdata is a Ruby binder for Docdata Payments. Current status: **in progress, not stable**.
8
+
9
+ This gem relies on the awesom Savon gem to communicate with Docdata Payments' SOAP API.
4
10
 
5
11
  ## Installation
6
12
 
@@ -16,14 +22,174 @@ Or install it yourself as:
16
22
 
17
23
  $ gem install docdata
18
24
 
19
- ## Usage
25
+ ## Workflow
26
+ Each transaction consists of 2 - optionally 3 - parts:
27
+
28
+ - `Docdata::Shopper` (details about the shopper: name, email, etc.)
29
+ - `Docdata::Payment` (details about the payment: currency, gross amount, etc.)
30
+ - `Docdata::LineItem` (optionally list the products of this payment) **currently not working!**
31
+
32
+
33
+ The general workflow is as follows:
34
+
35
+ 1. Set up a `Docdata::Shopper` object with the details of your shopper: `@shopper = Docdata::Shopper.new`
36
+ 2. Set up a `Docdata::Payment` object with the details of your order: `@payment = Docdata::Payment.new(shopper: @shopper)`
37
+ 3. Call the `create` method (`@payment.create`)
38
+ 4. On success, store the payment key and use `@payment.redirect_url` to redirect the consumer to the transaction page.
39
+ 5. When the consumer gets back to your application, use the `Docdata::Payment.find("PA1M3NTK3Y").status.paid` to check if the order was paid for.
40
+
41
+ ## Parameters
42
+ All the payment details that Docdata Payments requires, are - obviously - also required to make payments via this gem.
43
+
44
+ #### Docdata::Shopper:
45
+ | Name | Type | Required | Defaults to |
46
+ |-----------|------------|---------|----|
47
+ | id | String (ID for own reference) | Yes | |
48
+ | first_name | String | Yes | First Name |
49
+ | last_name | String | Yes | Last Name |
50
+ | street | String | Yes | Main Street |
51
+ | house_number | String | Yes | 123 |
52
+ | postal_code | String | Yes | 2244 |
53
+ | city | String | Yes | City |
54
+ | country_code | String (ISO country code) | Yes | NL |
55
+ | language_code | String (ISO language code) | Yes | nl |
56
+ | email | String | Yes | random@example.com |
57
+
58
+ #### Docdata::Payment:
59
+ | Name | Type | Required |
60
+ |-----------|------------|---------|
61
+ | amount | Integer (amount in cents) | Yes |
62
+ | currency | String (ISO currency code) | Yes |
63
+ | order_reference | String (your own unique reference) | Yes |
64
+ | profile | String (name of your Docdata Payment profile)| Yes |
65
+ | shopper | Docdata::Shopper | Yes |
66
+ | line_items | Array (of Docdata::LineItem objects) | No |
67
+ | bank_id | String | No |
68
+ | prefered_payment_method | String | No |
69
+ | key | String (is availabel after successful 'create' action) | No (readonly)
70
+
71
+
72
+ ## Default values
73
+ A quick warning about the default values for the Shopper object: **For some payment methods, Docdata Payments needs the actual information in order for the payment to take place.**
74
+
75
+ If you use `GIROPAY`, `SEPA` and `AFTERPAY` this is the case. (Maybe also in other payment methods, please let me know!)
76
+
77
+ ## Example usage in Rails application
78
+ 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.).
79
+ ```ruby
80
+ # orders_controller.rb
81
+ def start_transaction
82
+ # find the order from your database
83
+ @order = Order.find(params[:id])
84
+
85
+ # initialize a shopper, use details from your order
86
+ shopper = Docdata::Shopper.new(first_name: @order.first_name, last_name: @order.last_name)
87
+
88
+ # set up a payment
89
+ @payment = Docdata::Payment.new(
90
+ amount: @order.total,
91
+ currency: @order.currency,
92
+ shopper: shopper,
93
+ profile: "My Default Profile",
94
+ order_reference: "order ##{@order.id}"
95
+ )
96
+
97
+ # create the payment via the docdata api and collect the result
98
+ result = @payment.create
99
+
100
+ if result.success?
101
+ # Set the transaction key for future reference
102
+ @order.update_column :docdata_key, result.key
103
+ # redirect the user to the docdata payment page
104
+ redirect_to @payment.redirect_url
105
+ else
106
+ # TODO: Display the error and warn the user that something went wrong.
107
+ end
108
+ end
109
+ ```
110
+
111
+ ## Ideal
112
+
113
+ For transactions in the Netherlands, iDeal is the most common option. To redirect a user directly to the bank page (skipping the Docdata web menu page), you can ask your user to choose a bank from any of the banks listed in the `Docdata::Ideal.banks` method.
114
+
115
+ 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
+
117
+ Example code:
118
+ ```ruby
119
+ # orders_controller.rb
120
+ def ideal_checkout
121
+ @order = Order.find(params[:order_id])
122
+ @banks = Docdata::Ideal.banks
123
+ end
124
+
125
+ def start_ideal_transaction
126
+ @order = Order.find(params[:order_id])
127
+
128
+ # initialize a shopper, use details from your order
129
+ shopper = Docdata::Shopper.new(first_name: @order.first_name, last_name: @order.last_name)
130
+
131
+ # set up a payment
132
+ @payment = Docdata::Payment.new(
133
+ amount: @order.total,
134
+ currency: @order.currency,
135
+ shopper: shopper,
136
+ profile: "My Default Profile",
137
+ order_reference: "order ##{@order.id}",
138
+ bank_id: params[:bank_id],
139
+ default_act: true # redirect directly to the bank, skipping the Docdata web menu
140
+ )
141
+
142
+ # create the payment via the docdata api and collect the result
143
+ result = @payment.create
144
+
145
+ if result.success?
146
+ # Set the transaction key for future reference
147
+ @order.update_column :docdata_key, result.key
148
+ # redirect the user to the bank page
149
+ redirect_to @payment.redirect_url
150
+ else
151
+ # TODO: Display the error and warn the user that something went wrong.
152
+ end
153
+ end
154
+ ```
155
+
156
+ View template (ideal_checkout.html.erb):
157
+
158
+ ```erb
159
+ <h2>Choose your bank</h2>
160
+ <%= form_tag start_ideal_transaction_path, method: :post, target: "_blank" do %>
161
+ <%= select_tag "bank_id", options_from_collection_for_select(@banks, "id", "name") %>
162
+ <%= hidden_field_tag :order_id, @order.id %>
163
+ <%= submit_tag "Proceed to checkout" %>
164
+ <% end %>
165
+ ```
166
+
167
+ ## Tips and samples
168
+
169
+ #### Redirect directly to bank page (skip Docdata web menu)
170
+ When making a new `Docdata::Payment`, use the `default_act` parameter to redirect consumers directly to the acquirers website. Example:
171
+
172
+ ```ruby
173
+ @payment = Docdata::Payment.new(
174
+ amount: @order.total,
175
+ currency: @order.currency,
176
+ shopper: shopper,
177
+ profile: "My Default Profile",
178
+ order_reference: "order ##{@order.id}",
179
+ bank_id: params[:bank_id],
180
+ default_act: true # redirect directly to the bank, skipping the Docdata web menu
181
+ )
182
+ ```
20
183
 
21
- TODO: Write usage instructions here
184
+ #### Retrieve a list of iDeal banks to show
185
+ `Docata::Ideal.banks` returns an Array.
22
186
 
23
187
  ## Contributing
24
188
 
25
189
  1. Fork it
26
190
  2. Create your feature branch (`git checkout -b my-new-feature`)
27
- 3. Commit your changes (`git commit -am 'Add some feature'`)
28
- 4. Push to the branch (`git push origin my-new-feature`)
29
- 5. Create new Pull Request
191
+ 3. Make changes, document them and add tests (rspec)
192
+ 4. Run the entire test suite and make sure all tests pass
193
+ 5. Commit your changes (`git commit -am 'Add some feature'`)
194
+ 6. Push to the branch (`git push origin my-new-feature`)
195
+ 7. Create new Pull Request
data/Rakefile CHANGED
@@ -1 +1,9 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new do |t|
5
+ t.pattern = "spec/*_spec.rb"
6
+ end
7
+
8
+ task :default => :spec
9
+ task :test => :spec
data/docdata.gemspec CHANGED
@@ -8,23 +8,30 @@ Gem::Specification.new do |spec|
8
8
  spec.version = Docdata::VERSION
9
9
  spec.authors = ["Henk Meijer", "Eskes Media"]
10
10
  spec.email = ["meijerhenk@gmail.com"]
11
- spec.description = %q{A ruby binder for the DocData payment gateway.}
12
- spec.summary = %q{This gem provides a ruby API for the DocData payment gateway.}
13
- spec.homepage = ""
11
+ spec.description = %q{A ruby binder for the Docdata Payment API.}
12
+ spec.summary = %q{This gem provides a ruby interface for the Docdata Payment API. You basically create a Payment object and receive a reirect_url back to take your users to the checkout page.}
13
+ spec.homepage = "http://rdoc.info/github/henkm/docdata/"
14
14
  spec.license = "MIT"
15
15
 
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler" #, "~> 1.3"
22
+ spec.add_development_dependency "rake"
16
23
  spec.add_development_dependency "rspec"
17
24
  spec.add_development_dependency "vcr"
18
25
  spec.add_development_dependency "fakeweb"
19
26
  spec.add_development_dependency "coveralls"
20
27
  spec.add_development_dependency "simplecov"
21
28
  spec.add_development_dependency "yard"
29
+ spec.add_development_dependency "rubyntlm"
22
30
 
23
- spec.files = `git ls-files`.split($/)
24
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
25
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
26
- spec.require_paths = ["lib"]
27
-
28
- spec.add_development_dependency "bundler", "~> 1.3"
29
- spec.add_development_dependency "rake"
30
- end
31
+ # spec.add_runtime_dependency 'savon', git: 'savonrb/savon'
32
+ spec.add_dependency 'savon', '~> 2.0'
33
+ spec.add_dependency 'nori'
34
+ spec.add_dependency 'veto'
35
+ spec.add_dependency 'nokogiri'
36
+ spec.add_dependency("railties")
37
+ end
data/lib/docdata.rb CHANGED
@@ -1,5 +1,78 @@
1
+ # Libraries
2
+ require 'ostruct'
3
+ require 'rails'
4
+ require 'savon'
5
+ require 'active_support/dependencies'
6
+ require 'active_support'
7
+ require 'open-uri'
8
+ require 'nokogiri'
9
+ require 'veto'
10
+
11
+
12
+ # Files
1
13
  require "docdata/version"
14
+ require "docdata/docdata_error"
15
+ require "docdata/shopper"
16
+ require "docdata/payment"
17
+ require "docdata/line_item"
18
+ require "docdata/response"
19
+ require "docdata/ideal"
20
+ require "docdata/bank"
2
21
 
22
+ include Savon
23
+
24
+ #
25
+ # Docdata Module
26
+ #
3
27
  module Docdata
4
- # Your code goes here...
28
+ API_VERSION = 1
29
+
30
+ # @return [String] Your DocData username
31
+ # @note The is a required parameter.
32
+ mattr_accessor :username
33
+ @@username = nil
34
+
35
+ # @return [String] Your DocData password
36
+ mattr_accessor :password
37
+ @@password = nil
38
+
39
+ # @return [Boolean] Test mode switch
40
+ mattr_accessor :test_mode
41
+ @@test_mode = true
42
+
43
+ # @param [String] Set the url of your website where docdata can send messages to
44
+ mattr_accessor :return_url
45
+ @@return_url = nil
46
+
47
+ # returns the version number
48
+ def self.version
49
+ VERSION
50
+ end
51
+
52
+ # sets up configuration
53
+ def self.setup
54
+ yield self
55
+ end
56
+
57
+ def self.url
58
+ if test_mode
59
+ "https://test.docdatapayments.com/ps/services/paymentservice/1_1?wsdl"
60
+ else
61
+ "https://www.docdatapayments.com/ps/services/paymentservice/1_1?wsdl"
62
+ end
63
+ end
64
+
65
+ # For testing purpose only: set the username and password
66
+ # in environment variables to make the tests pass with your test
67
+ # credentials.
68
+ def self.set_credentials_from_environment
69
+ self.password = ENV["DOCDATA_PASSWORD"]
70
+ self.username = ENV["DOCDATA_USERNAME"]
71
+ self.return_url = ENV["DOCDATA_RETURN_URL"]
72
+ end
73
+
74
+ def self.client
75
+ Savon.client(wsdl: url)
76
+ end
77
+
5
78
  end
@@ -0,0 +1,27 @@
1
+ module Docdata
2
+ #
3
+ # Object representing a "Bank" object with attributes provided by Mollie
4
+ #
5
+ # @example
6
+ # Bank.new({
7
+ # :id => "0031",
8
+ # :name => "ABN AMRO"
9
+ # })
10
+ class Bank
11
+ # @return [String] The id of the bank provided by Mollie.
12
+ attr_accessor :id
13
+ # @return [String] The name of the bank.
14
+ attr_accessor :name
15
+
16
+ #
17
+ # Initializer to transform a +Hash+ into an Bank object
18
+ #
19
+ # @param [Hash] values
20
+ def initialize(values=nil)
21
+ return if values.nil?
22
+
23
+ @id = values[:id].to_s
24
+ @name = values[:name].to_s
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,41 @@
1
+ #
2
+ # Configuration object for storing some parameters required for making transactions
3
+ #
4
+ module Docdata::Config
5
+ class << self
6
+ # @return [String] Your DocData username
7
+ # @note The is a required parameter.
8
+ attr_accessor :username
9
+ # @return [String] Your DocData password
10
+ attr_accessor :password
11
+ # @return [Boolean] Test mode switch
12
+ attr_accessor :test_mode
13
+
14
+
15
+ # Set's the default value's to nil and false
16
+ # @return [Hash] configuration options
17
+ def init!
18
+ @defaults = {
19
+ :@username => nil,
20
+ :@password => nil,
21
+ :@test_mode => true
22
+ }
23
+ end
24
+
25
+ # Resets the value's to there previous value (instance_variable)
26
+ # @return [Hash] configuration options
27
+ def reset!
28
+ @defaults.each { |key, value| instance_variable_set(key, value) }
29
+ end
30
+
31
+ # Set's the new value's as instance variables
32
+ # @return [Hash] configuration options
33
+ def update!
34
+ @defaults.each do |key, value|
35
+ instance_variable_set(key, value) unless instance_variable_defined?(key)
36
+ end
37
+ end
38
+ end
39
+ init!
40
+ reset!
41
+ end