tbk 0.9.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ed84e878638587bca89dbd61ce4509f4f7a5e6e5
4
+ data.tar.gz: 822749bd08deb1dec461465193ba1e8abbe93856
5
+ SHA512:
6
+ metadata.gz: 818be864649b81752e4bb026755bed2240db4ef3bc56e9e71e0e7c004e1acdfbd955a389daf58ab5ea4f29a7d3949beddda2cd1d57115bc7907fe3032679c3ee
7
+ data.tar.gz: 912e0e1f95cba893df563b6adfb1f49e35a4a68b05f3b1f380f9e6dfebad708c93e061c98f86e1aca4488f819464eca55f6e793d6953286a6e30da87ed7e10b3
metadata CHANGED
@@ -1,62 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tbk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
5
- prerelease:
4
+ version: 1.0.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Seba Gamboa
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-01-29 00:00:00.000000000 Z
11
+ date: 2014-03-28 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: tzinfo
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - '>='
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rake
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - '>='
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - '>='
44
39
  - !ruby/object:Gem::Version
45
40
  version: '0'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: rspec
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - '>='
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - '>='
60
53
  - !ruby/object:Gem::Version
61
54
  version: '0'
62
55
  description: Ruby implementation of Transbank's Webpay protocol
@@ -65,73 +58,29 @@ email:
65
58
  executables: []
66
59
  extensions: []
67
60
  extra_rdoc_files: []
68
- files:
69
- - .gitignore
70
- - .travis.yml
71
- - .yardopts
72
- - Gemfile
73
- - LICENSE
74
- - README.md
75
- - Rakefile
76
- - lib/tbk.rb
77
- - lib/tbk/commerce.rb
78
- - lib/tbk/config.rb
79
- - lib/tbk/errors.rb
80
- - lib/tbk/keys.rb
81
- - lib/tbk/keys/test_commerce.pem
82
- - lib/tbk/keys/webpay.101.pem
83
- - lib/tbk/keys/webpay_test.101.pem
84
- - lib/tbk/version.rb
85
- - lib/tbk/webpay.rb
86
- - lib/tbk/webpay/confirmation.rb
87
- - lib/tbk/webpay/encryption.rb
88
- - lib/tbk/webpay/payment.rb
89
- - spec/commerce_spec.rb
90
- - spec/config_spec.rb
91
- - spec/spec_helper.rb
92
- - spec/support/syntax.rb
93
- - spec/support/test_commerce.rb
94
- - spec/webpay/confirmation_spec.rb
95
- - spec/webpay/encryption_spec.rb
96
- - spec/webpay/payment_spec.rb
97
- - tbk.gemspec
61
+ files: []
98
62
  homepage: http://sagmor.com/tbk/
99
63
  licenses: []
64
+ metadata: {}
100
65
  post_install_message:
101
66
  rdoc_options: []
102
67
  require_paths:
103
68
  - lib
104
69
  required_ruby_version: !ruby/object:Gem::Requirement
105
- none: false
106
70
  requirements:
107
- - - ! '>='
71
+ - - '>='
108
72
  - !ruby/object:Gem::Version
109
73
  version: '0'
110
- segments:
111
- - 0
112
- hash: 4580346204296967975
113
74
  required_rubygems_version: !ruby/object:Gem::Requirement
114
- none: false
115
75
  requirements:
116
- - - ! '>='
76
+ - - '>='
117
77
  - !ruby/object:Gem::Version
118
78
  version: '0'
119
- segments:
120
- - 0
121
- hash: 4580346204296967975
122
79
  requirements: []
123
80
  rubyforge_project:
124
- rubygems_version: 1.8.23
81
+ rubygems_version: 2.0.14
125
82
  signing_key:
126
- specification_version: 3
83
+ specification_version: 4
127
84
  summary: Pure Ruby implementation of Transbank's Webpay KCC 6.0
128
- test_files:
129
- - spec/commerce_spec.rb
130
- - spec/config_spec.rb
131
- - spec/spec_helper.rb
132
- - spec/support/syntax.rb
133
- - spec/support/test_commerce.rb
134
- - spec/webpay/confirmation_spec.rb
135
- - spec/webpay/encryption_spec.rb
136
- - spec/webpay/payment_spec.rb
85
+ test_files: []
137
86
  has_rdoc:
