payture_ruby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 513215f68d166198dcbc83405cacb0fa13fd5fd2
4
+ data.tar.gz: ff0687b97a9d4fdd0985798be216696134d2dbde
5
+ SHA512:
6
+ metadata.gz: 19608331dcdedd25b2a13caf99150ebc55ae40f55a00e7e3df9baf6e2c66a0e886e6c1285400a26df5535d9aeb989ffa9210f72bb601f69f1bee66eddfca310e
7
+ data.tar.gz: f52399d1c34dc5c2af4474a16b16ef8670c745716796385c1355ec44676cc66ea287a20eef300efde784080b86e9612916f678eb870b3a855d88eaa5396551ec
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in payture.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Igor Davydov
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,56 @@
1
+ # Payture
2
+
3
+ This gems wraps e-walet api of payture.com credit card processing
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'payture_ruby'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install payture_ruby
20
+
21
+ ## Configuration
22
+
23
+ In an initializer:
24
+
25
+ ```ruby
26
+ Payture.configure do |config|
27
+ config.host_type = 'sandbox' # or 'secure'
28
+ config.key = 'WVMerchant' # your user access key
29
+ config.password = 'Secret' # your user access pass
30
+ end
31
+ ```
32
+
33
+ Or you can just pass options to initializer
34
+
35
+ ```ruby
36
+ Payture::Cleient.new host_type: :secure
37
+ ```
38
+
39
+ ## Usage
40
+
41
+ Instanciate api client or call methods on Payture module directly
42
+
43
+ ```ruby
44
+ client = Payture::Cleient.new host_type: :secure
45
+ client.register v_w_user_lgn: '123@ya.ru', v_w_user_psw: 123, phone_number: 79156783333
46
+
47
+ Payture.get_list v_w_user_lgn: '123@ya.ru', v_w_user_psw: 123
48
+ ```
49
+
50
+ ## Contributing
51
+
52
+ 1. Fork it ( https://github.com/div/payture/fork )
53
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
54
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
55
+ 4. Push to the branch (`git push origin my-new-feature`)
56
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rake/testtask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task default: :test
7
+
8
+ desc 'Test the payture gem.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.libs << 'test'
12
+ t.pattern = 'test/**/*_test.rb'
13
+ t.verbose = true
14
+ end
@@ -0,0 +1,25 @@
1
+ require 'faraday'
2
+
3
+ module FaradayMiddleware
4
+ class PaytureAuth < Faraday::Middleware
5
+ def call(env)
6
+
7
+ if env[:url].query.nil?
8
+ query = {}
9
+ else
10
+ query = Faraday::Utils.parse_query(env[:url].query)
11
+ end
12
+
13
+ if @access_token
14
+ env[:url].query = Faraday::Utils.build_query(query.merge('VWID' => @access_token))
15
+ end
16
+
17
+ @app.call env
18
+ end
19
+
20
+ def initialize(app, access_token=nil)
21
+ @app = app
22
+ @access_token = access_token
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,53 @@
1
+ require 'faraday'
2
+
3
+ module FaradayMiddleware
4
+ class RaiseHttpException < Faraday::Middleware
5
+ def call(env)
6
+ @app.call(env).on_complete do |response|
7
+ case response[:status].to_i
8
+ when 400
9
+ raise Exchanges::BadRequest, error_message_400(response)
10
+ when 401
11
+ raise Exchanges::Unauthorized, error_message_400(response)
12
+ when 404
13
+ raise Exchanges::NotFound, error_message_400(response)
14
+ when 500
15
+ raise Exchanges::InternalServerError, error_message_500(response, "Something is technically wrong.")
16
+ when 502
17
+ raise Exchanges::BadGateway, error_message_500(response, "The server returned an invalid or incomplete response.")
18
+ when 503
19
+ raise Exchanges::ServiceUnavailable, error_message_500(response, "Exchanges is rate limiting your requests.")
20
+ when 504
21
+ raise Exchanges::GatewayTimeout, error_message_500(response, "504 Gateway Time-out")
22
+ end
23
+ end
24
+ end
25
+
26
+ def initialize(app)
27
+ super app
28
+ @parser = nil
29
+ end
30
+
31
+ private
32
+
33
+ def error_message_400(response)
34
+ "#{response[:method].to_s.upcase} #{response[:url].to_s}: #{response[:status]}"
35
+ end
36
+
37
+ def error_body(body)
38
+ if not body.nil? and not body.empty? and body.kind_of?(String)
39
+ body = ::JSON.parse(body)
40
+ end
41
+
42
+ if body.nil?
43
+ nil
44
+ elsif body['meta'] and body['meta']['error_message'] and not body['meta']['error_message'].empty?
45
+ ": #{body['meta']['error_message']}"
46
+ end
47
+ end
48
+
49
+ def error_message_500(response, body=nil)
50
+ "#{response[:method].to_s.upcase} #{response[:url].to_s}: #{[response[:status].to_s + ':', body].compact.join(' ')}"
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,33 @@
1
+ require 'faraday'
2
+ require 'payture'
3
+
4
+ module FaradayMiddleware
5
+ # Converts parsed response bodies to underscored keys if bodies were of
6
+ # Hash type.
7
+ class Underscore < Faraday::Response::Middleware
8
+
9
+ def initialize(app = nil, options = {})
10
+ super(app)
11
+ end
12
+
13
+ def parse(body)
14
+ convert_hash_keys body
15
+ end
16
+
17
+ private
18
+
19
+ def convert_hash_keys(value)
20
+ case value
21
+ when Array
22
+ value.map(&method(:convert_hash_keys))
23
+ when Hash
24
+ Hash[value.map { |k, v| [Payture::Helper.convert_to_underscore(k), convert_hash_keys(v)] }]
25
+ else
26
+ value
27
+ end
28
+ end
29
+
30
+ end
31
+ end
32
+
33
+
@@ -0,0 +1,27 @@
1
+ require File.expand_path('../connection', __FILE__)
2
+ require File.expand_path('../request', __FILE__)
3
+ require File.expand_path('../response', __FILE__)
4
+
5
+ module Payture
6
+ class Api
7
+ attr_accessor *Configuration::VALID_OPTIONS_KEYS
8
+
9
+ def initialize(options={})
10
+ options = Payture.options.merge(options)
11
+ Configuration::VALID_OPTIONS_KEYS.each do |key|
12
+ send("#{key}=", options[key])
13
+ end
14
+ end
15
+
16
+ include Connection
17
+ include Request
18
+
19
+ def host
20
+ "https://#{host_type}.#{Configuration::DOMAIN}/#{api_type}/"
21
+ end
22
+
23
+ def convert_to_underscore(key)
24
+ key.scan(/[A-Z][a-z]*/).join("_").downcase
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,20 @@
1
+ require File.expand_path('../../helper', __FILE__)
2
+
3
+ module Payture
4
+ class Client
5
+ module Vwapi
6
+
7
+ API_METHODS = %w(Register Update Delete Add Activate Remove GetList Pay Refund PayStatus)
8
+
9
+ API_METHODS.each do |method_name|
10
+ underscore_method_name = Payture::Helper.convert_to_underscore method_name
11
+ define_method underscore_method_name do |options|
12
+ options ||= {}
13
+ response = get(method_name, options)
14
+ response.send(underscore_method_name)
15
+ end
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,7 @@
1
+ module Payture
2
+ class Client < Api
3
+ Dir[File.expand_path("../client/*.rb", __FILE__)].each{|f| require f}
4
+
5
+ include Client::Vwapi
6
+ end
7
+ end
@@ -0,0 +1,58 @@
1
+ require 'faraday'
2
+ require File.expand_path('../version', __FILE__)
3
+
4
+ module Payture
5
+ module Configuration
6
+
7
+ DOMAIN = 'payture.com'
8
+
9
+ VALID_OPTIONS_KEYS = [
10
+ :api_type,
11
+ :host_type,
12
+ :key,
13
+ :password,
14
+ :format,
15
+ :user_agent,
16
+ :adapter
17
+ ].freeze
18
+
19
+
20
+ DEFAULT_API_TYPE = 'vwapi'
21
+ DEFAULT_HOST_TYPE = 'sandbox'
22
+ DEFAULT_KEY = 'VWMerchant'
23
+ DEFAULT_PASSWORD = nil
24
+ DEFAULT_USER_AGENT = "Payture Ruby Gem #{Payture::VERSION}".freeze
25
+ DEFAULT_FORMAT = 'xml'
26
+ DEFAULT_ADAPTER = Faraday.default_adapter
27
+
28
+ attr_accessor *VALID_OPTIONS_KEYS
29
+
30
+ # When this module is extended, set all configuration options to their default values
31
+ def self.extended(base)
32
+ base.reset
33
+ end
34
+
35
+ # Convenience method to allow configuration options to be set in a block
36
+ def configure
37
+ yield self
38
+ end
39
+
40
+ # Create a hash of options and their values
41
+ def options
42
+ VALID_OPTIONS_KEYS.inject({}) do |option, key|
43
+ option.merge!(key => send(key))
44
+ end
45
+ end
46
+
47
+ # Reset all configuration options to defaults
48
+ def reset
49
+ self.adapter = DEFAULT_ADAPTER
50
+ self.api_type = DEFAULT_API_TYPE
51
+ self.host_type = DEFAULT_HOST_TYPE
52
+ self.key = DEFAULT_KEY
53
+ self.password = DEFAULT_PASSWORD
54
+ self.user_agent = DEFAULT_USER_AGENT
55
+ self.format = DEFAULT_FORMAT
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,30 @@
1
+ require 'faraday_middleware'
2
+ Dir[File.expand_path('../../faraday/*.rb', __FILE__)].each{|f| require f}
3
+
4
+ module Payture
5
+ module Connection
6
+ private
7
+
8
+ def connection(raw=false)
9
+ options = {
10
+ :headers => {'Accept' => "application/#{format}; charset=utf-8", 'User-Agent' => user_agent},
11
+ :url => host,
12
+ }
13
+
14
+ Faraday::Connection.new(options) do |connection|
15
+ connection.use FaradayMiddleware::PaytureAuth, key
16
+ connection.use Faraday::Request::UrlEncoded
17
+ connection.use FaradayMiddleware::Mashify unless raw
18
+ connection.use FaradayMiddleware::Underscore unless raw
19
+ unless raw
20
+ case format.to_s.downcase
21
+ when 'json' then connection.use Faraday::Response::ParseJson
22
+ when 'xml' then connection.use Faraday::Response::ParseXml
23
+ end
24
+ end
25
+ connection.use FaradayMiddleware::RaiseHttpException
26
+ connection.adapter(adapter)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,19 @@
1
+ module Payture
2
+
3
+ class Error < StandardError; end
4
+
5
+ class BadRequest < Error; end
6
+
7
+ class Unauthorized < Error; end
8
+
9
+ class NotFound < Error; end
10
+
11
+ class InternalServerError < Error; end
12
+
13
+ class BadGateway < Error; end
14
+
15
+ class ServiceUnavailable < Error; end
16
+
17
+ class GatewayTimeout < Error; end
18
+
19
+ end
@@ -0,0 +1,7 @@
1
+ module Payture
2
+ module Helper
3
+ def self.convert_to_underscore(key)
4
+ key.scan(/[A-Z][a-z]*/).join("_").downcase
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,55 @@
1
+ module Payture
2
+ module Request
3
+
4
+ def get(path, options={}, raw=false, unformatted=false, no_response_wrapper=false)
5
+ request(:get, path, options, raw, unformatted, no_response_wrapper)
6
+ end
7
+
8
+ def post(path, options={}, raw=false, unformatted=false, no_response_wrapper=false)
9
+ request(:post, path, options, raw, unformatted, no_response_wrapper)
10
+ end
11
+
12
+ def put(path, options={}, raw=false, unformatted=false, no_response_wrapper=false)
13
+ request(:put, path, options, raw, unformatted, no_response_wrapper)
14
+ end
15
+
16
+ def delete(path, options={}, raw=false, unformatted=false, no_response_wrapper=false)
17
+ request(:delete, path, options, raw, unformatted, no_response_wrapper)
18
+ end
19
+
20
+ private
21
+
22
+ def request(method, path, options, raw=false, unformatted=false, no_response_wrapper=false)
23
+ response = connection(raw).send(method) do |request|
24
+ case method
25
+ when :get, :delete
26
+ request.url(path, 'DATA' => encoded_string(options))
27
+ when :post, :put
28
+ request.path = path
29
+ request.body = options unless options.empty?
30
+ end
31
+ end
32
+ return response if raw
33
+ return response.body if no_response_wrapper
34
+ return Response.create( response.body )
35
+ end
36
+
37
+ def encoded_string hash
38
+ s = hash.map{|k,v| "#{convert_to_camelcase(k)}=#{v}"}.join(';')
39
+ CGI.escape s
40
+ end
41
+
42
+ def convert_to_camelcase(key)
43
+ key = key.to_s
44
+ if key.split('_').count > 1
45
+ key.split('_').collect(&:capitalize).join
46
+ else
47
+ key
48
+ end
49
+ end
50
+
51
+ def formatted_path(path)
52
+ [path, format].compact.join('.')
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,9 @@
1
+ module Payture
2
+ module Response
3
+ def self.create( response_hash )
4
+ data = response_hash.data.dup rescue response_hash.dup
5
+ data.extend( self )
6
+ data
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module Payture
2
+ VERSION = "0.0.1"
3
+ end
data/lib/payture.rb ADDED
@@ -0,0 +1,23 @@
1
+ require File.expand_path('../payture/configuration', __FILE__)
2
+ require File.expand_path('../payture/api', __FILE__)
3
+ require File.expand_path('../payture/client', __FILE__)
4
+ require File.expand_path('../payture/error', __FILE__)
5
+ require File.expand_path('../payture/helper', __FILE__)
6
+
7
+ module Payture
8
+ extend Configuration
9
+
10
+ def self.client(options={})
11
+ Client.new(options)
12
+ end
13
+
14
+ def self.method_missing(method, *args, &block)
15
+ return super unless client.respond_to?(method)
16
+ client.send(method, *args, &block)
17
+ end
18
+
19
+ def self.respond_to?(method)
20
+ return client.respond_to?(method) || super
21
+ end
22
+
23
+ end
data/payture.gemspec ADDED
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'payture/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "payture_ruby"
8
+ spec.version = Payture::VERSION
9
+ spec.authors = ["Igor Davydov"]
10
+ spec.email = ["iskiche@gmail.com"]
11
+ spec.summary = %q{Payture api ruby gem}
12
+ spec.description = %q{Optional.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "minitest", "~> 5"
24
+ spec.add_development_dependency "webmock"
25
+ spec.add_development_dependency "minitest-vcr"
26
+ spec.add_development_dependency "vcr"
27
+ spec.add_dependency "faraday"
28
+ spec.add_dependency "faraday_middleware"
29
+ spec.add_dependency "multi_xml"
30
+ spec.add_dependency "hashie"
31
+ end
@@ -0,0 +1,37 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://sandbox.payture.com/vwapi/Activate?DATA=VWUserLgn%253Dfucker1%2540dom.com%253BVWUserPsw%253D123%253BCardId%253De43544ba-cf4f-4702-85ef-313df89577eb%253Bamount%253D100&VWID=VWMerchant
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - application/xml; charset=utf-8
12
+ User-Agent:
13
+ - Payture Ruby Gem 0.0.1
14
+ Accept-Encoding:
15
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Server:
22
+ - nginx
23
+ Date:
24
+ - Thu, 21 Aug 2014 11:47:44 GMT
25
+ Content-Type:
26
+ - text/xml; charset=utf-8
27
+ Content-Length:
28
+ - '119'
29
+ Connection:
30
+ - keep-alive
31
+ body:
32
+ encoding: UTF-8
33
+ string: <Activate Success="True" VWUserLgn="fucker1@dom.com" CardId="e43544ba-cf4f-4702-85ef-313df89577eb"
34
+ />
35
+ http_version:
36
+ recorded_at: Thu, 21 Aug 2014 11:47:44 GMT
37
+ recorded_with: VCR 2.9.2
@@ -0,0 +1,37 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://sandbox.payture.com/vwapi/Add?DATA=VWUserLgn%253Drom1%2540dom.com%253BVWUserPsw%253D123%253BCardNumber%253D4111111111111112%253BEMonth%253D12%253BEYear%253D15%253BCardHolder%253DIvan%2BIvanov%253BSecureCode%253D123%253BPhoneNumber%253D79001234567&VWID=VWMerchant
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - application/xml; charset=utf-8
12
+ User-Agent:
13
+ - Payture Ruby Gem 0.0.1
14
+ Accept-Encoding:
15
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Server:
22
+ - nginx
23
+ Date:
24
+ - Wed, 20 Aug 2014 22:06:08 GMT
25
+ Content-Type:
26
+ - text/xml; charset=utf-8
27
+ Content-Length:
28
+ - '93'
29
+ Connection:
30
+ - keep-alive
31
+ body:
32
+ encoding: UTF-8
33
+ string: <Add VWUserLgn="rom1@dom.com" Success="False" ErrCode="DUPLICATE_CARD"
34
+ />
35
+ http_version:
36
+ recorded_at: Wed, 20 Aug 2014 22:06:08 GMT
37
+ recorded_with: VCR 2.9.2
@@ -0,0 +1,37 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://sandbox.payture.com/vwapi/Add?DATA=VWUserLgn%253Dfucker1%2540dom.com%253BVWUserPsw%253D123%253BCardNumber%253D4111111111111112%253BEMonth%253D12%253BEYear%253D15%253BCardHolder%253DIvan%2BIvanov%253BSecureCode%253D123%253BPhoneNumber%253D79001234567&VWID=VWMerchant
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - application/xml; charset=utf-8
12
+ User-Agent:
13
+ - Payture Ruby Gem 0.0.1
14
+ Accept-Encoding:
15
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Server:
22
+ - nginx
23
+ Date:
24
+ - Thu, 21 Aug 2014 11:43:19 GMT
25
+ Content-Type:
26
+ - text/xml; charset=utf-8
27
+ Content-Length:
28
+ - '117'
29
+ Connection:
30
+ - keep-alive
31
+ body:
32
+ encoding: UTF-8
33
+ string: <Add VWUserLgn="" Success="True" CardName="411111xxxxxx1112" CardId="e43544ba-cf4f-4702-85ef-313df89577eb"
34
+ />
35
+ http_version:
36
+ recorded_at: Thu, 21 Aug 2014 11:43:19 GMT
37
+ recorded_with: VCR 2.9.2