bank_gateway_saman 1.0.3

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
+ SHA256:
3
+ metadata.gz: 9f9d330650a5d8e565bd23bace6fcb4676318999401cf1979c9538f6c7ede722
4
+ data.tar.gz: 77b6be29455d19fca08b02f9df935b6041b0a859fc316ded723d2af8784d6940
5
+ SHA512:
6
+ metadata.gz: a545e5e4e84896b6be9a021885b595bdcb39cf285cb3d94a5da35dcb289de09c6f0437c3583412338486c06e19288db687d6e582ef97ddd720d98ef96b629d57
7
+ data.tar.gz: c369ee1f9ba760b6291c6f0b6af97d1096ebc06b9709718c4db523ecd6cf8798c2af37f6fae3bb1c1e11033da76555d7ebfb10fc6dd54541c1faffd9bec013f5
data/README.md ADDED
@@ -0,0 +1,112 @@
1
+ # Saman
2
+
3
+ [Coverage Report](http://amirhosein.zlf.gitlab.io/bank_gateway_saman/)
4
+
5
+ This gem will help you to handle all required requests for using Saman gateway using ruby
6
+
7
+ ## Install
8
+ ### Using in ruby
9
+ - Add `saman` gem to your Gemfile
10
+
11
+ `gem 'saman'`
12
+
13
+ - Run bundle install
14
+
15
+ `bundle install`
16
+
17
+ ### Using in Rails
18
+ - Add `saman` gem to your Gemfile
19
+
20
+ `gem 'saman'`
21
+
22
+ - Run bundle install
23
+
24
+ `bundle install`
25
+
26
+ - Create the initializer for it
27
+
28
+ `bundle exec rails g saman:install`
29
+
30
+ ### How to use it?
31
+
32
+ #### Configurations
33
+
34
+ For `rails` applications it will generate an `initializer` file called `saman.rb` which you could set all the required configurations.
35
+
36
+ If you are using this gem in a `ruby`
37
+ script, you should set the configurations like below before calling any methods.
38
+
39
+ ```
40
+ Saman.configure do |config|
41
+ # config.username = config_hash[:username]
42
+ # config.password = config_hash[:password]
43
+
44
+ # config.proxy = config_hash[:proxy]
45
+ # e.g. config.proxy = 'http://localhost:8080/'
46
+
47
+ # config.terminal_id_default = config_hash[:terminal_id_default]
48
+
49
+ # a terminal id which support multi account
50
+ # config.terminal_id_with_wage = config_hash[:terminal_id_with_wage]
51
+
52
+ # a termianl id which is needed for you wage account
53
+ # config.terminal_id_wage_only = config_hash[:terminal_id_wage_only]
54
+
55
+ # config.retry_count = config_hash[:retry_count]
56
+ # config.authorize_wsdl = config_hash[:authorize_wsdl]
57
+ # config.authorize_address = config_hash[:authorize_address]
58
+ # config.verify_wsdl = config_hash[:verify_wsdl]
59
+ end
60
+
61
+ ```
62
+
63
+ #### Is gateway ready?
64
+ You can check if the Saman gateway is ready or not, this method always return a `boolean` value
65
+
66
+ `Saman.up?`
67
+
68
+ #### How get a token from gateway?
69
+ The `authorize` method get a token for you from bank and it returns a response like below
70
+ `Saman.authorize(params)`
71
+ ```
72
+ {
73
+ method: 'POST',
74
+ fields: {
75
+ Token: 'generated_token'
76
+ },
77
+ url: 'http://sample.com/'
78
+ }
79
+ ```
80
+ This means you should submit a from by `POST` request to `http://sample.com/` with a field named `Token` and value of `generated_token`
81
+
82
+ The required params for generating a token are like below
83
+ ```
84
+ {
85
+ "amount": 3000,
86
+ "order_id": 128,
87
+ "customer": {
88
+ "mobile_number": "09128987989"
89
+ },
90
+ "split_amount": {
91
+ "amount": 1500,
92
+ "wage": 1500
93
+ },
94
+ "redirect_url": "http://localhost"
95
+ }
96
+ ```
97
+ NOTE: if you do not want to use `split_amount` feature, just pass the `amount` and ignore that.
98
+
99
+
100
+ #### How verify a payment?
101
+
102
+ For verifying a payment, you just need to pass the parameters which were sending to you from gateway like below and this method returns a boolean after calling verify.
103
+
104
+ `Saman.verify(posted_params)`
105
+
106
+ ### Development
107
+ if you want to change the gem, you could easily clone it and do whatever you want
108
+
109
+ After your changes always run `specs` and `rubocop` to make sure about the code quality
110
+
111
+ - `rspec spec`
112
+ - `rubocop --format html > rubocop.html`
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+ module Saman
5
+ module Generators
6
+ # Install generator class for saman gem using in rails
7
+ class InstallGenerator < Rails::Generators::Base
8
+ source_root File.expand_path('../templates', __FILE__)
9
+ desc 'Creates Saman initializer for your application'
10
+
11
+ def copy_initializer
12
+ template 'saman_initializer.rb', 'config/initializers/saman.rb'
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ Saman.configure do |config|
4
+ # You can read config from a file
5
+ # config_hash = Rails.application.config_for(:saman)
6
+ # config.username = config_hash[:username]
7
+ # config.password = config_hash[:password]
8
+
9
+ # config.proxy = config_hash[:proxy]
10
+ # e.g. config.proxy = 'http://localhost:8080/'
11
+
12
+ # config.terminal_id_default = config_hash[:terminal_id_default]
13
+
14
+ # a terminal id which support multi account
15
+ # config.terminal_id_with_wage = config_hash[:terminal_id_with_wage]
16
+
17
+ # a termianl id which is needed for you wage account
18
+ # config.terminal_id_wage_only = config_hash[:terminal_id_wage_only]
19
+
20
+ # config.retry_count = config_hash[:retry_count]
21
+ # config.authorize_wsdl = config_hash[:authorize_wsdl]
22
+ # config.authorize_address = config_hash[:authorize_address]
23
+ # config.verify_wsdl = config_hash[:verify_wsdl]
24
+
25
+ # or you can set all the configs from environment variables
26
+ # like ENV['saman_username']
27
+ end
data/lib/saman.rb ADDED
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'saman/authorize'
4
+ require_relative 'saman/verify'
5
+ require_relative 'saman/health_check'
6
+ require_relative 'saman/configuration'
7
+ require_relative 'generators/saman/install_generator'
8
+
9
+ require 'savon'
10
+ require 'yaml'
11
+ require 'rest-client'
12
+ require 'json'
13
+
14
+ # Saman gateway module to handle requests
15
+ module Saman
16
+ attr_accessor :config
17
+
18
+ def self.authorize(params)
19
+ Saman::Client.new.authorize(params)
20
+ end
21
+
22
+ def self.verify(params)
23
+ Saman::Client.new.verify(params)
24
+ end
25
+
26
+ def self.up?
27
+ Saman::Client.new.health_check
28
+ end
29
+ end
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Saman module for gateway communications
4
+ module Saman
5
+ # extend Client class to handle authorize method
6
+ class Client
7
+ def authorize(params)
8
+ config = Saman.configuration
9
+ request_parameters = create_authorize_parameters(params)
10
+ response = send_rest_requests(
11
+ config.authorize_address,
12
+ request_parameters,
13
+ config.retry_count
14
+ )
15
+ raise response[:error] unless response.is_a? RestClient::Response
16
+ authorize_result(response)
17
+ end
18
+
19
+ private
20
+
21
+ def authorize_result(response)
22
+ token = parse_authorize_result(response)
23
+ {
24
+ method: 'POST',
25
+ fields: {
26
+ Token: token
27
+ },
28
+ url: Saman.configuration.authorize_address
29
+ }
30
+ end
31
+
32
+ def create_authorize_parameters(params)
33
+ {
34
+ Action: 'Token',
35
+ Amount: calculate_the_amount(params),
36
+ Wage: calculate_the_wage(params),
37
+ TerminalId: get_terminal_id(params),
38
+ ResNum: params[:order_id],
39
+ RedirectUrl: params[:redirect_url],
40
+ CellNumber: params[:customer][:mobile_number]
41
+ }
42
+ end
43
+
44
+ def get_terminal_id(params)
45
+ case params[:split_amount]&.count
46
+ when nil
47
+ Saman.configuration.terminal_id_default
48
+ when 1
49
+ return Saman.configuration.terminal_id_wage_only if \
50
+ params[:split_amount].key?(:wage)
51
+ Saman.configuration.terminal_id_default
52
+ else
53
+ Saman.configuration.terminal_id_with_wage
54
+ end
55
+ end
56
+
57
+ def calculate_the_wage(params)
58
+ return 0 unless multiple_accounts?(params)
59
+ return 0 if params[:split_amount].count == 1
60
+
61
+ params[:split_amount][:wage] || 0
62
+ end
63
+
64
+ def calculate_the_amount(params)
65
+ return params[:amount] unless multiple_accounts?(params)
66
+ return params[:amount] if params[:split_amount].count == 1
67
+
68
+ params[:split_amount][:amount] || 0
69
+ end
70
+
71
+ def multiple_accounts?(params)
72
+ params[:split_amount]&.count&.positive?
73
+ end
74
+
75
+ def parse_authorize_result(response)
76
+ token_result = JSON.parse(response.body)
77
+ token = token_result['token'] if token_result['status'].to_i == 1
78
+ raise "Code ##{token_result['errorCode']}, #{token_result['errorDesc']}" \
79
+ if token.nil?
80
+
81
+ token
82
+ end
83
+
84
+ def send_rest_requests(url, parameters, retry_to)
85
+ RestClient.proxy = Saman.configuration.proxy unless \
86
+ Saman.configuration.proxy.blank?
87
+ return RestClient.post(url, parameters.to_json, content_type: :json)
88
+ rescue RestClient::Exceptions::OpenTimeout => exception
89
+ retry if (retry_to -= 1).positive?
90
+ return { error: 'Saman is not available right now,
91
+ calling web service got time out' }
92
+ rescue StandardError => exception
93
+ retry if (retry_to -= 1).positive?
94
+ return { error: exception.message }
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Saman module for gateway communications
4
+ module Saman
5
+ class << self
6
+ attr_accessor :configuration
7
+ end
8
+
9
+ def self.configure
10
+ self.configuration ||= Configuration.new
11
+ yield(configuration)
12
+ end
13
+
14
+ # configure class
15
+ class Configuration
16
+ attr_accessor :username
17
+ attr_accessor :password
18
+ attr_accessor :proxy
19
+ attr_accessor :terminal_id_default
20
+ attr_accessor :terminal_id_with_wage
21
+ attr_accessor :terminal_id_wage_only
22
+ attr_writer :retry_count
23
+ attr_writer :authorize_wsdl
24
+ attr_writer :authorize_address
25
+ attr_writer :verify_wsdl
26
+
27
+ def authorize_address
28
+ @authorize_address || 'https://sep.shaparak.ir/MobilePG/MobilePayment'
29
+ end
30
+
31
+ def verify_wsdl
32
+ @verify_wsdl || 'https://verify.sep.ir/payments/referencepayment.asmx?wsdl'
33
+ end
34
+
35
+ def authorize_wsdl
36
+ @authorize_wsdl || 'https://sep.shaparak.ir/payments/initpayment.asmx?wsdl'
37
+ end
38
+
39
+ def retry_count
40
+ @retry_count || 3
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Saman
4
+ # Client class to handle requests
5
+ class Client
6
+ def health_check
7
+ authorize_up? && verify_up?
8
+ end
9
+
10
+ def verify_up?
11
+ verify_client = Savon.client(wsdl: Saman.configuration.verify_wsdl)
12
+ expected_operations_for_verify = %i[
13
+ verify_transaction
14
+ verify_transaction1
15
+ ]
16
+
17
+ (expected_operations_for_verify - verify_client.operations).empty?
18
+ rescue StandardError
19
+ return false
20
+ end
21
+
22
+ def authorize_up?
23
+ authorize_client = Savon.client(wsdl: Saman.configuration.authorize_wsdl)
24
+ expected_operations_for_authorize = %i[
25
+ request_token
26
+ request_multi_settle_type_token
27
+ ]
28
+
29
+ (expected_operations_for_authorize - authorize_client.operations).empty?
30
+ rescue StandardError
31
+ return false
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Saman module for gateway communications
4
+ module Saman
5
+ # extend Client class to handle verify method
6
+ class Client
7
+ def verify(params)
8
+ return false unless params[:State] == 'OK'
9
+ verify_the_payment(params)
10
+ end
11
+
12
+ private
13
+
14
+ def verify_the_payment(params)
15
+ savon_client = create_savon_client_for_verify
16
+ request_parameters = {
17
+ String_1: params[:RefNum],
18
+ String_2: params[:TerminalId]
19
+ }
20
+ response = send_verify_request(savon_client, request_parameters)
21
+ raise response[:error] if response.to_hash.include? :error
22
+ last_response = response.body[:verify_transaction_response][:result].to_i
23
+ last_response.positive?
24
+ end
25
+
26
+ def create_savon_client_for_verify
27
+ config = Saman.configuration
28
+ options = {
29
+ wsdl: config.verify_wsdl,
30
+ convert_request_keys_to: :none
31
+ }
32
+ options['proxy'] = config.proxy unless config.proxy.blank?
33
+
34
+ Savon.client(options)
35
+ end
36
+
37
+ def send_verify_request(client, parameters, retry_to = 3)
38
+ client.call(:verify_transaction, message: parameters)
39
+ rescue StandardError => exception
40
+ retry if (retry_to -= 1).positive?
41
+ return { error: exception.message }
42
+ end
43
+ end
44
+ end
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bank_gateway_saman
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Amirhosein Zolfaghari
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2010-06-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rest-client
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.0.2
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.0.2
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: 2.0.2
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 2.0.2
33
+ - !ruby/object:Gem::Dependency
34
+ name: savon
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 2.12.0
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 2.12.0
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: 2.12.0
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 2.12.0
53
+ description: Help you to handle all requests to saman payment gateway
54
+ email: amirhosein@zolfaghari.me
55
+ executables: []
56
+ extensions: []
57
+ extra_rdoc_files:
58
+ - README.md
59
+ files:
60
+ - README.md
61
+ - lib/generators/saman/install_generator.rb
62
+ - lib/generators/saman/templates/saman_initializer.rb
63
+ - lib/saman.rb
64
+ - lib/saman/authorize.rb
65
+ - lib/saman/configuration.rb
66
+ - lib/saman/health_check.rb
67
+ - lib/saman/verify.rb
68
+ homepage: https://gitlab.com/amirhosein.zlf/bank_gateway_saman
69
+ licenses:
70
+ - MIT
71
+ metadata: {}
72
+ post_install_message:
73
+ rdoc_options: []
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - "~>"
79
+ - !ruby/object:Gem::Version
80
+ version: '2.4'
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirements: []
87
+ rubyforge_project:
88
+ rubygems_version: 2.7.3
89
+ signing_key:
90
+ specification_version: 4
91
+ summary: Help you to communicate better with saman payment gateway
92
+ test_files: []