parsbank 0.0.5 → 0.0.8
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.
- checksums.yaml +4 -4
- data/README.md +5 -3
- data/lib/db_setup.rb +103 -0
- data/lib/locales/en.yml +18 -0
- data/lib/locales/fa.yml +19 -0
- data/lib/parsbank/{bsc-bitcoin/bsc-bitcoin.rb → binance/binance.rb} +2 -1
- data/lib/parsbank/gates.rb +16 -0
- data/lib/parsbank/mellat/logo.svg +1 -0
- data/lib/parsbank/mellat/mellat.rb +2 -6
- data/lib/parsbank/nobitex/logo.svg +6 -0
- data/lib/parsbank/nobitex/nobitex.rb +1 -15
- data/lib/parsbank/restfull.rb +35 -23
- data/lib/parsbank/soap.rb +106 -0
- data/lib/parsbank/transaction_request.rb +134 -0
- data/lib/parsbank/transaction_verify.rb +135 -0
- data/lib/parsbank/version.rb +1 -1
- data/lib/parsbank/zarinpal/logo.svg +1 -1
- data/lib/parsbank/zarinpal/zarinpal.rb +89 -60
- data/lib/parsbank/zibal/zibal.rb +1 -18
- data/lib/parsbank.rb +25 -185
- data/lib/psp.json +82 -76
- data/lib/tmpl/_loader.html.erb +105 -0
- data/lib/tmpl/bank_list.html.erb +215 -0
- metadata +15 -18
- /data/lib/parsbank/{bsc-bitcoin/bsc-bitcoin.svg → binance/logo.svg} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c6774ac55b53a31e7df4982c3b01e9693edd7a481f748c38bc061941c267870
|
4
|
+
data.tar.gz: ef51aa116673b80e5affff7cdb939d50ca39763210b981b43667b7db9da287ad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee11744864df67b0d88495722594309df70d57bc79464c346011ac75f8209c14fd4c84b1346b27bd27a17daf3392932696d759c18ca8f6e110fe32d4056251f7
|
7
|
+
data.tar.gz: f3a0a594e3e6d032a67c5cfe4b2f22f20f527c66a448b7ff5c002b07a76eda6106d958e1b39b9ee278b623a8edafa248807cfa0fb5eb07291fe6455e3143e82b
|
data/README.md
CHANGED
@@ -54,7 +54,7 @@ ParsBank.configuration do |config|
|
|
54
54
|
config.mitm_server = 'https://your-mitm-server.com' # MITM server location
|
55
55
|
config.secrets_path = Rails.root.join('config/bank_secrets.yaml') # Path to bank credentials (e.g., merchant ID, tokens)
|
56
56
|
|
57
|
-
# Web Panel Configuration
|
57
|
+
# Web Panel Configuration For Pro Users
|
58
58
|
config.webpanel_path = '/parsbank' # Web panel path
|
59
59
|
config.username = ENV['PARSBANK_USERNAME'] # Web panel username
|
60
60
|
config.password = ENV['PARSBANK_PASSWORD'] # Web panel password
|
@@ -84,8 +84,8 @@ class CartController < ApplicationController
|
|
84
84
|
# @INPUT tags: Used for call which payments method such as ['crypto','rls','dollar','persian-banks','russian-banks']
|
85
85
|
# @OUTPUT get_redirect_from: an javascript code for redirect user to gateways
|
86
86
|
def redirect_to_parsbank
|
87
|
-
form = ParsBank.
|
88
|
-
render html:
|
87
|
+
form = ParsBank.transaction_request(fiat_amount: '10', description: 'Charge Account')
|
88
|
+
render html: from.html_form
|
89
89
|
end
|
90
90
|
|
91
91
|
# @DESC: Shortcode for get all of enabled paymetns methods
|
@@ -93,6 +93,8 @@ class CartController < ApplicationController
|
|
93
93
|
# @OUTPUT gateways_list_shortcode: List of all banks with name and logo with ul wrapper as html
|
94
94
|
def choose_payment
|
95
95
|
@payments_list_available_shortcode = ParsBank.gateways_list_shortcode
|
96
|
+
# ..OR..
|
97
|
+
@available_gateways_list = ParsBank.Parsbank.available_gateways_list
|
96
98
|
end
|
97
99
|
|
98
100
|
# @DESC: Parse all returned params from banks for verify transaction
|
data/lib/db_setup.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Parsbank
|
4
|
+
class DBSetup
|
5
|
+
def self.establish_connection
|
6
|
+
if Parsbank.configuration.database_url.present?
|
7
|
+
setup_db
|
8
|
+
else
|
9
|
+
simulate_db
|
10
|
+
puts("\033[31mParsBank ERROR: database_url not set, Transaction history not stored on database\033[0m")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.simulate_db
|
15
|
+
model_name = Parsbank.configuration.model || 'Transaction'
|
16
|
+
simulated_model = Class.new do
|
17
|
+
attr_accessor :description, :amount, :gateway, :callback_url, :status,
|
18
|
+
:user_id, :cart_id, :local_id, :ip, :gateway_verify_response, :gateway_response, :track_id, :unit, :created_at, :updated_at
|
19
|
+
|
20
|
+
def initialize(attributes = {})
|
21
|
+
build_attrs attributes.merge({created_at: Time.now})
|
22
|
+
end
|
23
|
+
|
24
|
+
def update!(attributes = {})
|
25
|
+
build_attrs attributes.merge({updated_at: Time.now})
|
26
|
+
end
|
27
|
+
|
28
|
+
def build_attrs attributes = {}
|
29
|
+
attributes.each do |key, value|
|
30
|
+
send("#{key}=", value)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
def save
|
34
|
+
# Simulate saving (e.g., print or log the data)
|
35
|
+
@id = Time.now.to_i # Simulate an ID assignment
|
36
|
+
true
|
37
|
+
end
|
38
|
+
|
39
|
+
attr_reader :id
|
40
|
+
end
|
41
|
+
|
42
|
+
# Set the simulated class as a constant
|
43
|
+
Object.const_set(model_name.camelcase, simulated_model)
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.setup_db
|
47
|
+
database_url = Parsbank.configuration.database_url
|
48
|
+
model = Parsbank.configuration.model
|
49
|
+
raise 'DATABASE_URL environment variable is not set' if database_url.nil?
|
50
|
+
|
51
|
+
supported_databases = {
|
52
|
+
'postgresql' => 'pg',
|
53
|
+
'mysql2' => 'mysql2',
|
54
|
+
'sqlite3' => 'sqlite3',
|
55
|
+
'nulldb' => 'nulldb'
|
56
|
+
}.freeze
|
57
|
+
|
58
|
+
uri = URI.parse(database_url)
|
59
|
+
|
60
|
+
gem_name = supported_databases[uri.scheme]
|
61
|
+
unless gem_name
|
62
|
+
raise "Unsupported database adapter: #{uri.scheme}. Supported adapters: #{supported_databases.keys.join(', ')}"
|
63
|
+
end
|
64
|
+
|
65
|
+
begin
|
66
|
+
require gem_name
|
67
|
+
rescue LoadError
|
68
|
+
raise "Missing required gem for #{uri.scheme}. Please add `gem '#{gem_name}'` to your Gemfile."
|
69
|
+
end
|
70
|
+
|
71
|
+
begin
|
72
|
+
ActiveRecord::Base.establish_connection(database_url)
|
73
|
+
unless ActiveRecord::Base.connection.table_exists?(model.tableize)
|
74
|
+
puts 'Create Transaction Table'
|
75
|
+
ActiveRecord::Base.connection.create_table model.tableize do |t|
|
76
|
+
t.string :gateway
|
77
|
+
t.string :amount
|
78
|
+
t.string :unit
|
79
|
+
t.string :track_id
|
80
|
+
t.string :local_id
|
81
|
+
t.string :ip
|
82
|
+
t.integer :user_id
|
83
|
+
t.integer :cart_id
|
84
|
+
t.text :description
|
85
|
+
t.string :callback_url
|
86
|
+
t.text :gateway_verify_response
|
87
|
+
t.text :gateway_response
|
88
|
+
t.string :status
|
89
|
+
t.timestamps
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
unless Object.const_defined?(model)
|
94
|
+
Object.const_set(model, Class.new(ActiveRecord::Base) do
|
95
|
+
self.table_name = model.tableize
|
96
|
+
end)
|
97
|
+
end
|
98
|
+
rescue StandardError => e
|
99
|
+
raise "Failed to connect to the database: #{e.message}"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/lib/locales/en.yml
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
en:
|
2
|
+
actions:
|
3
|
+
redirect_to_gate: "You are being redirected to the payment gateway..."
|
4
|
+
success: "The operation was successful"
|
5
|
+
failed: "The operation encountered an error"
|
6
|
+
uncertain: "The operation status is temporarily uncertain"
|
7
|
+
bank_names:
|
8
|
+
nobitex: "Nobitex"
|
9
|
+
mellat: "Mellat Bank"
|
10
|
+
zarinpal: "Zarinpal"
|
11
|
+
zibal: "Zibal"
|
12
|
+
binance: "Binance"
|
13
|
+
bank_list:
|
14
|
+
nobitex: "You are making a cryptocurrency payment through the Nobitex gateway. Please note that you can use two methods: Tether (USDT-TRC20) and Bitcoin (BTC-Lightning)."
|
15
|
+
zarinpal: "You are making a payment through the Zarinpal gateway."
|
16
|
+
mellat: "You are making a payment through the Mellat Bank direct payment gateway."
|
17
|
+
zibal: "You are making a payment through the Zibal gateway."
|
18
|
+
binance: "You are making a cryptocurrency payment through Binance."
|
data/lib/locales/fa.yml
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
fa:
|
2
|
+
actions:
|
3
|
+
redirect_to_gate: "در حال انتقال به درگاه پرداخت هستید"
|
4
|
+
success: "عملیات با موفقیت انجام شد"
|
5
|
+
failed: "عملیات با خطا مواجه شد"
|
6
|
+
uncertain: "به طور موقت وضعیت عملیات نامشخص است"
|
7
|
+
bank_names:
|
8
|
+
nobitex: "نوبیتکس"
|
9
|
+
mellat: "بانک ملت"
|
10
|
+
zarinpal: "زرینپال"
|
11
|
+
zibal: "زیبال"
|
12
|
+
binance: "بایننس"
|
13
|
+
bank_list:
|
14
|
+
nobitex: " شما درحال پرداخت کریپتویی از طریق درگاه پرداخت نوبیتکس میباشید, توجه داشته باشید که شما میتوانید از دو روش تتر(USDT-TRC20) و بیت کوین(BTC-lightcoin) استفاده کنید"
|
15
|
+
zarinpal: "شما در حال پراخت با درگاه زرین پال میباشید"
|
16
|
+
mellat: "شما در حال پرداخت با درگاه پرداخت مستقیم بانک ملت میباشید"
|
17
|
+
zibal: "شما در حال پرداخت با درگاه زیبال میباشید"
|
18
|
+
binance: "شما در حال پرداخت پرداخت کریپتویی از طریق بایننس میباشید"
|
19
|
+
|
@@ -4,7 +4,7 @@ require 'openssl'
|
|
4
4
|
require 'base64'
|
5
5
|
|
6
6
|
module Parsbank
|
7
|
-
class
|
7
|
+
class Binance < Gates
|
8
8
|
|
9
9
|
attr_accessor :api_key, :secret_key, :endpoint
|
10
10
|
|
@@ -18,6 +18,7 @@ module Parsbank
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
+
|
21
22
|
# Generate a payment address for a given cryptocurrency
|
22
23
|
def generate_payment_address(asset:, network: nil)
|
23
24
|
endpoint = '/sapi/v1/capital/deposit/address'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Parsbank
|
2
|
+
class Gates
|
3
|
+
def self.logo
|
4
|
+
File.read "#{__dir__}/#{self.class.name.split('::').last.downcase}/logo.svg"
|
5
|
+
end
|
6
|
+
|
7
|
+
def default_config(key)
|
8
|
+
Parsbank.load_secrets_yaml[self.class.name.split('::').last.downcase][key.to_s]
|
9
|
+
end
|
10
|
+
|
11
|
+
def redirect_loaders(&block)
|
12
|
+
content = block_given? ? block.call : ''
|
13
|
+
ERB.new(File.read("#{__dir__}/../tmpl/_loader.html.erb")).result(binding).gsub(/\s+/, ' ').strip
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" xml:space="preserve" enable-background="new 0 0 190 190" viewBox="15 0 190 180"><g><radialGradient id="SVGID_1_" cx="102.0404663" cy="41.313755" r="37.7397079" fx="78.5114517" fy="20.3117523" gradientUnits="userSpaceOnUse"><stop offset="0" style="stop-color:#FFFFFF"></stop><stop offset="0.0255132" style="stop-color:#FDF8F8"></stop><stop offset="0.2973083" style="stop-color:#EEADB4"></stop><stop offset="0.5401202" style="stop-color:#E1717E"></stop><stop offset="0.745488" style="stop-color:#D94657"></stop><stop offset="0.9052967" style="stop-color:#D32C3F"></stop><stop offset="1" style="stop-color:#D12236"></stop></radialGradient><path fill-rule="evenodd" clip-rule="evenodd" fill="url(#SVGID_1_)" stroke="#AA1F00" stroke-width="3" d=" M154.9982605,35.2635803v17.4064026l-44.9999542-25.9817524c-2-1.154747-4.5000381,0.2886276-4.5000381,2.5980511v30.0937233 c-14.4299927,2.1699829-25.5,14.6199951-25.5,29.6599731c0,3.8600464,0.7299805,7.5400391,2.0700073,10.9299927 l-17.0700073,9.8500366v-74.556427c0-3.5727024,1.9060364-6.8740082,5.0001068-8.6603203l35-20.2066498 c3.093956-1.7862411,6.9058228-1.7862411,9.9997787,0l35,20.2066498 C153.0922241,28.3895721,154.9982605,31.6908779,154.9982605,35.2635803z"></path><path fill="#D12236" stroke="#AA1F00" stroke-width="3" d="M40.9271736,76.959938l15.0739479-8.7032013v51.9619827 c-0.0000381,2.3094254,2.4995384,3.7528381,4.4995613,2.5981293l26.061924-15.0468674 c9.0942612,11.4117508,25.411293,14.7736511,38.4362946,7.2536621c3.3428955-1.9300232,6.1648712-4.4021988,8.4306488-7.2576752 l17.0653839,9.8580475l-64.5677567,37.2782059c-3.0940552,1.7863617-6.9060898,1.7863312-10.0001144-0.000061 l-34.9994774-20.2075653c-3.0939064-1.7863159-5.000103-5.0874939-5.0001488-8.6600571V85.6203232 C35.9273911,82.0476227,37.8331223,78.7462921,40.9271736,76.959938z"></path><path fill="#D12236" stroke="#AA1F00" stroke-width="3" d="M134.0728302,154.9002228l-15.0743942-8.7032013l45.0008316-25.9802322 c2.0000458-1.1546783,2.0000763-4.0414658,0.0000458-5.1961746l-26.0619202-15.0468597 c5.3357391-13.5817337,0.0887146-29.3936462-12.9362946-36.9136391c-3.3428955-1.9300232-6.8925476-3.1378365-10.4983444-3.6723137 V39.6797218l64.570076,37.2782173c3.0940399,1.7863464,4.9997864,5.087677,4.9997253,8.6603775v40.4142151 c-0.0000458,3.5725708-1.9062347,6.8737335-5.0001373,8.6600647l-34.9994812,20.2075653 C140.9789124,156.686554,137.1668701,156.6865692,134.0728302,154.9002228z"></path><linearGradient id="SVGID_00000119836251559533381810000007217859948108605595_" gradientUnits="userSpaceOnUse" x1="134.7217255" y1="114.6244202" x2="96.320816" y2="74.8863297"><stop offset="0.0811578" style="stop-color:#FFD88B"></stop><stop offset="0.3899239" style="stop-color:#FFD667"></stop><stop offset="0.7925526" style="stop-color:#FFD33E"></stop><stop offset="1" style="stop-color:#FFD22E"></stop></linearGradient><circle fill="url(#SVGID_00000119836251559533381810000007217859948108605595_)" stroke="#FF9F00" stroke-width="3.5" cx="109.9994202" cy="89.0412445" r="21"></circle></g></svg>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Parsbank
|
2
|
-
class Mellat
|
2
|
+
class Mellat < Gates
|
3
3
|
attr_accessor :order_id, :amount, :local_date, :local_time, :additional_data, :payer_id, :callback_url
|
4
4
|
attr_reader :response, :status, :status_message, :ref_id
|
5
5
|
|
@@ -18,7 +18,7 @@ module Parsbank
|
|
18
18
|
rescue KeyError => e
|
19
19
|
raise ArgumentError, "Missing required argument: #{e.message}"
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
def validate(response = nil)
|
23
23
|
@response = response
|
24
24
|
perform_validation
|
@@ -65,10 +65,6 @@ function postRefId (refIdValue) {
|
|
65
65
|
|
66
66
|
private
|
67
67
|
|
68
|
-
def default_config(key)
|
69
|
-
Parsbank.load_secrets_yaml[self.class.name.split("::").last.downcase][key.to_s]
|
70
|
-
end
|
71
|
-
|
72
68
|
def create_wsdl_client
|
73
69
|
Savon.client(
|
74
70
|
wsdl: default_config(:wsdl) || 'https://bpm.shaparak.ir/pgwchannel/services/pgw?wsdl',
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 800 800" preserveAspectRatio="xMidYMid meet">
|
2
|
+
<path d="M0 0 C29.98287632 28.38266662 37.63391251 71.06493204 39.46484375 110.52734375 C40.31202771 154.92975 29.86598145 204.25929523 0.28125 238.5703125 C-0.30011719 239.26511719 -0.88148438 239.95992188 -1.48046875 240.67578125 C-9.81789052 249.85324551 -21.67611901 256.11718396 -33.71875 258.5703125 C-35.03875 258.5703125 -36.35875 258.5703125 -37.71875 258.5703125 C-37.32360063 257.11179369 -36.92754943 255.65351924 -36.53125 254.1953125 C-36.25925781 253.18597656 -35.98726563 252.17664063 -35.70703125 251.13671875 C-35.00172375 248.59147865 -34.27221785 246.06359208 -33.51171875 243.53515625 C-23.79117233 210.80512141 -22.35178836 174.91061391 -38.40625 143.8828125 C-46.85746156 128.35134581 -58.78064957 117.22443485 -75.71875 111.5703125 C-93.02217424 107.22355858 -110.87400028 112.8207742 -125.85644531 121.44189453 C-148.77305826 135.32765555 -164.80350975 157.6091968 -177.71875 180.5703125 C-178.05712891 181.16344238 -178.39550781 181.75657227 -178.74414062 182.36767578 C-208.06853461 234.04981757 -219.01027215 296.84557372 -220.71875 355.5703125 C-220.74211426 356.36743652 -220.76547852 357.16456055 -220.78955078 357.98583984 C-222.17370204 414.61972605 -212.37270254 471.92939392 -194.71875 525.5703125 C-194.38040131 526.60372772 -194.38040131 526.60372772 -194.03521729 527.65802002 C-175.92320978 582.95320119 -152.73773661 639.09294597 -115.71875 684.5703125 C-115.25017578 685.15312988 -114.78160156 685.73594727 -114.29882812 686.33642578 C-104.32531403 698.69721719 -93.71672552 709.72390578 -80.51953125 718.64453125 C-77.71875 720.5703125 -77.71875 720.5703125 -75.71875 722.5703125 C-132.76999776 716.17058293 -194.41700644 672.01409971 -235.1328125 633.97265625 C-237.24700441 632.00856558 -239.3916045 630.12080901 -241.59375 628.2578125 C-250.61673064 620.42654629 -259.02312328 611.69845848 -266.71875 602.5703125 C-267.56179688 601.61640625 -268.40484375 600.6625 -269.2734375 599.6796875 C-288.16365104 578.23119016 -303.83955573 554.50456846 -317.71875 529.5703125 C-318.13189453 528.83586914 -318.54503906 528.10142578 -318.97070312 527.34472656 C-341.50730026 487.03957621 -355.04945886 442.29421732 -360.71875 396.5703125 C-360.83589355 395.6534668 -360.95303711 394.73662109 -361.07373047 393.79199219 C-372.82086175 297.33634963 -344.70039279 196.68993972 -282.42016602 112.484375 C-277.06886577 105.6567691 -271.50184788 99.03548215 -265.71875 92.5703125 C-265.18701172 91.97541016 -264.65527344 91.38050781 -264.10742188 90.76757812 C-252.5193361 77.89344741 -240.1407826 65.59127078 -226.5546875 54.8203125 C-224.40784883 53.11703554 -222.29599235 51.39141688 -220.1953125 49.6328125 C-166.88571954 5.19457656 -63.78005057 -56.99883829 0 0 Z " fill="#5525AC" transform="translate(362.71875,24.4296875)"/>
|
3
|
+
<path d="M0 0 C7.18875557 0.57510045 13.62151637 2.57857541 20.4375 4.875 C21.62327637 5.27428711 22.80905273 5.67357422 24.03076172 6.08496094 C73.95241984 23.2846928 120.85879426 52.57798095 159.41015625 88.59375 C161.54656893 90.57871261 163.71442515 92.48931489 165.9375 94.375 C174.59481506 101.89128818 182.60314944 110.25255676 190 119 C190.84433594 119.95519531 191.68867187 120.91039063 192.55859375 121.89453125 C251.68342563 189.04481233 283.32387647 273.08376214 287 362 C287.03609375 362.87237305 287.0721875 363.74474609 287.109375 364.64355469 C287.28714781 369.77452252 287.21220512 374.87107802 287 380 C286.95359375 381.12245117 286.9071875 382.24490234 286.859375 383.40136719 C282.79672481 473.44908522 251.57593219 562.86358552 189.40625 629.41015625 C187.42128739 631.54656893 185.51068511 633.71442515 183.625 635.9375 C176.77654255 643.8256028 169.2153172 651.34471075 161.2421875 658.09375 C159.43131772 659.6333048 157.65363477 661.19644289 155.8828125 662.78125 C134.581492 681.7337669 110.90091013 698.1330921 86 712 C85.22817383 712.43376953 84.45634766 712.86753906 83.66113281 713.31445312 C61.34722186 725.75582345 37.86881454 735.1103659 13 741 C12.20899902 741.19062012 11.41799805 741.38124023 10.60302734 741.57763672 C-14.0261503 747.26964098 -41.07360529 746.30855798 -63 733 C-66.57427523 730.56205505 -69.80402787 727.91337009 -73 725 C-73.90492188 724.17628906 -74.80984375 723.35257813 -75.7421875 722.50390625 C-82.55872097 715.99893179 -88.0628066 709.01203152 -93 701 C-93.67804688 699.90558594 -94.35609375 698.81117188 -95.0546875 697.68359375 C-104.75569094 681.17523885 -109.91402413 661.78072782 -113 643 C-113.11569336 642.33564941 -113.23138672 641.67129883 -113.35058594 640.98681641 C-121.45061902 592.56688574 -112.46220715 533.3285866 -84.13671875 492.765625 C-74.51652786 479.73187252 -61.32260349 467.47700429 -45 464 C-41.4375 463.8125 -41.4375 463.8125 -39 464 C-40.08890231 469.1686966 -41.31437389 474.25681123 -42.80175781 479.32519531 C-52.42064617 512.23036332 -53.96518454 548.4066818 -37.16796875 579.3046875 C-28.48013523 594.48968087 -17.06767432 605.0774079 -0.48828125 610.87890625 C16.32978144 615.19664945 34.44137027 609.61550255 49.05078125 601.25390625 C67.31501746 589.61801537 81.32921441 574.09291807 93 556 C93.35626465 555.44828125 93.7125293 554.8965625 94.07958984 554.328125 C121.05400703 512.11782122 134.75622658 462.3237218 141 413 C141.15098145 411.82985352 141.30196289 410.65970703 141.45751953 409.45410156 C148.55970967 351.94704745 143.79218867 293.14526422 130 237 C129.71817871 235.84419434 129.43635742 234.68838867 129.14599609 233.49755859 C118.97527788 192.32608691 104.43363569 152.17875535 86 114 C85.52626953 113.00484375 85.05253906 112.0096875 84.56445312 110.984375 C68.69174346 77.71482716 49.24981002 46.92018206 24 20 C23.43023438 19.36449219 22.86046875 18.72898437 22.2734375 18.07421875 C17.26272884 12.69091893 11.18776096 8.61467551 5.23046875 4.35546875 C2 2 2 2 0 0 Z " fill="#5525AC" transform="translate(502,0)"/>
|
4
|
+
<path d="M0 0 C0.33 0 0.66 0 1 0 C1.87119265 74.19015402 1.87119265 74.19015402 -3 111 C-3.1654834 112.28261719 -3.3309668 113.56523437 -3.50146484 114.88671875 C-4.48344598 122.29411977 -5.65932659 129.64958034 -7 137 C-7.18143555 138.01545898 -7.36287109 139.03091797 -7.54980469 140.07714844 C-16.31455331 188.48692184 -32.03888974 238.6613107 -61 279 C-61.65484375 279.92683594 -62.3096875 280.85367187 -62.984375 281.80859375 C-70.64011623 292.50586008 -78.94581154 302.46989378 -88 312 C-88.50692383 312.53560547 -89.01384766 313.07121094 -89.53613281 313.62304688 C-118.86142713 344.3935678 -157.25360081 364.97682876 -198.77734375 373.52246094 C-201.18823431 374.04044226 -203.57480802 374.63547714 -205.96875 375.2265625 C-217.96904242 377.96043929 -217.96904242 377.96043929 -222.8828125 375.63671875 C-225.3661936 373.27015175 -227.12520496 370.87186263 -229 368 C-229.74121094 367.01773437 -230.48242188 366.03546875 -231.24609375 365.0234375 C-246.04406945 344.91016868 -253.9728436 321.5085935 -258 297 C-258.11569336 296.33564941 -258.23138672 295.67129883 -258.35058594 294.98681641 C-266.45061902 246.56688574 -257.46220715 187.3285866 -229.13671875 146.765625 C-219.51652786 133.73187252 -206.32260349 121.47700429 -190 118 C-186.4375 117.8125 -186.4375 117.8125 -184 118 C-185.08890231 123.1686966 -186.31437389 128.25681123 -187.80175781 133.32519531 C-197.42064617 166.23036332 -198.96518454 202.4066818 -182.16796875 233.3046875 C-173.48013523 248.48968087 -162.06767432 259.0774079 -145.48828125 264.87890625 C-128.67021856 269.19664945 -110.55862973 263.61550255 -95.94921875 255.25390625 C-77.68498254 243.61801537 -63.67078559 228.09291807 -52 210 C-51.64373535 209.44828125 -51.2874707 208.8965625 -50.92041016 208.328125 C-11.40994208 146.50106684 -1.2235268 71.91768876 0 0 Z " fill="#865CE0" transform="translate(647,346)"/>
|
5
|
+
<path d="M0 0 C0.69867188 0.74121094 1.39734375 1.48242188 2.1171875 2.24609375 C24.55303974 30.21612287 32.82621846 65.71319248 34 101 C34.061875 102.70542969 34.061875 102.70542969 34.125 104.4453125 C34.92417015 149.09894475 24.79238456 198.44815615 -5 233 C-5.58136719 233.69480469 -6.16273438 234.38960937 -6.76171875 235.10546875 C-15.09914052 244.28293301 -26.95736901 250.54687146 -39 253 C-40.32 253 -41.64 253 -43 253 C-42.60485063 251.54148119 -42.20879943 250.08320674 -41.8125 248.625 C-41.54050781 247.61566406 -41.26851562 246.60632813 -40.98828125 245.56640625 C-40.28297375 243.02116615 -39.55346785 240.49327958 -38.79296875 237.96484375 C-29.07242233 205.23480891 -27.63303836 169.34030141 -43.6875 138.3125 C-52.13871156 122.78103331 -64.06189957 111.65412235 -81 106 C-98.30342424 101.65324608 -116.15525028 107.2504617 -131.13769531 115.87158203 C-154.05430826 129.75734305 -170.08475975 152.0388843 -183 175 C-183.33837891 175.59312988 -183.67675781 176.18625977 -184.02539062 176.79736328 C-213.50129206 228.74652609 -223.73179045 291.0862414 -226 350 C-226.33 350 -226.66 350 -227 350 C-228.16698179 278.4969313 -218.71418955 204.29501105 -188 139 C-187.55430664 138.04963867 -187.10861328 137.09927734 -186.64941406 136.12011719 C-176.81458028 115.36369036 -165.31684662 95.97836767 -151 78 C-150.58137695 77.46568359 -150.16275391 76.93136719 -149.73144531 76.38085938 C-137.24849055 60.54055764 -122.49335107 45.6431536 -106 34 C-105.34950684 33.53223145 -104.69901367 33.06446289 -104.02880859 32.58251953 C-86.21854607 19.86568264 -66.88989248 9.60585727 -46 3 C-44.89760986 2.65098633 -44.89760986 2.65098633 -43.77294922 2.29492188 C-38.55691991 0.68008061 -33.30252827 -0.70133447 -28 -2 C-26.65494385 -2.34417969 -26.65494385 -2.34417969 -25.28271484 -2.6953125 C-22.46748377 -3.40166722 -19.64435479 -4.05140891 -16.8125 -4.6875 C-15.93932129 -4.90946045 -15.06614258 -5.1314209 -14.16650391 -5.36010742 C-7.35468257 -6.78247902 -4.50964561 -5.13020432 0 0 Z " fill="#865CE0" transform="translate(368,30)"/>
|
6
|
+
</svg>
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require 'faraday'
|
4
4
|
require 'faraday_middleware'
|
5
5
|
module Parsbank
|
6
|
-
class Nobitex
|
6
|
+
class Nobitex < Gates
|
7
7
|
attr_accessor :amount, :description, :email, :mobile, :merchant, :callbackUrl, :orderId, :allowedCards, :ledgerId,
|
8
8
|
:nationalCode, :checkMobileWithCard
|
9
9
|
|
@@ -25,16 +25,6 @@ module Parsbank
|
|
25
25
|
raise ArgumentError, "Missing required argument: #{e.message}"
|
26
26
|
end
|
27
27
|
|
28
|
-
def self.logo
|
29
|
-
file_path = "#{__dir__}/logo.svg"
|
30
|
-
return [404, { 'Content-Type' => 'text/plain' }, ['File not found']] unless File.exist?(file_path)
|
31
|
-
|
32
|
-
[
|
33
|
-
200,
|
34
|
-
{ 'Content-Type' => 'image/svg+xml' },
|
35
|
-
File.open(file_path, 'r')
|
36
|
-
]
|
37
|
-
end
|
38
28
|
|
39
29
|
def validate(response = nil)
|
40
30
|
@response = response
|
@@ -84,10 +74,6 @@ module Parsbank
|
|
84
74
|
|
85
75
|
private
|
86
76
|
|
87
|
-
def default_config(key)
|
88
|
-
Parsbank.load_secrets_yaml[self.class.name.split('::').last.downcase][key.to_s]
|
89
|
-
end
|
90
|
-
|
91
77
|
def create_rest_client
|
92
78
|
connection = Parsbank::Restfull.new(
|
93
79
|
endpoint: default_config(:endpoint) || 'https://gateway.zibal.ir',
|
data/lib/parsbank/restfull.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'net/http'
|
2
4
|
require 'uri'
|
3
5
|
require 'json'
|
@@ -7,7 +9,7 @@ module Parsbank
|
|
7
9
|
attr_accessor :connection
|
8
10
|
|
9
11
|
MAX_RETRIES = 3
|
10
|
-
RETRY_INTERVAL =
|
12
|
+
RETRY_INTERVAL = 5 # In seconds
|
11
13
|
|
12
14
|
def initialize(args = {})
|
13
15
|
@endpoint = args.fetch(:endpoint)
|
@@ -22,6 +24,7 @@ module Parsbank
|
|
22
24
|
|
23
25
|
def call
|
24
26
|
response = send_request
|
27
|
+
|
25
28
|
log_response(response)
|
26
29
|
|
27
30
|
if response.is_a?(Net::HTTPSuccess)
|
@@ -40,8 +43,9 @@ module Parsbank
|
|
40
43
|
def setup_connection
|
41
44
|
@uri = URI.parse(@endpoint)
|
42
45
|
@connection = Net::HTTP.new(@uri.host, @uri.port)
|
43
|
-
@connection.use_ssl =
|
44
|
-
|
46
|
+
@connection.use_ssl = @uri.scheme == 'https'
|
47
|
+
@connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
48
|
+
@connection.set_debug_output($stdout) if Parsbank.configuration.debug
|
45
49
|
# Setting timeouts
|
46
50
|
@connection.open_timeout = 10 # Time to wait for the connection to open
|
47
51
|
@connection.read_timeout = 10 # Time to wait for a response
|
@@ -56,18 +60,16 @@ module Parsbank
|
|
56
60
|
|
57
61
|
# Handling redirects manually (max 5 redirects)
|
58
62
|
handle_redirects(response)
|
59
|
-
|
63
|
+
|
60
64
|
return response
|
61
65
|
end
|
62
66
|
rescue Timeout::Error => e
|
63
67
|
retries += 1
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
raise "Request timed out after #{MAX_RETRIES} retries: #{e.message}"
|
70
|
-
end
|
68
|
+
raise "Request timed out after #{MAX_RETRIES} retries: #{e.message}" unless retries < MAX_RETRIES
|
69
|
+
|
70
|
+
log_to_rails("Timeout occurred. Retrying... (#{retries}/#{MAX_RETRIES})", :warn)
|
71
|
+
sleep(RETRY_INTERVAL)
|
72
|
+
retry
|
71
73
|
rescue StandardError => e
|
72
74
|
log_to_rails("Request failed: #{e.message}", :error)
|
73
75
|
raise e
|
@@ -89,7 +91,10 @@ module Parsbank
|
|
89
91
|
|
90
92
|
def build_post_request
|
91
93
|
request = Net::HTTP::Post.new(@action, default_headers)
|
92
|
-
request
|
94
|
+
request['Connection'] = 'close' # Avoid HTTP/2 issues
|
95
|
+
request.body = JSON.generate(@request_message) if @request_message.any?
|
96
|
+
puts "Request Header: #{default_headers}" if Parsbank.configuration.debug
|
97
|
+
puts "Request Body: #{request.body}" if Parsbank.configuration.debug
|
93
98
|
request
|
94
99
|
end
|
95
100
|
|
@@ -105,8 +110,10 @@ module Parsbank
|
|
105
110
|
|
106
111
|
def default_headers
|
107
112
|
{
|
108
|
-
'
|
109
|
-
'
|
113
|
+
'content-type' => 'application/json',
|
114
|
+
'accept' => 'application/json',
|
115
|
+
'user-agent' => 'ParsBank Ruby Gem',
|
116
|
+
'app-version' => Parsbank::VERSION
|
110
117
|
}.merge(@headers)
|
111
118
|
end
|
112
119
|
|
@@ -126,7 +133,9 @@ module Parsbank
|
|
126
133
|
end
|
127
134
|
|
128
135
|
def log_and_raise_error(response)
|
129
|
-
log_to_rails(
|
136
|
+
log_to_rails(
|
137
|
+
"Request to #{@endpoint}/#{@action} failed with status: #{response.code}, error: #{response.body.inspect}", :error
|
138
|
+
)
|
130
139
|
raise "API request failed with status #{response.code}: #{response.body}"
|
131
140
|
end
|
132
141
|
|
@@ -150,7 +159,10 @@ module Parsbank
|
|
150
159
|
def webhook(message)
|
151
160
|
webhook_url = Parsbank.configuration.webhook
|
152
161
|
webhook_url.gsub!('MESSAGE', message) if Parsbank.configuration.webhook_method == :get
|
153
|
-
|
162
|
+
if Parsbank.configuration.webhook_method == :get
|
163
|
+
webhook_url.gsub!('TITLE',
|
164
|
+
"Webhook of Connection Error at #{Time.now}")
|
165
|
+
end
|
154
166
|
|
155
167
|
uri = URI.parse(webhook_url)
|
156
168
|
connection = Net::HTTP.new(uri.host, uri.port)
|
@@ -170,13 +182,13 @@ module Parsbank
|
|
170
182
|
end
|
171
183
|
|
172
184
|
def handle_redirects(response)
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
185
|
+
return unless response.is_a?(Net::HTTPRedirection)
|
186
|
+
|
187
|
+
location = response['Location']
|
188
|
+
log_to_rails("Redirecting to: #{location}", :warn)
|
189
|
+
redirect_uri = URI.parse(location)
|
190
|
+
request = Net::HTTP::Get.new(redirect_uri)
|
191
|
+
@connection.request(request)
|
180
192
|
end
|
181
193
|
end
|
182
194
|
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
require 'rexml/document'
|
4
|
+
require 'logger'
|
5
|
+
|
6
|
+
module Parsbank
|
7
|
+
# SOAP Client Class - Standard SOAP generation with namespaces and headers
|
8
|
+
class SOAP
|
9
|
+
attr_reader :endpoint, :namespace, :logger
|
10
|
+
|
11
|
+
# Initialize SOAP Client with endpoint, namespace, and optional logger
|
12
|
+
def initialize(endpoint, namespace)
|
13
|
+
@endpoint = URI.parse(endpoint)
|
14
|
+
@namespace = namespace
|
15
|
+
@logger = Logger.new(STDOUT)
|
16
|
+
@logger.level = Parsbank.configuration.debug ? Logger::DEBUG : Logger::WARN
|
17
|
+
end
|
18
|
+
|
19
|
+
# Main method to make a SOAP request
|
20
|
+
def call(action, body, headers = {})
|
21
|
+
log_request(action, body)
|
22
|
+
|
23
|
+
xml = build_envelope(action, body.map { |k, v| "<s:#{k}>#{v}</#{k}>" }.join(''))
|
24
|
+
|
25
|
+
http = Net::HTTP.new(@endpoint.host, @endpoint.port)
|
26
|
+
http.use_ssl = (@endpoint.scheme == 'https')
|
27
|
+
|
28
|
+
request = Net::HTTP::Post.new(@endpoint.request_uri)
|
29
|
+
request.content_type = 'text/xml; charset=utf-8'
|
30
|
+
request['SOAPAction'] = "#{@namespace}/#{action}"
|
31
|
+
request.body = xml
|
32
|
+
|
33
|
+
headers.store('Parsbank-RubyGem', Parsbank::VERSION)
|
34
|
+
headers.each { |key, value| request[key] = value }
|
35
|
+
|
36
|
+
begin
|
37
|
+
response = http.request(request)
|
38
|
+
log_response(response)
|
39
|
+
parse_response(response)
|
40
|
+
rescue Timeout::Error => e
|
41
|
+
handle_error("Request timed out", e)
|
42
|
+
rescue SocketError => e
|
43
|
+
handle_error("Network connection failed", e)
|
44
|
+
rescue Errno::ECONNREFUSED => e
|
45
|
+
handle_error("Connection refused by server", e)
|
46
|
+
rescue StandardError => e
|
47
|
+
handle_error("Unexpected error: #{e.message}", e)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
# Build the SOAP XML Envelope
|
54
|
+
def build_envelope(action, body)
|
55
|
+
<<~XML
|
56
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
57
|
+
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
|
58
|
+
xmlns:s="#{@namespace}">
|
59
|
+
<soap:Header/>
|
60
|
+
<soap:Body>
|
61
|
+
<s:#{action}>
|
62
|
+
#{body}
|
63
|
+
</s:#{action}>
|
64
|
+
</soap:Body>
|
65
|
+
</soap:Envelope>
|
66
|
+
XML
|
67
|
+
end
|
68
|
+
|
69
|
+
# Parse the XML response body
|
70
|
+
def parse_response(response)
|
71
|
+
if response.is_a?(Net::HTTPSuccess)
|
72
|
+
puts "Response Success"
|
73
|
+
puts response.body
|
74
|
+
parse_xml(response.body)
|
75
|
+
else
|
76
|
+
{ error: "HTTP Error #{response.code}: #{response.message}" }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Convert XML to Hash
|
81
|
+
def parse_xml(xml)
|
82
|
+
begin
|
83
|
+
doc = REXML::Document.new(xml)
|
84
|
+
{ success: true, body: doc }
|
85
|
+
rescue REXML::ParseException => e
|
86
|
+
{ success: false, error: "Invalid XML response: #{e.message}" }
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Error handling and logging
|
91
|
+
def handle_error(message, exception)
|
92
|
+
@logger.error("#{message}: #{exception.message}")
|
93
|
+
{ success: false, error: message }
|
94
|
+
end
|
95
|
+
|
96
|
+
# Log the SOAP request for debugging
|
97
|
+
def log_request(action, body)
|
98
|
+
@logger.debug("Sending SOAP request: Action = #{action}, Body = #{body}")
|
99
|
+
end
|
100
|
+
|
101
|
+
# Log the SOAP response for debugging
|
102
|
+
def log_response(response)
|
103
|
+
@logger.debug("Received SOAP response: Status = #{response.code}, Body = #{response.body}")
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|