payments-pl 0.4.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.
@@ -0,0 +1,115 @@
1
+ require 'ostruct'
2
+
3
+ module Payments
4
+ class Pos
5
+ attr_reader :pos_id, :pos_auth_key, :key1, :key2, :type, :encoding
6
+
7
+ def initialize(options)
8
+ options.symbolize_keys!
9
+
10
+ @pos_id = options[:pos_id]
11
+ @pos_auth_key = options[:pos_auth_key]
12
+ @key1 = options[:key1]
13
+ @key2 = options[:key2]
14
+ @type = options[:type] || 'express_gateway'
15
+ @encoding = options[:encoding] || 'UTF'
16
+ end
17
+
18
+ def new_transaction(options = {})
19
+ options.stringify_keys!
20
+
21
+ options[:pos_id] = @pos_id
22
+ options[:pos_auth_key] = @pos_auth_key
23
+ options[:session_id] ||= (Time.now.to_f * 100).to_i
24
+
25
+ Transaction.new(options)
26
+ end
27
+
28
+ def new_transaction_url
29
+ if @type == 'express_gateway'
30
+ return "https://www.platnosci.pl/paygw/#{@encoding}/NewPayment"
31
+ elsif @type == 'sms_premium'
32
+ return "https://www.platnosci.pl/paygw/#{@encoding}/NewSMS"
33
+ else
34
+ return nil
35
+ end
36
+ end
37
+
38
+ def path_for(method)
39
+ case method
40
+ when :get then "/paygw/#{@encoding}/Payment/get/txt"
41
+ when :confirm then "/paygw/#{@encoding}/Payment/confirm/txt"
42
+ when :cancel then "/paygw/#{@encoding}/Payment/cancel/txt"
43
+ else nil
44
+ end
45
+ end
46
+
47
+ def encrypt(*params)
48
+ Digest::MD5.hexdigest(params.join)
49
+ end
50
+
51
+ def verify(t)
52
+ sig = nil
53
+ if t.trans_status
54
+ sig = encrypt(t.trans_pos_id, t.trans_session_id, t.trans_order_id, t.trans_status, t.trans_amount, t.trans_desc, t.trans_ts, @key2)
55
+ else
56
+ sig = encrypt(t.trans_pos_id, t.trans_session_id, t.trans_ts, @key2)
57
+ end
58
+ return sig == t.trans_sig
59
+ end
60
+
61
+ def get(session_id)
62
+ send_request(:get, session_id)
63
+ end
64
+
65
+ def confirm(session_id)
66
+ send_request(:confirm, session_id)
67
+ end
68
+
69
+ def cancel(session_id)
70
+ send_request(:cancel, session_id)
71
+ end
72
+
73
+ def send_request(method, session_id)
74
+ url = path_for(method)
75
+ data = prepare_data(session_id)
76
+ connection = Net::HTTP.new('www.platnosci.pl', 443)
77
+ connection.use_ssl = true
78
+
79
+ response = connection.start do |http|
80
+ post = Net::HTTP::Post.new(url)
81
+ post.set_form_data(data.stringify_keys)
82
+ http.request(post)
83
+ end
84
+
85
+ if response.code == '200'
86
+ t = parse_response_body(response.body)
87
+ if t.status == 'OK'
88
+ raise SignatureInvalid unless verify(t)
89
+ end
90
+ return [t.status, t]
91
+ else
92
+ raise RequestFailed
93
+ end
94
+ end
95
+
96
+ def prepare_data(session_id)
97
+ ts = (Time.now.to_f * 1000).to_i
98
+ sig = encrypt(@pos_id, session_id, ts, @key1)
99
+
100
+ {
101
+ 'pos_id' => @pos_id,
102
+ 'session_id' => session_id,
103
+ 'ts' => ts,
104
+ 'sig' => sig
105
+ }
106
+ end
107
+
108
+ def parse_response_body(body)
109
+ body.gsub!("\r", "")
110
+ pattern = /^(\w+):(?:[ ])?(.*)$/
111
+ data = body.scan(pattern)
112
+ OpenStruct.new(data)
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,45 @@
1
+ module Payments
2
+ class Transaction < ActiveRecord::Base
3
+ def self.columns
4
+ @columns ||=[]
5
+ end
6
+
7
+ def self.column(name, sql_type = nil, default = nil, null = true)
8
+ columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
9
+ end
10
+
11
+ column :pos_id, :integer
12
+ column :pos_auth_key, :string
13
+ column :pay_type, :string
14
+ column :session_id, :text
15
+ column :amount, :integer
16
+ column :desc, :text
17
+ column :order_id, :integer
18
+ column :desc2, :text
19
+ column :trs_desc, :string
20
+ column :first_name, :string
21
+ column :last_name, :string
22
+ column :street, :string
23
+ column :street_hn, :string
24
+ column :street_an, :string
25
+ column :city, :string
26
+ column :post_code, :string
27
+ column :country, :string
28
+ column :email, :string
29
+ column :phone, :string
30
+ column :language, :string
31
+ column :client_ip, :string
32
+ column :js, :string
33
+ column :payback_login, :string
34
+ column :sig, :string
35
+ column :ts, :string
36
+
37
+ def pos
38
+ Payments[pos_id]
39
+ end
40
+
41
+ def new_url
42
+ pos.new_transaction_url
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,18 @@
1
+ module Payments
2
+ module ViewHelpers
3
+ def transaction_hidden_fields(transaction)
4
+ html = ""
5
+
6
+ %w(pos_id pos_auth_key pay_type session_id amount desc
7
+ order_id desc2 trs_desc first_name last_name street street_hn
8
+ street_an city post_code country email phone language client_ip
9
+ js payback_login sig ts
10
+ ).each do |field|
11
+ value = transaction.send(field)
12
+ html << hidden_field_tag(field, value) unless value.blank?
13
+ end
14
+
15
+ html
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,84 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+
3
+ require 'payments/pos'
4
+ require 'payments/transaction'
5
+ require 'payments/view_helpers'
6
+
7
+ module Payments
8
+ ERRORS = {
9
+ 100 => 'Brak parametru pos_id',
10
+ 101 => 'Brak parametru session_id',
11
+ 102 => 'Brak parametru ts',
12
+ 103 => 'Brak parametru sig',
13
+ 104 => 'Brak parametru desc',
14
+ 105 => 'Brak parametru client_ip',
15
+ 106 => 'Brak parametru first_name',
16
+ 107 => 'Brak parametru last_name',
17
+ 108 => 'Brak parametru street',
18
+ 109 => 'Brak parametru city',
19
+ 110 => 'Brak parametru post_code',
20
+ 111 => 'Brak parametru amount',
21
+ 112 => 'Błędny numer konta bankowego',
22
+ 113 => 'Brak parameteru email',
23
+ 114 => 'Brak numeru telefonu',
24
+ 200 => 'Inny chwilowy błąd',
25
+ 201 => 'Inny chwilowy błąd bazy danych',
26
+ 202 => 'POS o podanym identyfikatorze jest zablokowany',
27
+ 203 => 'Niedozwolona wartość pay_type dla danego pos_id',
28
+ 204 => 'Podana metoda płatności (wartość pay_type) jest chwilowo zablokowana dla danego pos_id, np. przerwa konserwacyjna bramki płatniczej',
29
+ 205 => 'Kwota transakcji mniejsza od wartości minimalnej',
30
+ 206 => 'Kwota transakcji większa od wartości maksymalnej',
31
+ 207 => 'Przekroczona wartość wszystkich transakcji dla jednego klienta w ostatnim przedziale czasowym',
32
+ 208 => 'POS dziala w wariancie ExpressPayment lecz nie nastąpiła aktywacja tego wariantu współpracy (czekamy na zgodę działu obsługi klienta)',
33
+ 209 => 'Błędny numer pos id lub pos auth key',
34
+ 500 => 'Transakcja nie istnieje',
35
+ 501 => 'Brak autoryzacji dla danej transakcji',
36
+ 502 => 'Transakcja rozpoczęta wcześniej',
37
+ 503 => 'Autoryzacja do transakcji była juz przeprowadzana',
38
+ 504 => 'Transakcja anulowana wczesniej',
39
+ 505 => 'Transakcja przekazana do odbioru wcześniej',
40
+ 506 => 'Transakcja już odebrana',
41
+ 507 => 'Błąd podczas zwrotu środków do klienta',
42
+ 599 => 'Błędny stan transakcji, np. nie można uznać transakcji kilka razy lub inny, prosimy o kontakt',
43
+ 999 => 'Inny błąd krytyczny - prosimy o kontakt'
44
+ }
45
+
46
+ @@pos_table = {}
47
+
48
+ class SignatureInvalid < StandardError; end
49
+ class PosNotFound < StandardError; end
50
+ class RequestFailed < StandardError; end
51
+
52
+ class << self
53
+ def init
54
+ config = YAML.load_file(File.join(RAILS_ROOT, 'config', 'payments.yml'))
55
+ config.each do |k, v|
56
+ pos = Pos.new(v)
57
+ @@pos_table[k] = pos
58
+ end
59
+ end
60
+
61
+ def [](name_or_id)
62
+ get_pos_by_name(name_or_id) || get_pos_by_id(name_or_id) || raise(PosNotFound)
63
+ end
64
+
65
+ def get_pos_by_name(name)
66
+ @@pos_table[name]
67
+ end
68
+
69
+ def get_pos_by_id(id)
70
+ id = id.to_i
71
+ @@pos_table.each do |k, v|
72
+ return v if v.pos_id == id
73
+ end
74
+ nil
75
+ end
76
+
77
+ def error_text(error_code)
78
+ ERRORS[error_code.to_i]
79
+ end
80
+ end
81
+ end
82
+
83
+ Payments.init
84
+ ActionView::Base.send(:include, Payments::ViewHelpers)
@@ -0,0 +1,78 @@
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{payments-pl}
8
+ s.version = "0.4.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Micha\305\202 M\305\202o\305\272niak"]
12
+ s.date = %q{2010-08-17}
13
+ s.description = %q{Simple gem for payments via platnosci.pl}
14
+ s.email = %q{m.mlozniak@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "doc/Payments.html",
27
+ "doc/Payments/Pos.html",
28
+ "doc/Payments/PosNotFound.html",
29
+ "doc/Payments/RequestFailed.html",
30
+ "doc/Payments/SignatureInvalid.html",
31
+ "doc/Payments/Transaction.html",
32
+ "doc/Payments/ViewHelpers.html",
33
+ "doc/_index.html",
34
+ "doc/class_list.html",
35
+ "doc/css/common.css",
36
+ "doc/css/full_list.css",
37
+ "doc/css/style.css",
38
+ "doc/file.README.html",
39
+ "doc/file_list.html",
40
+ "doc/frames.html",
41
+ "doc/index.html",
42
+ "doc/js/app.js",
43
+ "doc/js/full_list.js",
44
+ "doc/js/jquery.js",
45
+ "doc/method_list.html",
46
+ "doc/top-level-namespace.html",
47
+ "lib/payments/pos.rb",
48
+ "lib/payments/transaction.rb",
49
+ "lib/payments/view_helpers.rb",
50
+ "lib/payments_pl.rb",
51
+ "payments-pl.gemspec",
52
+ "test/helper.rb",
53
+ "test/test_payments-pl.rb"
54
+ ]
55
+ s.homepage = %q{http://github.com/ronin/payments-pl}
56
+ s.rdoc_options = ["--charset=UTF-8"]
57
+ s.require_paths = ["lib"]
58
+ s.rubygems_version = %q{1.3.7}
59
+ s.summary = %q{Simple gem for payments via platnosci.pl}
60
+ s.test_files = [
61
+ "test/test_payments-pl.rb",
62
+ "test/helper.rb"
63
+ ]
64
+
65
+ if s.respond_to? :specification_version then
66
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
67
+ s.specification_version = 3
68
+
69
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
70
+ s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
71
+ else
72
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
73
+ end
74
+ else
75
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
76
+ end
77
+ end
78
+
data/test/helper.rb ADDED
@@ -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 'payments-pl'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestPaymentsPl < 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
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: payments-pl
3
+ version: !ruby/object:Gem::Version
4
+ hash: 15
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 4
9
+ - 0
10
+ version: 0.4.0
11
+ platform: ruby
12
+ authors:
13
+ - !binary |
14
+ TWljaGHFgiBNxYJvxbpuaWFr
15
+
16
+ autorequire:
17
+ bindir: bin
18
+ cert_chain: []
19
+
20
+ date: 2010-08-17 00:00:00 +02:00
21
+ default_executable:
22
+ dependencies:
23
+ - !ruby/object:Gem::Dependency
24
+ name: thoughtbot-shoulda
25
+ prerelease: false
26
+ requirement: &id001 !ruby/object:Gem::Requirement
27
+ none: false
28
+ requirements:
29
+ - - ">="
30
+ - !ruby/object:Gem::Version
31
+ hash: 3
32
+ segments:
33
+ - 0
34
+ version: "0"
35
+ type: :development
36
+ version_requirements: *id001
37
+ description: Simple gem for payments via platnosci.pl
38
+ email: m.mlozniak@gmail.com
39
+ executables: []
40
+
41
+ extensions: []
42
+
43
+ extra_rdoc_files:
44
+ - LICENSE
45
+ - README.rdoc
46
+ files:
47
+ - .document
48
+ - .gitignore
49
+ - LICENSE
50
+ - README.rdoc
51
+ - Rakefile
52
+ - VERSION
53
+ - doc/Payments.html
54
+ - doc/Payments/Pos.html
55
+ - doc/Payments/PosNotFound.html
56
+ - doc/Payments/RequestFailed.html
57
+ - doc/Payments/SignatureInvalid.html
58
+ - doc/Payments/Transaction.html
59
+ - doc/Payments/ViewHelpers.html
60
+ - doc/_index.html
61
+ - doc/class_list.html
62
+ - doc/css/common.css
63
+ - doc/css/full_list.css
64
+ - doc/css/style.css
65
+ - doc/file.README.html
66
+ - doc/file_list.html
67
+ - doc/frames.html
68
+ - doc/index.html
69
+ - doc/js/app.js
70
+ - doc/js/full_list.js
71
+ - doc/js/jquery.js
72
+ - doc/method_list.html
73
+ - doc/top-level-namespace.html
74
+ - lib/payments/pos.rb
75
+ - lib/payments/transaction.rb
76
+ - lib/payments/view_helpers.rb
77
+ - lib/payments_pl.rb
78
+ - payments-pl.gemspec
79
+ - test/helper.rb
80
+ - test/test_payments-pl.rb
81
+ has_rdoc: true
82
+ homepage: http://github.com/ronin/payments-pl
83
+ licenses: []
84
+
85
+ post_install_message:
86
+ rdoc_options:
87
+ - --charset=UTF-8
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ hash: 3
96
+ segments:
97
+ - 0
98
+ version: "0"
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ hash: 3
105
+ segments:
106
+ - 0
107
+ version: "0"
108
+ requirements: []
109
+
110
+ rubyforge_project:
111
+ rubygems_version: 1.3.7
112
+ signing_key:
113
+ specification_version: 3
114
+ summary: Simple gem for payments via platnosci.pl
115
+ test_files:
116
+ - test/test_payments-pl.rb
117
+ - test/helper.rb