rma-payment-gateway 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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +60 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/README.md +446 -0
- data/Rakefile +12 -0
- data/docs/API.md +339 -0
- data/docs/EXAMPLES.md +650 -0
- data/docs/FLOW_DIAGRAM.md +440 -0
- data/docs/QUICK_REFERENCE.md +323 -0
- data/docs/README.md +259 -0
- data/docs/SECURITY.md +506 -0
- data/docs/USAGE_GUIDE.md +522 -0
- data/lib/rma/payment/gateway/account_inquiry.rb +69 -0
- data/lib/rma/payment/gateway/authorization.rb +81 -0
- data/lib/rma/payment/gateway/client.rb +124 -0
- data/lib/rma/payment/gateway/configuration.rb +42 -0
- data/lib/rma/payment/gateway/debit_request.rb +65 -0
- data/lib/rma/payment/gateway/errors.rb +42 -0
- data/lib/rma/payment/gateway/utils.rb +130 -0
- data/lib/rma/payment/gateway/version.rb +9 -0
- data/lib/rma/payment/gateway.rb +24 -0
- data/sig/rma/payment/gateway.rbs +8 -0
- metadata +65 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "faraday"
|
|
4
|
+
require "json"
|
|
5
|
+
|
|
6
|
+
module Rma
|
|
7
|
+
module Payment
|
|
8
|
+
module Gateway
|
|
9
|
+
# Client class for RMA Payment Gateway.
|
|
10
|
+
# Handles all communication with the RMA Payment Gateway API.
|
|
11
|
+
#
|
|
12
|
+
# @example
|
|
13
|
+
# client = Rma::Payment::Gateway::Client.new
|
|
14
|
+
# client.authorization
|
|
15
|
+
# client.account_inquiry
|
|
16
|
+
# client.debit_request
|
|
17
|
+
#
|
|
18
|
+
# @param config [Rma::Payment::Gateway::Configuration] Configuration instance
|
|
19
|
+
class Client
|
|
20
|
+
attr_reader :config, :access_token, :private_key
|
|
21
|
+
|
|
22
|
+
def initialize(config = nil)
|
|
23
|
+
@config = config || Rma::Payment::Gateway.configuration
|
|
24
|
+
validate_configuration!
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Authorization methods
|
|
28
|
+
def authorization
|
|
29
|
+
@authorization ||= Authorization.new(self)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Account Inquiry methods
|
|
33
|
+
def account_inquiry
|
|
34
|
+
@account_inquiry ||= AccountInquiry.new(self)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Debit Request methods
|
|
38
|
+
def debit_request
|
|
39
|
+
@debit_request ||= DebitRequest.new(self)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# HTTP request methods
|
|
43
|
+
def post(body: {}, headers: {})
|
|
44
|
+
request(:post, body: body, headers: headers)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def get(headers: {})
|
|
48
|
+
request(:get, headers: headers)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def validate_configuration!
|
|
54
|
+
raise ConfigurationError, "Configuration is required" if config.nil?
|
|
55
|
+
return if config.valid?
|
|
56
|
+
|
|
57
|
+
raise ConfigurationError, "Missing required configuration fields: #{config.missing_fields.join(", ")}"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def request(method, body: {}, headers: {})
|
|
61
|
+
response = connection.send(method) do |req|
|
|
62
|
+
req.url "/BFSSecure/nvpapi"
|
|
63
|
+
req.headers = build_headers(headers)
|
|
64
|
+
req.body = body.to_query if method == :post && !body.empty?
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
handle_response(response)
|
|
68
|
+
rescue Faraday::Error => e
|
|
69
|
+
raise NetworkError, "Network error: #{e.message}"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def connection
|
|
73
|
+
@connection ||= Faraday.new(url: config.base_url) do |conn|
|
|
74
|
+
conn.request :url_encoded
|
|
75
|
+
conn.response :json, content_type: /\bjson$/
|
|
76
|
+
conn.adapter Faraday.default_adapter
|
|
77
|
+
conn.options.timeout = config.timeout
|
|
78
|
+
conn.options.open_timeout = config.open_timeout
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def build_headers(custom_headers = {})
|
|
83
|
+
headers = { "Content-Type" => "application/x-www-form-urlencoded" }
|
|
84
|
+
headers.merge(custom_headers)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def handle_response(response)
|
|
88
|
+
case response.status
|
|
89
|
+
when 200..299
|
|
90
|
+
response.body
|
|
91
|
+
when 400..499
|
|
92
|
+
handle_client_error(response)
|
|
93
|
+
when 500..599
|
|
94
|
+
handle_server_error(response)
|
|
95
|
+
else
|
|
96
|
+
raise APIError, "Unexpected response status: #{response.status}"
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def handle_client_error(response)
|
|
101
|
+
body = response.body || {}
|
|
102
|
+
error_message = body["result"]["bfs_responseDesc"] || "Client error"
|
|
103
|
+
|
|
104
|
+
raise InvalidParameterError.new(
|
|
105
|
+
error_message,
|
|
106
|
+
response_code: body["result"]["bfs_responseCode"],
|
|
107
|
+
response_detail: body["result"]["bfs_responseDesc"]
|
|
108
|
+
)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def handle_server_error(response)
|
|
112
|
+
body = response.body || {}
|
|
113
|
+
error_message = body["result"]["bfs_responseDesc"] || "Server error"
|
|
114
|
+
|
|
115
|
+
raise APIError.new(
|
|
116
|
+
error_message,
|
|
117
|
+
response_code: body["result"]["bfs_responseCode"],
|
|
118
|
+
response_description: body["result"]["bfs_responseDesc"]
|
|
119
|
+
)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "dotenv/load" # Load environment variables
|
|
4
|
+
|
|
5
|
+
module Rma
|
|
6
|
+
module Payment
|
|
7
|
+
module Gateway
|
|
8
|
+
# Configuration class for RMA Payment Gateway.
|
|
9
|
+
# Handles all configuration options required for the RMA Payment Gateway client.
|
|
10
|
+
#
|
|
11
|
+
# @example
|
|
12
|
+
# config = Rma::Payment::Gateway::Configuration.new
|
|
13
|
+
# config.base_url = 'https://api.example.com'
|
|
14
|
+
# config.rsa_key_path = '/path/to/rsa_key.pem'
|
|
15
|
+
# config.beneficiary_id = 'YOUR_BENEFICIARY_ID'
|
|
16
|
+
class Configuration
|
|
17
|
+
attr_accessor :base_url, :rsa_key_path, :beneficiary_id, :payment_description, :timeout, :open_timeout
|
|
18
|
+
|
|
19
|
+
def initialize
|
|
20
|
+
@base_url = ENV["RMA_BASE_URL"]
|
|
21
|
+
@rsa_key_path = ENV["RMA_RSA_KEY_PATH"]
|
|
22
|
+
@beneficiary_id = ENV["RMA_BENEFICIARY_ID"]
|
|
23
|
+
@payment_description = ENV["RMA_PAYMENT_DESCRIPTION"]
|
|
24
|
+
@timeout = 30
|
|
25
|
+
@open_timeout = 10
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def valid?
|
|
29
|
+
required_fields.all? { |field| !send(field).nil? && !send(field).to_s.empty? }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def required_fields
|
|
33
|
+
%i[base_url rsa_key_path beneficiary_id payment_description]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def missing_fields
|
|
37
|
+
required_fields.reject { |field| !send(field).nil? && !send(field).to_s.empty? }
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "uri"
|
|
4
|
+
require "securerandom"
|
|
5
|
+
|
|
6
|
+
module Rma
|
|
7
|
+
module Payment
|
|
8
|
+
module Gateway
|
|
9
|
+
# Authorization class for RMA Payment Gateway.
|
|
10
|
+
# Handles authentication and authorization for the RMA Payment Gateway client.
|
|
11
|
+
#
|
|
12
|
+
# @example
|
|
13
|
+
# auth = Rma::Payment::Gateway::Authorization.new(client)
|
|
14
|
+
# auth.call(order_no, amount, email)
|
|
15
|
+
#
|
|
16
|
+
# @param client [Rma::Payment::Gateway::Client] Client instance
|
|
17
|
+
class DebitRequest
|
|
18
|
+
attr_reader :client, :transaction_id, :otp
|
|
19
|
+
|
|
20
|
+
def initialize(client)
|
|
21
|
+
@client = client
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Fetch debit request
|
|
25
|
+
# Returns the debit request string
|
|
26
|
+
def call(transaction_id, otp)
|
|
27
|
+
@transaction_id = transaction_id
|
|
28
|
+
@otp = otp
|
|
29
|
+
response = client.post(body: debit_request_body)
|
|
30
|
+
|
|
31
|
+
validate_debit_request_response!(response)
|
|
32
|
+
|
|
33
|
+
response["result"]
|
|
34
|
+
rescue StandardError => e
|
|
35
|
+
raise AuthenticationError, "Failed to fetch debit request: #{e.message}"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def debit_request_body
|
|
41
|
+
params = {
|
|
42
|
+
bfs_bfsTxnId: transaction_id,
|
|
43
|
+
bfs_remitterOtp: otp,
|
|
44
|
+
bfs_benfId: client.config.beneficiary_id,
|
|
45
|
+
bfs_msgType: "DR"
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
# Convert to URL-encoded format
|
|
49
|
+
URI.encode_www_form(params)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def validate_debit_request_response!(response)
|
|
53
|
+
unless response.is_a?(Hash) && response["result"]["bfs_responseCode"] == "00"
|
|
54
|
+
error_detail = response["result"]["bfs_responseDesc"] || "Unknown error"
|
|
55
|
+
raise AuthenticationError, "Debit request failed: #{error_detail}"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
return if response["result"]
|
|
59
|
+
|
|
60
|
+
raise AuthenticationError, "No response data in response"
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rma
|
|
4
|
+
module Payment
|
|
5
|
+
module Gateway
|
|
6
|
+
class Error < StandardError; end
|
|
7
|
+
|
|
8
|
+
class ConfigurationError < Error; end
|
|
9
|
+
|
|
10
|
+
class AuthenticationError < Error; end
|
|
11
|
+
|
|
12
|
+
class InvalidParameterError < Error
|
|
13
|
+
attr_reader :response_code, :response_detail
|
|
14
|
+
|
|
15
|
+
def initialize(message, response_code: 422, response_detail: "Invalid parameters")
|
|
16
|
+
super(message)
|
|
17
|
+
@response_code = response_code
|
|
18
|
+
@response_detail = response_detail
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class APIError < Error
|
|
23
|
+
attr_reader :response_code, :response_message, :response_description, :response_detail
|
|
24
|
+
|
|
25
|
+
def initialize(message, response_code: 422, response_message: "Invalid parameters",
|
|
26
|
+
response_description: "Invalid parameters", response_detail: "Invalid parameters")
|
|
27
|
+
super(message)
|
|
28
|
+
@response_code = response_code
|
|
29
|
+
@response_message = response_message
|
|
30
|
+
@response_description = response_description
|
|
31
|
+
@response_detail = response_detail
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
class NetworkError < Error; end
|
|
36
|
+
|
|
37
|
+
class SignatureError < Error; end
|
|
38
|
+
|
|
39
|
+
class TransactionError < APIError; end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "securerandom"
|
|
4
|
+
require "time"
|
|
5
|
+
|
|
6
|
+
module Rma
|
|
7
|
+
module Payment
|
|
8
|
+
module Gateway
|
|
9
|
+
module Utils
|
|
10
|
+
# Generate ISO 8601 timestamp
|
|
11
|
+
# @param time [Time] Optional time object (defaults to current time)
|
|
12
|
+
# @return [String] ISO 8601 formatted timestamp
|
|
13
|
+
def self.generate_timestamp(time = Time.now)
|
|
14
|
+
time.utc.strftime("%Y%m%d%H%M%S")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Validate account number format
|
|
18
|
+
# @param account_number [String] Account number to validate
|
|
19
|
+
# @return [Boolean] True if valid format
|
|
20
|
+
def self.valid_account_number?(account_number)
|
|
21
|
+
return false if account_number.nil? || account_number.empty?
|
|
22
|
+
|
|
23
|
+
# Account numbers should be numeric and between 8-15 digits
|
|
24
|
+
account_number.to_s.match?(/^\d{8,15}$/)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Validate phone number format (Bhutan)
|
|
28
|
+
# @param phone_number [String] Phone number to validate
|
|
29
|
+
# @return [Boolean] True if valid format
|
|
30
|
+
def self.valid_phone_number?(phone_number)
|
|
31
|
+
return false if phone_number.nil? || phone_number.empty?
|
|
32
|
+
|
|
33
|
+
# Bhutan phone numbers are typically 8 digits
|
|
34
|
+
phone_number.to_s.match?(/^\d{8}$/)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Validate email format
|
|
38
|
+
# @param email [String] Email to validate
|
|
39
|
+
# @return [Boolean] True if valid format
|
|
40
|
+
def self.valid_email?(email)
|
|
41
|
+
return false if email.nil? || email.empty?
|
|
42
|
+
|
|
43
|
+
email.to_s.match?(/\A[\w+\-.]+@[a-z\d-]+(\.[a-z\d-]+)*\.[a-z]+\z/i)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Validate amount
|
|
47
|
+
# @param amount [Numeric] Amount to validate
|
|
48
|
+
# @return [Boolean] True if valid
|
|
49
|
+
def self.valid_amount?(amount)
|
|
50
|
+
return false if amount.nil?
|
|
51
|
+
|
|
52
|
+
amount.is_a?(Numeric) && amount >= 0
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Format amount to 2 decimal places
|
|
56
|
+
# @param amount [Numeric] Amount to format
|
|
57
|
+
# @return [String] Formatted amount
|
|
58
|
+
def self.format_amount(amount)
|
|
59
|
+
format("%.2f", amount.to_f)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Validate date format (YYYY-MM-DD)
|
|
63
|
+
# @param date_string [String] Date string to validate
|
|
64
|
+
# @return [Boolean] True if valid format
|
|
65
|
+
def self.valid_date_format?(date_string)
|
|
66
|
+
return false if date_string.nil? || date_string.empty?
|
|
67
|
+
|
|
68
|
+
date_string.to_s.match?(/^\d{4}-\d{2}-\d{2}$/)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Parse date string
|
|
72
|
+
# @param date_string [String] Date string in YYYY-MM-DD format
|
|
73
|
+
# @return [Date, nil] Parsed date or nil if invalid
|
|
74
|
+
def self.parse_date(date_string)
|
|
75
|
+
return nil unless valid_date_format?(date_string)
|
|
76
|
+
|
|
77
|
+
Date.parse(date_string)
|
|
78
|
+
rescue ArgumentError
|
|
79
|
+
nil
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Sanitize string for API request
|
|
83
|
+
# @param str [String] String to sanitize
|
|
84
|
+
# @return [String] Sanitized string
|
|
85
|
+
def self.sanitize_string(str)
|
|
86
|
+
return "" if str.nil?
|
|
87
|
+
|
|
88
|
+
str.to_s.strip
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Mask sensitive data for logging
|
|
92
|
+
# @param data [String] Sensitive data to mask
|
|
93
|
+
# @param visible_chars [Integer] Number of characters to show at start and end
|
|
94
|
+
# @return [String] Masked string
|
|
95
|
+
def self.mask_sensitive(data, visible_chars = 4)
|
|
96
|
+
return "" if data.nil? || data.empty?
|
|
97
|
+
|
|
98
|
+
data_str = data.to_s
|
|
99
|
+
return data_str if data_str.length <= visible_chars * 2
|
|
100
|
+
|
|
101
|
+
"#{data_str[0...visible_chars]}#{"*" * (data_str.length - visible_chars * 2)}#{data_str[-visible_chars..]}"
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Bank codes mapping
|
|
105
|
+
BANK_CODES = {
|
|
106
|
+
"1010" => "Bank of Bhutan (BOBL)",
|
|
107
|
+
"1020" => "Bhutan National Bank (BNBL)",
|
|
108
|
+
"1030" => "Druk PNB Bank Limited (DPNBL)",
|
|
109
|
+
"1040" => "Tashi Bank (TBank)",
|
|
110
|
+
"1050" => "Bhutan Development Bank Limited (BDBL)",
|
|
111
|
+
"1060" => "Digital Kidu (DK Bank)"
|
|
112
|
+
}.freeze
|
|
113
|
+
|
|
114
|
+
# Get bank name from code
|
|
115
|
+
# @param bank_code [String] Bank code
|
|
116
|
+
# @return [String, nil] Bank name or nil if not found
|
|
117
|
+
def self.bank_name(bank_code)
|
|
118
|
+
BANK_CODES[bank_code.to_s]
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Validate bank code
|
|
122
|
+
# @param bank_code [String] Bank code to validate
|
|
123
|
+
# @return [Boolean] True if valid
|
|
124
|
+
def self.valid_bank_code?(bank_code)
|
|
125
|
+
BANK_CODES.key?(bank_code.to_s)
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "gateway/version"
|
|
4
|
+
|
|
5
|
+
module Rma
|
|
6
|
+
module Payment
|
|
7
|
+
module Gateway
|
|
8
|
+
class Error < StandardError; end
|
|
9
|
+
|
|
10
|
+
class << self
|
|
11
|
+
attr_accessor :configuration
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.configure
|
|
15
|
+
self.configuration ||= Configuration.new
|
|
16
|
+
yield(configuration)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.client
|
|
20
|
+
Client.new(configuration)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rma-payment-gateway
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Tashi Dendup
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies: []
|
|
12
|
+
description: A Ruby gem for integrating with RMA Payment Gateway API, including Payment
|
|
13
|
+
Authorization, Debit payment request, and Payment OTP confirmation.
|
|
14
|
+
email:
|
|
15
|
+
- tashii.dendupp@gmail.com
|
|
16
|
+
executables: []
|
|
17
|
+
extensions: []
|
|
18
|
+
extra_rdoc_files: []
|
|
19
|
+
files:
|
|
20
|
+
- CHANGELOG.md
|
|
21
|
+
- CODE_OF_CONDUCT.md
|
|
22
|
+
- README.md
|
|
23
|
+
- Rakefile
|
|
24
|
+
- docs/API.md
|
|
25
|
+
- docs/EXAMPLES.md
|
|
26
|
+
- docs/FLOW_DIAGRAM.md
|
|
27
|
+
- docs/QUICK_REFERENCE.md
|
|
28
|
+
- docs/README.md
|
|
29
|
+
- docs/SECURITY.md
|
|
30
|
+
- docs/USAGE_GUIDE.md
|
|
31
|
+
- lib/rma/payment/gateway.rb
|
|
32
|
+
- lib/rma/payment/gateway/account_inquiry.rb
|
|
33
|
+
- lib/rma/payment/gateway/authorization.rb
|
|
34
|
+
- lib/rma/payment/gateway/client.rb
|
|
35
|
+
- lib/rma/payment/gateway/configuration.rb
|
|
36
|
+
- lib/rma/payment/gateway/debit_request.rb
|
|
37
|
+
- lib/rma/payment/gateway/errors.rb
|
|
38
|
+
- lib/rma/payment/gateway/utils.rb
|
|
39
|
+
- lib/rma/payment/gateway/version.rb
|
|
40
|
+
- sig/rma/payment/gateway.rbs
|
|
41
|
+
homepage: https://github.com/dcplbt/rma-payment-gateway
|
|
42
|
+
licenses: []
|
|
43
|
+
metadata:
|
|
44
|
+
allowed_push_host: https://rubygems.org
|
|
45
|
+
homepage_uri: https://github.com/dcplbt/rma-payment-gateway
|
|
46
|
+
source_code_uri: https://github.com/dcplbt/rma-payment-gateway
|
|
47
|
+
changelog_uri: https://github.com/dcplbt/rma-payment-gateway/blob/main/CHANGELOG.md
|
|
48
|
+
rdoc_options: []
|
|
49
|
+
require_paths:
|
|
50
|
+
- lib
|
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
52
|
+
requirements:
|
|
53
|
+
- - ">="
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
version: 3.2.0
|
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0'
|
|
61
|
+
requirements: []
|
|
62
|
+
rubygems_version: 3.7.2
|
|
63
|
+
specification_version: 4
|
|
64
|
+
summary: RMA Payment Gateway
|
|
65
|
+
test_files: []
|