data/.gitignore DELETED
@@ -1,19 +0,0 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .rspec
5
- .rvmrc
6
- .config
7
- .yardoc
8
- Gemfile.lock
9
- InstalledFiles
10
- _yardoc
11
- coverage
12
- doc/
13
- lib/bundler/man
14
- pkg
15
- rdoc
16
- spec/reports
17
- test/tmp
18
- test/version_tmp
19
- tmp
@@ -1,9 +0,0 @@
1
- language: ruby
2
- bundler_args: --without docs
3
- rvm:
4
- - 1.9.3
5
- - 1.8.7
6
- - jruby-18mode # JRuby in 1.8 mode
7
- - jruby-19mode # JRuby in 1.9 mode
8
- - rbx-18mode
9
- - rbx-19mode
data/.yardopts DELETED
@@ -1,5 +0,0 @@
1
- --no-private
2
- --hide-void-return
3
-
4
- --markup=markdown
5
- --markup-provider=redcarpet
data/Gemfile DELETED
@@ -1,13 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in tbk.gemspec
4
- gemspec
5
-
6
- platforms :jruby do
7
- gem "jruby-openssl"
8
- end
9
-
10
- group :docs do
11
- gem 'yard'
12
- gem 'redcarpet'
13
- end
data/LICENSE DELETED
@@ -1,20 +0,0 @@
1
- Copyright (c) 2013 Seba Gamboa
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.
data/README.md DELETED
@@ -1,101 +0,0 @@
1
- ### About
2
- [![Gem Version](https://badge.fury.io/rb/tbk.png)](http://badge.fury.io/rb/tbk)
3
- [![Build Status](https://travis-ci.org/sagmor/tbk.png)](https://travis-ci.org/sagmor/tbk)
4
- [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/sagmor/tbk)
5
-
6
- This is a pure ruby replacement of Transbank's Binary Integration Kit (aka. KCC)
7
- developed to simplify the integration with it's payment gateway Webpay.
8
-
9
-
10
- ### Disclaimer
11
-
12
- This library is not developed, supported nor endorsed in any way by Transbank S.A.
13
- and is the result of reverse engineering Transbank's Integration Kit (aka. KCC)
14
- for interoperability purposes as allowed by
15
- [Chilean Law 20.435 Article 71 Ñ Section b](http://www.leychile.cl/Navegar?idNorma=1012827)
16
-
17
- ### Usage
18
-
19
- Add this line to your application's Gemfile:
20
-
21
- ```ruby
22
- gem 'tbk'
23
- ```
24
-
25
- Configure your commerce
26
-
27
- ```ruby
28
- TBK.configure do |config|
29
- config.commerce_id YOUR_COMMERCE_ID
30
- config.commerce_key YOUR_RSA_KEY
31
- end
32
- ```
33
-
34
- To start a payment from your application
35
-
36
- ```ruby
37
- class WebpayController < ApplicationController
38
-
39
- # ...
40
-
41
- # Start a payment
42
- def pay
43
- # Setup the payment
44
- @payment = TBK::Webpay::Payment.new({
45
- amount: ORDER_AMOUNT,
46
- order_id: ORDER_ID,
47
- success_url: webpay_success_url,
48
- # Webpay can only access the HTTP protocol to a direct IP address (keep that in mind)
49
- confirmation_url: webpay_confirmation_url(host: SERVER_IP_ADDRESS, protocol: 'http'),
50
-
51
- # Optionaly supply:
52
- session_id: SOME_SESSION_VALUE,
53
- failure_url: webpay_failure_url # success_url is used by default
54
- })
55
-
56
- # Redirect the user to Webpay
57
- redirect_to @payment.redirect_url
58
- end
59
-
60
- # ...
61
- end
62
- ```
63
-
64
- And to process a payment
65
-
66
- ```ruby
67
- class WebpayController < ApplicationController
68
-
69
- # ...
70
-
71
- # Confirmation callback executed from Webpay servers
72
- def confirmation
73
- # Read the confirmation data from the request
74
- @confirmation = TBK::Webpay::Confirmation.new(request.raw_post)
75
-
76
- if # confirmation is invalid for some reason (wrong order_id or amount, double payment, etc...)
77
- render text: @confirmation.reject
78
- return # reject and stop execution
79
- end
80
-
81
- if @confirmation.success?
82
- # EXITO!
83
- # perform everything you have to do here.
84
- end
85
-
86
- # Acknowledge payment
87
- render text: @confirmation.acknowledge
88
- end
89
-
90
- # ...
91
-
92
- end
93
- ```
94
-
95
- ### Contributing
96
-
97
- 1. Fork it
98
- 2. Create your feature branch (`git checkout -b my-new-feature`)
99
- 3. Commit your changes (`git commit -am 'Add some feature'`)
100
- 4. Push to the branch (`git push origin my-new-feature`)
101
- 5. Create new Pull Request
data/Rakefile DELETED
@@ -1,6 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require 'rspec/core/rake_task'
3
-
4
- RSpec::Core::RakeTask.new(:spec)
5
-
6
- task :default => :spec
data/lib/tbk.rb DELETED
@@ -1,12 +0,0 @@
1
- require "base64"
2
- require "openssl"
3
- require "securerandom"
4
- require "net/https"
5
- require "cgi"
6
-
7
- require "tbk/version"
8
- require "tbk/config"
9
- require "tbk/errors"
10
- require "tbk/keys"
11
- require "tbk/commerce"
12
- require "tbk/webpay"
@@ -1,69 +0,0 @@
1
-
2
- module TBK
3
- # Represents a commerce registered with Transbank
4
- class Commerce
5
-
6
- # The registered commerce id
7
- # @return [Integer] the commerce id
8
- attr_reader :id
9
-
10
- # The commerce secret RSA key
11
- # @return [OpenSSL::PKey::RSA] the commerce key
12
- attr_reader :key
13
-
14
- # The commerce environment
15
- # @return [Symbol] the commerce environment
16
- attr_reader :environment
17
-
18
- # Initializes a new commerce
19
- # @param [Hash] attributes The commerce attributes
20
- # @option attributes [Integer] :id The commerce ID
21
- # @option attributes [String|OpenSSL::PKey::RSA] :key The commerce RSA private key
22
- # @option attributes [Boolean] :test flag to set commerce in test mode
23
- def initialize(attributes)
24
- @environment = (attributes[:environment] || :production).to_sym
25
- raise TBK::CommerceError, "Invalid commerce environment" unless [:production,:test].include? @environment
26
-
27
- @id = attributes[:id]
28
- raise TBK::CommerceError, "Missing commerce id" if self.id.nil?
29
-
30
- @key = case attributes[:key]
31
- when String
32
- OpenSSL::PKey::RSA.new(attributes[:key])
33
- when OpenSSL::PKey::RSA
34
- attributes[:key]
35
- when nil
36
- TEST_COMMERCE_KEY if self.test?
37
- end
38
-
39
- raise TBK::CommerceError, "Missing commerce key" if self.key.nil?
40
- raise TBK::CommerceError, "Commerce key must be a RSA private key" unless self.key.private?
41
- end
42
-
43
- # @return [Boolean] whether or not the commerce is in test mode
44
- def test?
45
- self.environment == :test
46
- end
47
-
48
- # @return [Boolean] whether or not the commerce is in production mode
49
- def production?
50
- self.environment == :production
51
- end
52
-
53
- # @return [Integer] RSA key bytes
54
- def key_bytes
55
- self.key.n.num_bytes
56
- end
57
-
58
- # @return [TBK::Commerce] The default commerce
59
- def self.default_commerce
60
- @default_commerce ||= Commerce.new({
61
- :id => TBK.config.commerce_id,
62
- :key => TBK.config.commerce_key,
63
- :environment => TBK.config.environment
64
- }) unless TBK.config.commerce_id.nil?
65
- end
66
-
67
- TEST_COMMERCE_KEY = TBK.parse_key('test_commerce')
68
- end
69
- end
@@ -1,43 +0,0 @@
1
- module TBK
2
- class Config
3
-
4
- # Set and gets the default commerce id
5
- def commerce_id(id = nil)
6
- @id = id if id
7
- @id || ENV['TBK_COMMERCE_ID']
8
- end
9
-
10
- # Sets and gets the default commerce key
11
- def commerce_key(key = nil)
12
- @key = key if key
13
- @key || ENV['TBK_COMMERCE_KEY']
14
- end
15
-
16
- # Sets the default commerce environment
17
- # @returns [Symbol] the default commerce environment
18
- def environment(environment = nil)
19
- @environment = environment if environment
20
- (@environment || ENV['TBK_COMMERCE_ENVIRONMENT'] || :production.to_sym)
21
- end
22
- end
23
-
24
- # Returns the configuration object
25
- # @returns [TBK::Config] the configuration object
26
- def self.config
27
- @config ||= Config.new
28
- end
29
-
30
- # Configure the app defaults simply by doing
31
- #
32
- # TBK.configure do |config|
33
- # config.commerce_id 123456
34
- # config.commerce_key File.read(COMMERCE_KEY_PATH)
35
- # end
36
- #
37
- # @yield [TBK::Config] The config object
38
- def self.configure(&block)
39
- yield(self.config)
40
- nil
41
- end
42
-
43
- end
@@ -1,16 +0,0 @@
1
- module TBK
2
- class Error < StandardError
3
- attr_reader :origin
4
- def initialize(msg, origin=nil)
5
- super(msg)
6
- @origin = origin
7
- end
8
- end
9
-
10
- class CommerceError < Error; end
11
-
12
- module Webpay
13
- class PaymentError < Error; end
14
- class EncryptionError < Error; end
15
- end
16
- end
@@ -1,5 +0,0 @@
1
- module TBK
2
- def self.parse_key(name)
3
- OpenSSL::PKey::RSA.new( File.read(File.expand_path("../keys/#{name}.pem",__FILE__)) )
4
- end
5
- end
@@ -1,27 +0,0 @@
1
- -----BEGIN RSA PRIVATE KEY-----
2
- MIIEowIBAAKCAQEAn3HzPC1ZBzCO3edUCf/XJiwj3bzJpjjTi/zBO9O+DDzZCaMp
3
- 14aspxQryvJhv8644E19Q+NHfxtz1cxd2wnSYKvay1gJx30ZlTOAkzUj4QMimR16
4
- vomLlQ3T2MAz1znt/PVPVU7T/JOG9R+EbiHNVKa/hUjwJEFVXLQNME97nHoLjb3v
5
- V5yV2aVhmox7b54n6F3UVPHvCsHKbJpXpE+vnLpVmdETbNpFVrDygXyG+mnEvyiO
6
- BLIwEY3XTMrgXvS069groLi5Gg8C5LDaYOWjE9084T4fiWGrHhn2781R1rykunTu
7
- 77wiWPuQHMS0+YC7mhnsk8Z/ilD+aWz/vhsgHwIDAQABAoIBAQCM+Nrt4cpNKQmn
8
- +Ne8348CGRS9ACXp6WRg6OCQXO4zM7lRZAminVgZgSQXE6aJR+T9rIWMeG7GWydX
9
- aJGzEEQJZOjV0MkUr+7mk9qiTOGkGHmGlyHnRQU8jDU59vXe3UEl3l5+NmwHbQht
10
- waf9F7XLmoLK/WoVJA6tICRpCl1oQrpziqN+gjdmMpz9i8I1sMFE7+Y7xf+7S2u7
11
- c1MRPUWqgdS9yViQVh3vZi25m5CyKRVnOB0hpNuZ7nrJymtADYSWt9wV2W1fX+MX
12
- UUoYfxyQQvWryHhGdedU7GGAnoEdblUcDkBuAaFmsm1P8K4HQZLWP4v6pYlW2JLa
13
- Zoaerb3BAoGBANCRevl0CLB0HBU7sCs0eN9fTkIEsh3OVIxPSBqDnKsynJrIWovK
14
- cs37Vb6phzdQO3ADoFJvR9ck8+v6Cv0KR8IOFl9wfC4ZoxkKBBeq94ZLN+YhE2PW
15
- KiRFybqcgCtzxKS3MyWgpIcT9xFtHVjlorZ8Jk51fgLZbGzamtLhderVAoGBAMO0
16
- mIiiV4l2vXzu4tFfkpu/GOx/D9/vAic3X9FOky09BNCyuMXMQgI8e3wWsGEZghls
17
- Vg9KDV5EPxAmpumcdPFK2IMACaH41ac7vys3ZD8kMK0INQkuDAcG4YsxMaTwEPo0
18
- p1i3zwwEWwknw1yJkOyozz0EcIzS9NrZZEjnBHEjAoGAQ81XdeqzvHEyg/CQd6sq
19
- NCtubGXMZYYi1C4d2Yi5kKn2YRcK4HDi23V+TWodK+0oNWToZIQKjbVUmn0Bv3rt
20
- EvezbDlMFUx+SfCIng0VRJIFTQmpnQYNUxdg2gpwXC/ZWFa6CNxtQABMjFy1cqXM
21
- PJild1IYseJurgBu3mkvBTUCgYBqA/T1X2woLUis2wPIBAv5juXDh3lkB6eU8uxX
22
- CEe2I+3t2EM781B2wajrKadWkmjluMhN9AGV5UZ8S1P0DStUYwUywdx1/8RNmZIP
23
- qSwHAGXV9jI0zNr7G4Em0/leriWkRM26w6fHjLx8EyxDfsohSbkqBrOptcWqoEUx
24
- MOQ5HQKBgAS4sbddOas2MapuhKU2surEb3Kz3RCIpta4bXgTQMt9wawcZSSpvnfT
25
- zs5sehYvBFszL3MV98Uc50HXMf7gykRCmPRmB9S+f+kiVRvQDHfc9nRNg2XgcotU
26
- KAE16PQM8GihQ0C+EcXHouyud5CRJGfyurokRlH/jY3BiRAG5c+6
27
- -----END RSA PRIVATE KEY-----
@@ -1,14 +0,0 @@
1
- -----BEGIN PUBLIC KEY-----
2
- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxKKjroxE7X44TQovh9A9
3
- ZpntP7LrdoyFsnJbDKjOOCoiid92FydN5qemyQCeXhsc7QHUXwGdth22fB8xJr3a
4
- MZBEUJ+BKFrL+W6yE5V+F5Bj0Uq3lL0QMAIftGhLpgqw0ZMtU89kyd9Q4Rclq4r8
5
- p2m/ZD7Pn5EmTOFSeyoWTMZQDl7OEoCKh/cZH5NJdWL08lCI+sGLOghRmFzkve4h
6
- F9JCwKA7NYG7j3BWh39Oj2NIXEY/TO1Y3Y2WfNv9nvTpr46SpFlyp0KOhSiqgvXX
7
- DgeXlebyqS82ch2DzOV9fjDAw7t71WXJBAev8Gd6HXwIXE/JP6AnLCa2Y+b6Wv8K
8
- GWBCMIBXWL0m7WHeCaJ9Hx2yXZmHJh8FgeKffFKCwn3X90JiMocOSGsOE+Sfo85S
9
- h/39Vc7vZS3i7kJDDoz9ab9/vFy30RuJf4p8Erh7kWtERVoG6/EhR+j4N3mgIOBZ
10
- SHfzDAoOnqP5l7t2RXYcEbRLVN6o+XgUtalX33EJxJRsXoz9a6PxYlesIwPbKteD
11
- BZ/xyJDwTc2gU2YzSH8G9anKrcvITBDULSAuxQUkYOiLbkb7vSKWDYKe0do6ibO3
12
- RY/KXI63Q7bGKYaI2aa/8GnqVJ2G1U2s59NpqX0aaWjn59gsA8trA0YKOZP4xJIh
13
- CvLM94G4V7lxe2IHKPqLscMCAwEAAQ==
14
- -----END PUBLIC KEY-----
@@ -1,14 +0,0 @@
1
- -----BEGIN PUBLIC KEY-----
2
- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtKe3HHWwRcizAfkbS92V
3
- fQr8cUb94TRjQPzNTqBduvvj65AD5J98Cn1htE3NzOz+PjPRcnfVe53V4f3+YlIb
4
- 6nnxyeuYLByiwoPkCmpOFBxNp04/Yh3dxN4xgOANXA37rNbDeO4WIEMG6zbdQMNJ
5
- 7RqQUlJSmui8gt3YxtqWBhBVW79qDCYVzxFrv3SH7pRuYEr+cxDvzRylxnJgr6ee
6
- N7gmjoSMqF16f9aGdQ12obzV0A35BqpN6pRFoS/NvICbEeedS9g5gyUHf54a+juB
7
- OV2HH5VJsCCgcb7I7Sio/xXTyP+QjIGJfpukkE8F+ohwRiChZ9jMXofPtuZYZiFQ
8
- /gX08s5Qdpaph65UINP7crYbzpVJdrT2J0etyMcZbEanEkoX8YakLEBpPhyyR7mC
9
- 73fWd9sTuBEkG6kzCuG2JAyo6V8eyISnlKDEVd+/6G/Zpb5cUdBCERTYz5gvNoZN
10
- zkuq4isiXh5MOLGs91H8ermuhdQe/lqvXf8Op/EYrAuxcdrZK0orI4LbPdUrC0Jc
11
- Fl02qgXRrSpXo72anOlFc9P0blD4CMevW2+1wvIPA0DaJPsTnwBWOUqcfa7GAFH5
12
- KGs3zCiZ5YTLDlnaps8koSssTVRi7LVT8HhiC5mjBklxmZjBv6ckgQeFWgp18kuU
13
- ve5Elj5HSV7x2PCz8RKB4XcCAwEAAQ==
14
- -----END PUBLIC KEY-----
@@ -1,7 +0,0 @@
1
- module TBK
2
- module VERSION
3
- GEM = "0.9.2"
4
- KCC = "6.0"
5
- WEBSITE = "http://sagmor.com/tbk/"
6
- end
7
- end
@@ -1,3 +0,0 @@
1
- require 'tbk/webpay/encryption'
2
- require 'tbk/webpay/payment'
3
- require 'tbk/webpay/confirmation'
@@ -1,113 +0,0 @@
1
- # encoding: UTF-8
2
- module TBK
3
- module Webpay
4
- class Confirmation
5
- RESPONSE_CODES = {
6
- '0' => 'Transacción aprobada.',
7
- '-1' => 'Rechazo de tx. en B24, No autorizada',
8
- '-2' => 'Transacción debe reintentarse.',
9
- '-3' => 'Error en tx.',
10
- '-4' => 'Rechazo de tx. En B24, No autorizada',
11
- '-5' => 'Rechazo por error de tasa.',
12
- '-6' => 'Excede cupo máximo mensual.',
13
- '-7' => 'Excede límite diario por transacción.',
14
- '-8' => 'Rubro no autorizado.'
15
- }
16
-
17
- attr_accessor :commerce
18
- attr_reader :raw
19
- attr_reader :params
20
-
21
- def initialize(options)
22
- options = { :post => options } if options.is_a?(String)
23
-
24
- self.commerce = options[:commerce] || TBK::Commerce.default_commerce
25
- self.parse(options[:post])
26
- end
27
-
28
- def acknowledge
29
- self.commerce.webpay_encrypt('ACK')
30
- end
31
-
32
- def reject
33
- self.commerce.webpay_encrypt('ERR')
34
- end
35
-
36
- def success?
37
- self.params["TBK_RESPUESTA"] == "0"
38
- end
39
-
40
- def order_id
41
- self.params["TBK_ORDEN_COMPRA"]
42
- end
43
-
44
- def session_id
45
- self.params["TBK_ID_SESION"]
46
- end
47
-
48
- def transaction_id
49
- self.params["TBK_ID_TRANSACCION"]
50
- end
51
-
52
- def amount
53
- self.params["TBK_MONTO"].to_f/100
54
- end
55
-
56
- def authorization
57
- self.params["TBK_CODIGO_AUTORIZACION"]
58
- end
59
-
60
- def card_display_number
61
- "XXXX-XXXX-XXXX-#{ card_last_numbers }"
62
- end
63
-
64
- def card_last_numbers
65
- self.params["TBK_FINAL_NUMERO_TARJETA"]
66
- end
67
-
68
- def message
69
- RESPONSE_CODES[self.params["TBK_RESPUESTA"]]
70
- end
71
-
72
- def paid_at
73
- @paid_at ||= begin
74
- year = Time.now.year
75
- month = self.params["TBK_FECHA_TRANSACCION"][0...2].to_i
76
- day = self.params["TBK_FECHA_TRANSACCION"][2...4].to_i
77
- hour = self.params["TBK_HORA_TRANSACCION"][0...2].to_i
78
- minutes = self.params["TBK_HORA_TRANSACCION"][2...4].to_i
79
- seconds = self.params["TBK_HORA_TRANSACCION"][4...6].to_i
80
-
81
- offset = if defined? TZInfo::Timezone
82
- # Use tzinfo gem if available
83
- TZInfo::Timezone.get('America/Santiago').period_for_utc(DateTime.new(year,month,day,hour,minutes,0)).utc_offset
84
- else
85
- -14400
86
- end
87
-
88
- Time.new(year, month, day, hour, minutes, seconds, offset)
89
- end
90
- end
91
-
92
-
93
- protected
94
- def parse(post)
95
- @raw = post.to_s
96
- @raw_params = {}
97
- for line in @raw.split('&')
98
- key, value = *line.scan( %r{^([A-Za-z0-9_.]+)\=(.*)$} ).flatten
99
- @raw_params[key] = CGI.unescape(value)
100
- end
101
-
102
- puts @raw_params.inspect
103
-
104
- @params = {}
105
- decrypted_params = self.commerce.webpay_decrypt(@raw_params['TBK_PARAM'])
106
- for line in decrypted_params.split('#')
107
- key, value = *line.scan( %r{^([A-Za-z0-9_.]+)\=(.*)$} ).flatten
108
- @params[key] = CGI.unescape(value)
109
- end
110
- end
111
- end
112
- end
113
- end
@@ -1,71 +0,0 @@
1
- module TBK
2
- module Webpay
3
- module Encryption
4
- # Constants
5
- KEY_ID = 101
6
- KEY = TBK.parse_key('webpay.101')
7
- TEST_KEY = TBK.parse_key('webpay_test.101')
8
- IV_PADDING = "\x10\xBB\xFF\xBF\x00\x00\x00\x00\x00\x00\x00\x00\xF4\xBF"
9
-
10
- def webpay_key_id
11
- KEY_ID
12
- end
13
-
14
- def webpay_key
15
- self.production? ? KEY : TEST_KEY
16
- end
17
-
18
- def webpay_key_length
19
- webpay_key.n.num_bytes
20
- end
21
-
22
- def webpay_encrypt(text)
23
- signature = self.key.sign(OpenSSL::Digest::SHA512.new, text)
24
-
25
- key = SecureRandom.random_bytes(32)
26
- encripted_key = webpay_key.public_encrypt(key, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)
27
-
28
- iv = SecureRandom.random_bytes(16)
29
-
30
- cipher = OpenSSL::Cipher.new('AES-256-CBC')
31
- cipher.encrypt
32
- cipher.key = key
33
- cipher.iv = iv + IV_PADDING
34
- encripted_text = cipher.update(signature + text) + cipher.final
35
-
36
- Base64.encode64( iv + encripted_key + encripted_text).strip
37
- rescue RuntimeError => error
38
- raise TBK::Webpay::EncryptionError.new("Encryption failed",error)
39
- end
40
-
41
- def webpay_decrypt(encripted_text)
42
- data = Base64.decode64(encripted_text)
43
-
44
- iv = data[0...16]
45
- encripted_key = data[16...(16 + self.key_bytes)]
46
- key = self.key.private_decrypt(encripted_key, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)
47
-
48
- cipher = OpenSSL::Cipher.new('AES-256-CBC')
49
- cipher.decrypt
50
- cipher.key = key
51
- cipher.iv = iv + IV_PADDING
52
- decrypted_text = cipher.update(data[(16 + self.key_bytes)..-1]) + cipher.final
53
- signature = decrypted_text[0...(webpay_key_length)]
54
- text = decrypted_text[(webpay_key_length)..-1]
55
-
56
- unless webpay_key.verify(OpenSSL::Digest::SHA512.new, signature, text)
57
- raise TBK::Webpay::EncryptionError, "Invalid message signature"
58
- end
59
-
60
- text
61
- rescue TBK::Error
62
- raise
63
- rescue => error
64
- raise TBK::Webpay::EncryptionError.new("Decryption failed",error)
65
- end
66
-
67
- end
68
- end
69
-
70
- Commerce.send :include, Webpay::Encryption
71
- end
@@ -1,159 +0,0 @@
1
- module TBK
2
- module Webpay
3
- class Payment
4
- attr_accessor :commerce
5
- attr_accessor :amount
6
- attr_accessor :order_id
7
- attr_accessor :session_id
8
- attr_accessor :confirmation_url
9
- attr_accessor :success_url
10
- attr_accessor :failure_url
11
-
12
- def initialize(options = {})
13
- self.commerce = options[:commerce] || TBK::Commerce.default_commerce
14
- self.amount = options[:amount]
15
- self.order_id = options[:order_id]
16
- self.session_id = options[:session_id]
17
- self.confirmation_url = options[:confirmation_url]
18
- self.success_url = options[:success_url]
19
- self.failure_url = options[:failure_url]
20
- end
21
-
22
- # Transaction ids are generated randombly on the client side
23
- def transaction_id
24
- @transaction_id ||= (rand * 10000000000).to_i
25
- end
26
-
27
- def redirect_url
28
- "#{ self.process_url }?TBK_VERSION_KCC=#{ TBK::VERSION::KCC }&TBK_TOKEN=#{ self.token }"
29
- end
30
-
31
- def to_html_form(options = {}, &block)
32
- form = <<-EOF
33
- <form method="POST"
34
- class="#{ options[:class] || 'tbk_payment_form'}"
35
- id="#{ options[:id] }"
36
- action="#{ self.process_url }">
37
- <input type="hidden" name="TBK_PARAM" value="#{ self.param }">
38
- <input type="hidden" name="TBK_VERSION_KCC" value="#{ TBK::VERSION::KCC }">
39
- <input type="hidden" name="TBK_CODIGO_COMERCIO" value="#{ self.commerce.id }">
40
- <input type="hidden" name="TBK_KEY_ID" value="#{ self.commerce.webpay_key_id }">
41
- #{ yield if block_given? }
42
- </form>
43
- EOF
44
-
45
- form = form.html_safe if form.respond_to? :html_safe
46
-
47
- form
48
- end
49
-
50
- protected
51
- def process_url
52
- if self.commerce.test?
53
- "https://certificacion.webpay.cl:6443/filtroUnificado/bp_revision.cgi"
54
- else
55
- "https://webpay.transbank.cl:443/cgi-bin/bp_revision.cgi"
56
- end
57
- end
58
-
59
- def validation_url
60
- if self.commerce.test?
61
- "https://certificacion.webpay.cl:6443/filtroUnificado/bp_validacion.cgi"
62
- else
63
- "https://webpay.transbank.cl:443/cgi-bin/bp_validacion.cgi"
64
- end
65
- end
66
-
67
- def token
68
- @token ||= begin
69
- uri = URI.parse( self.validation_url )
70
-
71
- response = nil
72
- until response && response['location'].nil?
73
- uri = URI.parse( response.nil? ? self.validation_url : response['location'] )
74
-
75
- response = Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
76
- post = Net::HTTP::Post.new uri.path
77
- post["user-agent"] = "TBK/#{ TBK::VERSION::GEM } (Ruby/#{ RUBY_VERSION }; +#{ TBK::VERSION::WEBSITE })"
78
- post.set_form_data({
79
- 'TBK_VERSION_KCC' => TBK::VERSION::KCC,
80
- 'TBK_CODIGO_COMERCIO' => self.commerce.id,
81
- 'TBK_KEY_ID' => self.commerce.webpay_key_id,
82
- 'TBK_PARAM' => self.param
83
- })
84
-
85
- # http.read_timeout = Webpay::Config.timeout
86
- http.request post
87
- end
88
- end
89
-
90
- unless response.code == "200"
91
- raise TBK::Webpay::PaymentError, "Payment token generation failed"
92
- end
93
-
94
- response = self.commerce.webpay_decrypt(response.body)
95
-
96
- unless /ERROR=([a-zA-Z0-9]+)/.match(response)[1] == "0"
97
- raise TBK::Webpay::PaymentError, "Payment token generation failed"
98
- end
99
-
100
- /TOKEN=([a-zA-Z0-9]+)/.match(response)[1]
101
- end
102
- end
103
-
104
- def param
105
- @param ||= begin
106
- self.verify!
107
- self.commerce.webpay_encrypt(raw_params)
108
- end
109
- end
110
-
111
- def verify!
112
- raise TBK::Webpay::PaymentError, "Commerce required" if self.commerce.nil?
113
- raise TBK::Webpay::PaymentError, "Invalid amount (#{self.amount.inspect})" unless self.amount && self.amount > 0
114
- raise TBK::Webpay::PaymentError, "Order ID required" if self.order_id.nil?
115
- raise TBK::Webpay::PaymentError, "Success URL required" if self.success_url.nil?
116
- raise TBK::Webpay::PaymentError, "Confirmation URL required" if self.confirmation_url.nil?
117
- confirmation_uri = URI.parse(self.confirmation_url)
118
- raise TBK::Webpay::PaymentError, "Confirmation URL host MUST be an IP address" unless /(\d{1,3}\.){3}\d{1,3}/.match(confirmation_uri.host)
119
- raise TBK::Webpay::PaymentError, "Confirmation URL port MUST be 80 or 8080" unless [80, 8080].include?(confirmation_uri.port)
120
- end
121
-
122
- def raw_params(splitter="#", include_pseudomac=true)
123
- params = []
124
-
125
- params << "TBK_ORDEN_COMPRA=#{ self.order_id }"
126
- params << "TBK_CODIGO_COMERCIO=#{ self.commerce.id }"
127
- params << "TBK_ID_TRANSACCION=#{ self.transaction_id }"
128
-
129
- uri = URI.parse(self.confirmation_url)
130
-
131
- params << "TBK_URL_CGI_COMERCIO=#{ uri.path }"
132
- params << "TBK_SERVIDOR_COMERCIO=#{ uri.host }"
133
- params << "TBK_PUERTO_COMERCIO=#{ uri.port }"
134
-
135
- params << "TBK_VERSION_KCC=#{ TBK::VERSION::KCC }"
136
- params << "TBK_KEY_ID=#{ self.commerce.webpay_key_id }"
137
- params << "PARAMVERIFCOM=1"
138
-
139
- if include_pseudomac
140
- # An old pseudo mac generation carried from an old implementation
141
- digest = OpenSSL::Digest::MD5.new
142
- digest << self.raw_params('&',false) << self.commerce.id.to_s << "webpay"
143
- mac = digest.to_s
144
-
145
- params << "TBK_MAC=#{ mac }"
146
- end
147
-
148
-
149
- params << "TBK_MONTO=#{ (self.amount * 100).to_i }"
150
- params << "TBK_ID_SESION=#{ self.session_id }" if self.session_id
151
- params << "TBK_URL_EXITO=#{ self.success_url }"
152
- params << "TBK_URL_FRACASO=#{ self.failure_url || self.success_url }"
153
- params << "TBK_TIPO_TRANSACCION=TR_NORMAL"
154
-
155
- params.join(splitter)
156
- end
157
- end
158
- end
159
- end
@@ -1,46 +0,0 @@
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
@@ -1,54 +0,0 @@
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
@@ -1,3 +0,0 @@
1
- require 'bundler/setup'
2
- require 'tbk'
3
- Dir["spec/support/**/*.rb"].each { |f| require File.expand_path(f) }
@@ -1,5 +0,0 @@
1
- RSpec.configure do |config|
2
- config.expect_with :rspec do |expect|
3
- expect.syntax = :expect
4
- end
5
- end
@@ -1,12 +0,0 @@
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
@@ -1,4 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe TBK::Webpay::Confirmation do
4
- end
@@ -1,4 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe TBK::Webpay::Encryption do
4
- end
@@ -1 +0,0 @@
1
- require 'spec_helper'
@@ -1,23 +0,0 @@
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($/)
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