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 +7 -0
- data/README.md +112 -0
- data/lib/generators/saman/install_generator.rb +16 -0
- data/lib/generators/saman/templates/saman_initializer.rb +27 -0
- data/lib/saman.rb +29 -0
- data/lib/saman/authorize.rb +97 -0
- data/lib/saman/configuration.rb +43 -0
- data/lib/saman/health_check.rb +34 -0
- data/lib/saman/verify.rb +44 -0
- metadata +92 -0
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
|
data/lib/saman/verify.rb
ADDED
@@ -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: []
|