docdata 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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