tbk 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,169 @@
1
+ module TBK
2
+ module Webpay
3
+ class Payment
4
+ attr_accessor :commerce
5
+ attr_accessor :request_ip
6
+ attr_accessor :amount
7
+ attr_accessor :order_id
8
+ attr_accessor :session_id
9
+ attr_accessor :confirmation_url
10
+ attr_accessor :success_url
11
+ attr_accessor :failure_url
12
+
13
+ def initialize(options = {})
14
+ self.commerce = options[:commerce] || TBK::Commerce.default_commerce
15
+ self.request_ip = options[:request_ip]
16
+ self.amount = options[:amount]
17
+ self.order_id = options[:order_id]
18
+ self.session_id = options[:session_id]
19
+ self.confirmation_url = options[:confirmation_url]
20
+ self.success_url = options[:success_url]
21
+ self.failure_url = options[:failure_url]
22
+ end
23
+
24
+ # Transaction ids are generated randombly on the client side
25
+ def transaction_id
26
+ @transaction_id ||= (rand * 10000000000).to_i
27
+ end
28
+
29
+ def redirect_url
30
+ "#{ self.process_url }?TBK_VERSION_KCC=#{ TBK::VERSION::KCC }&TBK_TOKEN=#{ self.token }"
31
+ end
32
+
33
+ def to_html_form(options = {}, &block)
34
+ form = <<-EOF
35
+ <form method="POST"
36
+ class="#{ options[:class] || 'tbk_payment_form'}"
37
+ id="#{ options[:id] }"
38
+ action="#{ self.process_url }">
39
+ <input type="hidden" name="TBK_PARAM" value="#{ self.param }">
40
+ <input type="hidden" name="TBK_VERSION_KCC" value="#{ TBK::VERSION::KCC }">
41
+ <input type="hidden" name="TBK_CODIGO_COMERCIO" value="#{ self.commerce.id }">
42
+ <input type="hidden" name="TBK_KEY_ID" value="#{ self.commerce.webpay_key_id }">
43
+ #{ yield if block_given? }
44
+ </form>
45
+ EOF
46
+
47
+ form = form.html_safe if form.respond_to? :html_safe
48
+
49
+ form
50
+ end
51
+
52
+ def token
53
+ unless @token
54
+ @token = fetch_token
55
+ TBK::Webpay.logger.payment(self)
56
+ end
57
+
58
+ @token
59
+ end
60
+
61
+ protected
62
+ def process_url
63
+ if self.commerce.test?
64
+ "https://certificacion.webpay.cl:6443/filtroUnificado/bp_revision.cgi"
65
+ else
66
+ "https://webpay.transbank.cl:443/filtroUnificado/bp_revision.cgi"
67
+ end
68
+ end
69
+
70
+ def validation_url
71
+ if self.commerce.test?
72
+ "https://certificacion.webpay.cl:6443/filtroUnificado/bp_validacion.cgi"
73
+ else
74
+ "https://webpay.transbank.cl:443/filtroUnificado/bp_validacion.cgi"
75
+ end
76
+ end
77
+
78
+ def fetch_token
79
+ uri = URI.parse( self.validation_url )
80
+
81
+ response = nil
82
+ until response && response['location'].nil?
83
+ uri = URI.parse( response.nil? ? self.validation_url : response['location'] )
84
+
85
+ response = Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
86
+ post = Net::HTTP::Post.new uri.path
87
+ post["user-agent"] = "TBK/#{ TBK::VERSION::GEM } (Ruby/#{ RUBY_VERSION }; +#{ TBK::VERSION::WEBSITE })"
88
+ post.set_form_data({
89
+ 'TBK_VERSION_KCC' => TBK::VERSION::KCC,
90
+ 'TBK_CODIGO_COMERCIO' => self.commerce.id,
91
+ 'TBK_KEY_ID' => self.commerce.webpay_key_id,
92
+ 'TBK_PARAM' => self.param
93
+ })
94
+
95
+ # http.read_timeout = Webpay::Config.timeout
96
+ http.request post
97
+ end
98
+ end
99
+
100
+ unless response.code == "200"
101
+ raise TBK::Webpay::PaymentError, "Payment token generation failed"
102
+ end
103
+
104
+ response = self.commerce.webpay_decrypt(response.body)[:body]
105
+
106
+ unless /ERROR=([a-zA-Z0-9]+)/.match(response)[1] == "0"
107
+ raise TBK::Webpay::PaymentError, "Payment token generation failed"
108
+ end
109
+
110
+ /TOKEN=([a-zA-Z0-9]+)/.match(response)[1]
111
+ end
112
+
113
+
114
+ def param
115
+ @param ||= begin
116
+ self.verify!
117
+ self.commerce.webpay_encrypt(raw_params)
118
+ end
119
+ end
120
+
121
+ def verify!
122
+ raise TBK::Webpay::PaymentError, "Commerce required" if self.commerce.nil?
123
+ raise TBK::Webpay::PaymentError, "Invalid amount (#{self.amount.inspect})" unless self.amount && self.amount > 0
124
+ raise TBK::Webpay::PaymentError, "Order ID required" if self.order_id.nil?
125
+ raise TBK::Webpay::PaymentError, "Success URL required" if self.success_url.nil?
126
+ raise TBK::Webpay::PaymentError, "Confirmation URL required" if self.confirmation_url.nil?
127
+ confirmation_uri = URI.parse(self.confirmation_url)
128
+ raise TBK::Webpay::PaymentError, "Confirmation URL host MUST be an IP address" unless /(\d{1,3}\.){3}\d{1,3}/.match(confirmation_uri.host)
129
+ raise TBK::Webpay::PaymentError, "Confirmation URL port MUST be 80 or 8080" unless [80, 8080].include?(confirmation_uri.port)
130
+ end
131
+
132
+ def raw_params(splitter="#", include_pseudomac=true)
133
+ params = []
134
+
135
+ params << "TBK_ORDEN_COMPRA=#{ self.order_id }"
136
+ params << "TBK_CODIGO_COMERCIO=#{ self.commerce.id }"
137
+ params << "TBK_ID_TRANSACCION=#{ self.transaction_id }"
138
+
139
+ uri = URI.parse(self.confirmation_url)
140
+
141
+ params << "TBK_URL_CGI_COMERCIO=#{ uri.path }"
142
+ params << "TBK_SERVIDOR_COMERCIO=#{ uri.host }"
143
+ params << "TBK_PUERTO_COMERCIO=#{ uri.port }"
144
+
145
+ params << "TBK_VERSION_KCC=#{ TBK::VERSION::KCC }"
146
+ params << "TBK_KEY_ID=#{ self.commerce.webpay_key_id }"
147
+ params << "PARAMVERIFCOM=1"
148
+
149
+ if include_pseudomac
150
+ # An old pseudo mac generation carried from an old implementation
151
+ digest = OpenSSL::Digest::MD5.new
152
+ digest << self.raw_params('&',false) << self.commerce.id.to_s << "webpay"
153
+ mac = digest.to_s
154
+
155
+ params << "TBK_MAC=#{ mac }"
156
+ end
157
+
158
+
159
+ params << "TBK_MONTO=#{ (self.amount * 100).to_i }"
160
+ params << "TBK_ID_SESION=#{ self.session_id }" if self.session_id
161
+ params << "TBK_URL_EXITO=#{ self.success_url }"
162
+ params << "TBK_URL_FRACASO=#{ self.failure_url || self.success_url }"
163
+ params << "TBK_TIPO_TRANSACCION=TR_NORMAL"
164
+
165
+ params.join(splitter)
166
+ end
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe TBK::Commerce do
4
+ context "creation" do
5
+ it "can be done with all it's arguments" do
6
+ @commerce = TBK::Commerce.new({
7
+ :id => 12345,
8
+ :key => TBK::Commerce::TEST_COMMERCE_KEY
9
+ })
10
+
11
+ expect(@commerce.id).to be_eql 12345
12
+ end
13
+
14
+ it "raises an exception if no id is given" do
15
+ expect{
16
+ TBK::Commerce.new({
17
+ :key => TBK::Commerce::TEST_COMMERCE_KEY
18
+ })
19
+ }.to raise_error TBK::CommerceError
20
+ end
21
+
22
+ it "raises an exception if no key is given" do
23
+ expect{
24
+ TBK::Commerce.new({
25
+ :id => 12345
26
+ })
27
+ }.to raise_error TBK::CommerceError
28
+ end
29
+
30
+ end
31
+
32
+ context "default_commerce" do
33
+ it "should be nil if no default is configured" do
34
+ TBK.config.should_receive(:commerce_id).and_return nil
35
+ expect(TBK::Commerce.default_commerce).to be_nil
36
+ end
37
+
38
+ it "should return a valid commerce if configured" do
39
+ TBK.config.should_receive(:commerce_id).at_least(:once).and_return 12345
40
+ TBK.config.should_receive(:commerce_key).at_least(:once).and_return TBK::Commerce::TEST_COMMERCE_KEY
41
+
42
+ expect(TBK::Commerce.default_commerce).not_to be_nil
43
+ expect(TBK::Commerce.default_commerce.id).to be_eql 12345
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ describe TBK::Config do
4
+
5
+ it "should inject configuration methods on base module" do
6
+
7
+ expect(TBK).to respond_to :configure
8
+ expect(TBK).to respond_to :config
9
+ expect(TBK.config).to be_kind_of TBK::Config
10
+
11
+ TBK.configure do |config|
12
+ expect(config).to be_kind_of TBK::Config
13
+ expect(config).to be == TBK.config
14
+ end
15
+
16
+ end
17
+
18
+ context('#commerce_id') do
19
+ it "should be nil by default" do
20
+ expect(TBK.config.commerce_id).to be_nil
21
+ end
22
+
23
+ it "should read it's default value from the environment" do
24
+ ENV.should_receive(:[]).with('TBK_COMMERCE_ID').and_return "12345"
25
+
26
+ expect(TBK.config.commerce_id).to be_eql "12345"
27
+ end
28
+ end
29
+
30
+ context('#commerce_key') do
31
+ it "should be nil by default" do
32
+ expect(TBK.config.commerce_key).to be_nil
33
+ end
34
+
35
+ it "should read it's default value from the environment" do
36
+ ENV.should_receive(:[]).with('TBK_COMMERCE_KEY').and_return "PKEY"
37
+
38
+ expect(TBK.config.commerce_key).to be_eql "PKEY"
39
+ end
40
+ end
41
+
42
+ context('#environment') do
43
+ it "should be production by default" do
44
+ expect(TBK.config.environment).to be_eql :production
45
+ end
46
+
47
+ it "should read it's default value from the environment" do
48
+ ENV.should_receive(:[]).with('TBK_COMMERCE_ENVIRONMENT').and_return "test"
49
+
50
+ expect(TBK.config.environment).to be_eql :test
51
+ end
52
+ end
53
+
54
+ end
@@ -0,0 +1,8 @@
1
+ require 'bundler/setup'
2
+
3
+ require "codeclimate-test-reporter"
4
+ CodeClimate::TestReporter.start
5
+
6
+ require 'tbk'
7
+
8
+ Dir["spec/support/**/*.rb"].each { |f| require File.expand_path(f) }
@@ -0,0 +1,5 @@
1
+ RSpec.configure do |config|
2
+ config.expect_with :rspec do |expect|
3
+ expect.syntax = :expect
4
+ end
5
+ end
@@ -0,0 +1,12 @@
1
+ module TestCommerce
2
+ def test_commerce
3
+ @test_commerce ||= TBK::Commerce.new({
4
+ :id => 597026007976,
5
+ :test => true
6
+ })
7
+ end
8
+ end
9
+
10
+ RSpec.configure do |config|
11
+ config.include TestCommerce
12
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe TBK::Webpay::Confirmation do
4
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe TBK::Webpay::Encryption do
4
+ end
@@ -0,0 +1 @@
1
+ require 'spec_helper'
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'tbk/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "tbk"
8
+ gem.version = TBK::VERSION::GEM
9
+ gem.authors = ["Seba Gamboa"]
10
+ gem.email = ["me@sagmor.com"]
11
+ gem.description = %q{Ruby implementation of Transbank's Webpay protocol}
12
+ gem.summary = "Pure Ruby implementation of Transbank's Webpay KCC #{TBK::VERSION::KCC}"
13
+ gem.homepage = TBK::VERSION::WEBSITE
14
+
15
+ gem.files = `git ls-files`.split($/).grep(%r{^(?!example)})
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_development_dependency "tzinfo"
21
+ gem.add_development_dependency "rake"
22
+ gem.add_development_dependency "rspec"
23
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tbk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Seba Gamboa
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-31 00:00:00.000000000 Z
11
+ date: 2014-08-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tzinfo
@@ -58,7 +58,40 @@ email:
58
58
  executables: []
59
59
  extensions: []
60
60
  extra_rdoc_files: []
61
- files: []
61
+ files:
62
+ - ".gitignore"
63
+ - ".travis.yml"
64
+ - ".yardopts"
65
+ - Gemfile
66
+ - LICENSE
67
+ - README.md
68
+ - Rakefile
69
+ - lib/tbk.rb
70
+ - lib/tbk/commerce.rb
71
+ - lib/tbk/config.rb
72
+ - lib/tbk/errors.rb
73
+ - lib/tbk/keys.rb
74
+ - lib/tbk/keys/test_commerce.pem
75
+ - lib/tbk/keys/webpay.101.pem
76
+ - lib/tbk/keys/webpay_test.101.pem
77
+ - lib/tbk/version.rb
78
+ - lib/tbk/webpay.rb
79
+ - lib/tbk/webpay/confirmation.rb
80
+ - lib/tbk/webpay/encryption.rb
81
+ - lib/tbk/webpay/logger.rb
82
+ - lib/tbk/webpay/logger/base_logger.rb
83
+ - lib/tbk/webpay/logger/null_logger.rb
84
+ - lib/tbk/webpay/logger/official_logger.rb
85
+ - lib/tbk/webpay/payment.rb
86
+ - spec/commerce_spec.rb
87
+ - spec/config_spec.rb
88
+ - spec/spec_helper.rb
89
+ - spec/support/syntax.rb
90
+ - spec/support/test_commerce.rb
91
+ - spec/webpay/confirmation_spec.rb
92
+ - spec/webpay/encryption_spec.rb
93
+ - spec/webpay/payment_spec.rb
94
+ - tbk.gemspec
62
95
  homepage: http://sagmor.com/tbk/
63
96
  licenses: []
64
97
  metadata: {}
@@ -82,5 +115,13 @@ rubygems_version: 2.2.2
82
115
  signing_key:
83
116
  specification_version: 4
84
117
  summary: Pure Ruby implementation of Transbank's Webpay KCC 6.0
85
- test_files: []
118
+ test_files:
119
+ - spec/commerce_spec.rb
120
+ - spec/config_spec.rb
121
+ - spec/spec_helper.rb
122
+ - spec/support/syntax.rb
123
+ - spec/support/test_commerce.rb
124
+ - spec/webpay/confirmation_spec.rb
125
+ - spec/webpay/encryption_spec.rb
126
+ - spec/webpay/payment_spec.rb
86
127
  has_rdoc: