azericard 1.0.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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1b853dad3a4d492e17410701a6457644042ed291
4
+ data.tar.gz: 652bc4ab9636aca7f2c53fa2d2d1619957e56920
5
+ SHA512:
6
+ metadata.gz: 032d8cd4eeed7999567457298f078cc965f85381794d07941ebbb65f097e020d79c7341002576d4acdeb9b67624e9cdfb2743d294b153a9853b8efad39e25b78
7
+ data.tar.gz: 6a99d497e3a53925fb3e85c6951a8d7641763326a0b4fb2cc6dad5b6b0542cc80af522e7867b88fbfa274ef3184c0b3a0448ea34a870f2b82b99ff2de86cbd73
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in azericard.gemspec
4
+ gemspec
@@ -0,0 +1,24 @@
1
+ Copyright (c) 2013-2023 Nihad Abbasov <mail@narkoz.me>
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+
10
+ 2. Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24
+ POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,65 @@
1
+ # Azericard
2
+
3
+ Responsible for one of the most discussed and popular web projects of 2013,
4
+ Nihad Abbasov returns to GitHub with a gem that could well follow in its
5
+ footsteps - Azericard.
6
+
7
+ ## Installation
8
+
9
+ ```ruby
10
+ gem 'azericard'
11
+ # gem 'azericard', github: 'NARKOZ/azericard'
12
+ ```
13
+
14
+ ## Configuration
15
+
16
+ ```ruby
17
+ Azericard.configure do |config|
18
+ config.endpoint = Settings.azericard.endpoint
19
+ config.terminal = Settings.azericard.terminal
20
+ config.secret_key = Settings.azericard.secret_key
21
+
22
+ config.merchant_name = Settings.azericard.merchant_name
23
+ config.merchant_email = Settings.azericard.merchant_email
24
+ config.merchant_url = Settings.azericard.merchant_url
25
+ config.country_code = Settings.azericard.country_code
26
+ config.gmt_offset = Settings.azericard.gmt_offset
27
+ end
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ ```ruby
33
+ # Payment authorization
34
+ options = {
35
+ amount: @order.amount,
36
+ currency: @order.currency,
37
+ order: @order.number,
38
+ tr_type: 0,
39
+ desc: @order.description,
40
+ backref: azericard_callback_url
41
+ }
42
+ request_options = Azericard::Request.options_for_request(options)
43
+ p_sign = Azericard::Request.generate_mac(request_options.text_to_sign)
44
+
45
+ # Checkout transaction
46
+ options = {
47
+ amount: @order.amount,
48
+ currency: @order.currency,
49
+ order: @order.number,
50
+ tr_type: 21,
51
+ rrn: @order.payment.rrn,
52
+ intref: @order.payment.intref
53
+ }
54
+ request_options = Azericard::Request.options_for_request(options)
55
+
56
+ begin
57
+ Azericard::Request.process request_options
58
+ rescue Azericard::Error => e
59
+ e.message
60
+ end
61
+ ```
62
+
63
+ ## Copyright
64
+
65
+ Copyright (c) 2013-2023 Nihad Abbasov
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'azericard/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "azericard"
8
+ spec.version = Azericard::VERSION
9
+ spec.authors = ["Nihad Abbasov"]
10
+ spec.email = ["mail@narkoz.me"]
11
+ spec.description = "Provides an interface to AzeriCard online payment processing system"
12
+ spec.summary = "A gem to provide a ruby interface for Azericard electronic payment system"
13
+ spec.homepage = "https://github.com/narkoz/azericard"
14
+
15
+ spec.files = `git ls-files`.split($/)
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_runtime_dependency 'typhoeus'
21
+ spec.add_development_dependency 'rake'
22
+ end
@@ -0,0 +1,17 @@
1
+ require 'azericard/version'
2
+ require 'azericard/configuration'
3
+ require 'azericard/error'
4
+ require 'azericard/request'
5
+ require 'typhoeus'
6
+
7
+ module Azericard
8
+ extend Configuration
9
+
10
+ AzericardOptions = Struct.new(
11
+ :nonce, :timestamp,
12
+ :amount, :currency, :order, :tr_type,
13
+ :desc, :backref,
14
+ :rrn, :intref,
15
+ :text_to_sign
16
+ ).freeze
17
+ end
@@ -0,0 +1,26 @@
1
+ module Azericard
2
+ module Configuration
3
+ VALID_OPTIONS_KEYS = [
4
+ :endpoint, :terminal, :secret_key, :user_agent,
5
+ :merchant_name, :merchant_url, :merchant_email, :country_code, :gmt_offset
6
+ ].freeze
7
+ DEFAULT_USER_AGENT = "Azericard Ruby Gem #{Azericard::VERSION}".freeze
8
+
9
+ attr_accessor *VALID_OPTIONS_KEYS
10
+
11
+ def self.extended(base)
12
+ base.reset
13
+ end
14
+
15
+ def configure
16
+ yield self
17
+ end
18
+
19
+ def reset
20
+ VALID_OPTIONS_KEYS.each do |key|
21
+ send("#{key}=", nil)
22
+ end
23
+ self.user_agent = DEFAULT_USER_AGENT
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,5 @@
1
+ module Azericard
2
+ class Error < StandardError; end
3
+ class HTTPResponseError < Error; end
4
+ class AzericardResponseError < Error; end
5
+ end
@@ -0,0 +1,112 @@
1
+ module Azericard
2
+ module Request
3
+ # @param [Azericard::AzericardOptions] request_options
4
+ # @return [true]
5
+ # @raise [Azericard::HTTPResponseError]
6
+ # @raise [Azericard::AzericardResponseError]
7
+ def self.process(request_options)
8
+ p_sign = generate_mac(request_options.text_to_sign)
9
+
10
+ request = Typhoeus::Request.new(
11
+ Azericard.endpoint,
12
+ method: :post,
13
+ followlocation: true,
14
+ ssl_verifypeer: false,
15
+ ssl_verifyhost: 2,
16
+ cainfo: 'a.cer',
17
+ body: {
18
+ "AMOUNT" => request_options.amount,
19
+ "CURRENCY" => request_options.currency,
20
+ "ORDER" => request_options.order,
21
+ "RRN" => request_options.rrn,
22
+ "INT_REF" => request_options.intref,
23
+ "TERMINAL" => Azericard.terminal,
24
+ "TRTYPE" => request_options.tr_type,
25
+ "TIMESTAMP" => request_options.timestamp,
26
+ "NONCE" => request_options.nonce,
27
+ "P_SIGN" => p_sign
28
+ }
29
+ )
30
+
31
+ response = request.run
32
+
33
+ if response.success?
34
+ if response.body == '0'
35
+ true
36
+ else
37
+ raise AzericardResponseError, "Azericard responded with: #{response.body[0..4]}"
38
+ end
39
+ else
40
+ raise HTTPResponseError, "Azericard request failed: #{response.code}"
41
+ end
42
+ end
43
+
44
+ # @param [Hash] options
45
+ # @return [Azericard::AzericardOptions]
46
+ def self.options_for_request(options={})
47
+ nonce = SecureRandom.hex(8)
48
+ timestamp = Time.now.utc.strftime('%Y%m%d%H%M%S')
49
+ merch_name = Azericard.merchant_name
50
+ merch_url = Azericard.merchant_url
51
+ terminal = Azericard.terminal.to_s
52
+ email = Azericard.merchant_email
53
+ country = Azericard.country_code
54
+ merch_gmt = Azericard.gmt_offset
55
+
56
+ desc = backref = rrn = intref = nil
57
+
58
+ # Order total amount in float format with decimal point separator
59
+ amount = options.fetch(:amount).to_f.to_s
60
+
61
+ # Order currency: 3-character currency code
62
+ currency = options.fetch(:currency)
63
+
64
+ # Merchant order ID
65
+ order = options.fetch(:order).to_s
66
+
67
+ # Operation type
68
+ #
69
+ # 0 - auth
70
+ # 21 - checkout
71
+ # 24 - reversal
72
+ tr_type = options.fetch(:tr_type).to_s
73
+
74
+ if tr_type == '0'
75
+ # Order description
76
+ desc = options.fetch(:desc).to_s
77
+
78
+ # Merchant URL for posting authorization result
79
+ backref = options.fetch(:backref)
80
+
81
+ text_to_sign = "#{amount.size}#{amount}#{currency.size}#{currency}#{order.size}#{order}" \
82
+ "#{desc.size}#{desc}#{merch_name.size}#{merch_name}#{merch_url.size}#{merch_url}-" \
83
+ "#{terminal.size}#{terminal}#{email.size}#{email}#{tr_type.size}#{tr_type}#{country.size}#{country}" \
84
+ "#{merch_gmt.size}#{merch_gmt}#{timestamp.size}#{timestamp}#{nonce.size}#{nonce}#{backref.size}#{backref}"
85
+ elsif tr_type == '21' || tr_type == '24'
86
+ # Merchant bank's retrieval reference number
87
+ rrn = options.fetch(:rrn).to_s
88
+
89
+ # E-Commerce gateway internal reference number
90
+ intref = options.fetch(:intref)
91
+
92
+ text_to_sign = "#{order.size}#{order}#{amount.size}#{amount}#{currency.size}#{currency}" \
93
+ "#{rrn.size}#{rrn}#{intref.size}#{intref}#{tr_type.size}#{tr_type}#{terminal.size}#{terminal}" \
94
+ "#{timestamp.size}#{timestamp}#{nonce.size}#{nonce}"
95
+ end
96
+
97
+ AzericardOptions.new(nonce, timestamp, amount, currency, order, tr_type, desc, backref, rrn, intref, text_to_sign)
98
+ rescue KeyError => e
99
+ e.message
100
+ end
101
+
102
+ # Generates MAC – Message Authentication Code
103
+ def self.generate_mac(text_to_sign)
104
+ OpenSSL::HMAC.hexdigest('sha1', hex2bin(Azericard.secret_key), text_to_sign)
105
+ end
106
+
107
+ # Decodes a hexadecimally encoded binary string
108
+ def self.hex2bin(str)
109
+ str.scan(/../).map { |x| x.to_i(16).chr }.join
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,3 @@
1
+ module Azericard
2
+ VERSION = "1.0.0"
3
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: azericard
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Nihad Abbasov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: typhoeus
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Provides an interface to AzeriCard online payment processing system
42
+ email:
43
+ - mail@narkoz.me
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - .gitignore
49
+ - Gemfile
50
+ - LICENSE.txt
51
+ - README.md
52
+ - Rakefile
53
+ - azericard.gemspec
54
+ - lib/azericard.rb
55
+ - lib/azericard/configuration.rb
56
+ - lib/azericard/error.rb
57
+ - lib/azericard/request.rb
58
+ - lib/azericard/version.rb
59
+ homepage: https://github.com/narkoz/azericard
60
+ licenses: []
61
+ metadata: {}
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirements: []
77
+ rubyforge_project:
78
+ rubygems_version: 2.1.7
79
+ signing_key:
80
+ specification_version: 4
81
+ summary: A gem to provide a ruby interface for Azericard electronic payment system
82
+ test_files: []