tbk 1.0.1 → 1.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.
@@ -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: