rpostf 0.1.1

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.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Phil Hofmann <pho@panter.ch>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,27 @@
1
+ # Rpostf
2
+
3
+ Generate PostFinance (Swiss Post) URLs and vaildate responses.
4
+
5
+ * https://e-payment.postfinance.ch/
6
+
7
+ ## Example
8
+
9
+ pf = Rpostf.new(:login => 'your_login', :secret => 'your_secret', :local_host => 'your_domain')
10
+ p params = pf.params_for_post(:orderID => rand(1_000_000), :amount => 42)
11
+ p form = pf.form_for_post(:orderID => rand(1_000_000), :amount => 43)
12
+ p url = pf.url_for_get(:orderID => rand(1_000_000), :amount => 44)
13
+
14
+ ## Note on Patches/Pull Requests
15
+
16
+ * Fork the project.
17
+ * Make your feature addition or bug fix.
18
+ * Add tests for it. This is important so I don't break it in a
19
+ future version unintentionally.
20
+ * Commit, do not mess with rakefile, version, or history. (if you
21
+ want to have your own version, that is fine but bump version in a
22
+ commit by itself I can ignor e when I pull)
23
+ * Send me a pull request. Bonus points for topic branches.
24
+
25
+ ## Copyright
26
+
27
+ Copyright (c) 2010 Phil Hofmann <pho at panter dot ch>. See LICENSE for details.
@@ -0,0 +1,53 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "rpostf"
8
+ gem.summary = "PostFinance (Swiss Post) Payment Gateway API"
9
+ gem.description = "generate PostFinance (Swiss Post) URLs and vaildate responses"
10
+ gem.email = "phil@branch14.org"
11
+ gem.homepage = "http://github.com/branch14/rpostf"
12
+ gem.authors = ["Phil Hofmann"]
13
+ # gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/test_*.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ begin
29
+ require 'rcov/rcovtask'
30
+ Rcov::RcovTask.new do |test|
31
+ test.libs << 'test'
32
+ test.pattern = 'test/**/test_*.rb'
33
+ test.verbose = true
34
+ end
35
+ rescue LoadError
36
+ task :rcov do
37
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
+ end
39
+ end
40
+
41
+ task :test => :check_dependencies
42
+
43
+ task :default => :test
44
+
45
+ require 'rake/rdoctask'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "rpostf #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
@@ -0,0 +1,5 @@
1
+ class Hash
2
+ def reverse_merge!(other_hash)
3
+ replace(other_hash.merge!(self))
4
+ end
5
+ end
@@ -0,0 +1,162 @@
1
+ require 'logger'
2
+
3
+ require File.join(File.dirname(__FILE__), %w(string))
4
+ require File.join(File.dirname(__FILE__), %w(hash))
5
+
6
+ # Rpostf -- Ruby POST Finance
7
+ # a ruby library for the "Post Finance (SWISS POST)" payment gateway
8
+ #
9
+ # usage:
10
+ #
11
+ # pf = Rpostf.new(:login => 'asdf', :secret => 'xxxx', :local_host => 'http://bogus.net')
12
+ # url = pf.url_for_get(:orderID => bogus_id,
13
+ # :amount => suspicious_amount)
14
+ #
15
+ # # in rails something like
16
+ # form_tag url
17
+ #
18
+ # # or as a link
19
+ # link_to 'Checkout', url, :method => :post
20
+ #
21
+ # as of EPay Docs +url+ should be used in a form with POST and iso-8859-1
22
+ #
23
+ class Rpostf
24
+
25
+ class MissingParameter < StandardError
26
+
27
+ def initialize(param, logger=nil)
28
+ @param = param
29
+ @log = logger || Logger.new
30
+ end
31
+
32
+ def message
33
+ "You have to provide #{@param}."
34
+ end
35
+
36
+ end
37
+
38
+ DEFAULT_OPTIONS = {
39
+ :base_url => 'https://e-payment.postfinance.ch/ncol/test/orderdirect.asp',
40
+ #:base_url => 'https://e-payment.postfinance.ch/ncol/test/orderstandard.asp',
41
+ :locale => 'de_DE',
42
+ :currency => 'CHF',
43
+ :local_port => 80,
44
+ :local_protocol => 'https',
45
+ :local_route => '/postfinance_payments'
46
+ }
47
+
48
+ # mandatory keys for +options+ are
49
+ # +:login+
50
+ # +:secret+
51
+ # +:local_host+
52
+ #
53
+ # optional keys for +options+ are
54
+ # +:base_url+ default is ''
55
+ # +:language+ default is 'de_DE'
56
+ # +:currency+ default is 'CHF'
57
+ # +:local_port+ default is 80
58
+ # +:local_protocol+ default is 'https'
59
+ # +:locale_route+ default is '/postfinance_payments'
60
+ #
61
+ def initialize(options={})
62
+ check_keys options, :login, :secret, :local_host
63
+ @options = options.reverse_merge!(DEFAULT_OPTIONS)
64
+ end
65
+
66
+ # returns a string containing a url for a GET
67
+ #
68
+ # hands options over to params_for_post
69
+ def url_for_get(options={})
70
+ options = params_for_post(options)
71
+
72
+ parameters = []
73
+ options.each { |p| parameters << p*'=' }
74
+
75
+ [@options[:base_url], parameters*'&'].join('?')
76
+ end
77
+
78
+ # returns a hash containing the params for a POST
79
+ #
80
+ # mandatory keys for +options+ are
81
+ # +:orderID+
82
+ # +:amount+
83
+ #
84
+ # optionsl keys for +options+ are
85
+ # +:PSPID+
86
+ # +:currency+
87
+ # +:language+
88
+ # +:accepturl+
89
+ #
90
+ def params_for_post(options={})
91
+ check_keys options, :orderID, :amount
92
+
93
+ options.reverse_merge!({
94
+ :PSPID => @options[:login],
95
+ :currency => @options[:currency],
96
+ :language => @options[:locale],
97
+ :accepturl => [ @options[:local_protocol], '://',
98
+ @options[:local_host], ':',
99
+ @options[:local_port],
100
+ @options[:local_route] ]*''
101
+ })
102
+ options[:SHASign] = generate_signature(options)
103
+
104
+ options
105
+ end
106
+
107
+ # returns a string containing html markup
108
+ #
109
+ # hands options over to params_for_post
110
+ #
111
+ # +:submit_value+ is the caption of the submit button
112
+ def form_for_post(options={})
113
+ submit_value = options.delete(:submit_value) || 'Checkout with Post Finance'
114
+ options = params_for_post(options)
115
+ (["<form action=\"#{@options[:base_url]}\" method=\"post\">"] +
116
+ options.map { |n, v| hidden_field(n, v) } +
117
+ ["<input type=\"submit\" value=\"#{submit_value}\" />", '</form>']) * "\n"
118
+ end
119
+
120
+ # verifies a signature
121
+ def verify_signature(params)
122
+ keys = [:orderID, :currency, :amount, :PM, :ACCEPTANCE,
123
+ :STATUS, :CARDNO, :ALIAS, :PAYID, :NCERROR, :BRAND]
124
+ hash = (keys.map { |key| params[key] } << @options[:secret]).join('')
125
+ params[:SHASIGN] == hash.sha1
126
+ end
127
+
128
+ private
129
+
130
+ # generates a sha1 signature for the post finance url
131
+ def generate_signature(options)
132
+ [options[:orderID],
133
+ options[:amount],
134
+ [:currency, :login, :secret].map { |key| @options[:key]}
135
+ ].flatten.join('').sha1
136
+ end
137
+
138
+ # ensures that the passed options hash includes all mandatory keys
139
+ def check_keys(*args)
140
+ options = args.shift
141
+ args.each do |key|
142
+ raise MissingParameter.new(key) unless options.key?(key)
143
+ end
144
+ end
145
+
146
+ # build a hidden field html tag
147
+ def hidden_field(name, value)
148
+ "<input type=\"hidden\" name=\"#{name}\" value=\"#{value}\" />"
149
+ end
150
+
151
+ end
152
+
153
+ # examples
154
+ if $0 == __FILE__
155
+
156
+ pf = Rpostf.new(:login => 'your_login', :secret => 'your_secret', :local_host => 'your_domain')
157
+ p params = pf.params_for_post(:orderID => rand(1_000_000), :amount => 42)
158
+ puts form = pf.form_for_post(:orderID => rand(1_000_000), :amount => 43)
159
+ p url = pf.url_for_get(:orderID => rand(1_000_000), :amount => 44)
160
+
161
+ end
162
+
@@ -0,0 +1,7 @@
1
+ require 'digest/sha1'
2
+
3
+ class String
4
+ def sha1
5
+ Digest::SHA1.hexdigest(self).upcase
6
+ end
7
+ end
@@ -0,0 +1,53 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{rpostf}
8
+ s.version = "0.1.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Phil Hofmann"]
12
+ s.date = %q{2010-08-26}
13
+ s.description = %q{generate PostFinance (Swiss Post) URLs and vaildate responses}
14
+ s.email = %q{phil@branch14.org}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.md"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.md",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "lib/hash.rb",
27
+ "lib/rpostf.rb",
28
+ "lib/string.rb",
29
+ "rpostf.gemspec",
30
+ "test/helper.rb",
31
+ "test/test_rpostf.rb"
32
+ ]
33
+ s.homepage = %q{http://github.com/branch14/rpostf}
34
+ s.rdoc_options = ["--charset=UTF-8"]
35
+ s.require_paths = ["lib"]
36
+ s.rubygems_version = %q{1.3.6}
37
+ s.summary = %q{PostFinance (Swiss Post) Payment Gateway API}
38
+ s.test_files = [
39
+ "test/helper.rb",
40
+ "test/test_rpostf.rb"
41
+ ]
42
+
43
+ if s.respond_to? :specification_version then
44
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
45
+ s.specification_version = 3
46
+
47
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
48
+ else
49
+ end
50
+ else
51
+ end
52
+ end
53
+
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'rpostf'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,8 @@
1
+ require 'helper'
2
+
3
+ class TestRpostf < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ #flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ #pass
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rpostf
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 1
9
+ version: 0.1.1
10
+ platform: ruby
11
+ authors:
12
+ - Phil Hofmann
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-08-26 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: generate PostFinance (Swiss Post) URLs and vaildate responses
22
+ email: phil@branch14.org
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files:
28
+ - LICENSE
29
+ - README.md
30
+ files:
31
+ - .document
32
+ - .gitignore
33
+ - LICENSE
34
+ - README.md
35
+ - Rakefile
36
+ - VERSION
37
+ - lib/hash.rb
38
+ - lib/rpostf.rb
39
+ - lib/string.rb
40
+ - rpostf.gemspec
41
+ - test/helper.rb
42
+ - test/test_rpostf.rb
43
+ has_rdoc: true
44
+ homepage: http://github.com/branch14/rpostf
45
+ licenses: []
46
+
47
+ post_install_message:
48
+ rdoc_options:
49
+ - --charset=UTF-8
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ segments:
57
+ - 0
58
+ version: "0"
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ segments:
64
+ - 0
65
+ version: "0"
66
+ requirements: []
67
+
68
+ rubyforge_project:
69
+ rubygems_version: 1.3.6
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: PostFinance (Swiss Post) Payment Gateway API
73
+ test_files:
74
+ - test/helper.rb
75
+ - test/test_rpostf.rb