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
data/docs/USAGE_GUIDE.md
ADDED
|
@@ -0,0 +1,522 @@
|
|
|
1
|
+
# Usage Guide
|
|
2
|
+
|
|
3
|
+
This guide provides practical examples and best practices for integrating the RMA Payment Gateway into your Ruby application.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Quick Start](#quick-start)
|
|
8
|
+
- [Rails Integration](#rails-integration)
|
|
9
|
+
- [Sinatra Integration](#sinatra-integration)
|
|
10
|
+
- [Common Use Cases](#common-use-cases)
|
|
11
|
+
- [Best Practices](#best-practices)
|
|
12
|
+
- [Troubleshooting](#troubleshooting)
|
|
13
|
+
|
|
14
|
+
## Quick Start
|
|
15
|
+
|
|
16
|
+
### 1. Installation
|
|
17
|
+
|
|
18
|
+
Add to your Gemfile:
|
|
19
|
+
|
|
20
|
+
```ruby
|
|
21
|
+
gem 'rma-payment-gateway'
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Run:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
bundle install
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### 2. Configuration
|
|
31
|
+
|
|
32
|
+
Create a `.env` file:
|
|
33
|
+
|
|
34
|
+
```env
|
|
35
|
+
RMA_BASE_URL=https://your-rma-gateway-url.com
|
|
36
|
+
RMA_RSA_KEY_PATH=/path/to/rsa_private_key.pem
|
|
37
|
+
RMA_BENEFICIARY_ID=your_beneficiary_id
|
|
38
|
+
RMA_PAYMENT_DESCRIPTION=Payment for services
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### 3. Basic Usage
|
|
42
|
+
|
|
43
|
+
```ruby
|
|
44
|
+
require 'rma/payment/gateway'
|
|
45
|
+
|
|
46
|
+
# Initialize client
|
|
47
|
+
client = Rma::Payment::Gateway::Client.new
|
|
48
|
+
|
|
49
|
+
# Process payment
|
|
50
|
+
begin
|
|
51
|
+
# Step 1: Authorization
|
|
52
|
+
auth_response = client.authorization.call("ORDER123", 100.50, "customer@email.com")
|
|
53
|
+
transaction_id = auth_response["bfs_bfsTxnId"]
|
|
54
|
+
|
|
55
|
+
# Step 2: Account Inquiry (customer provides bank details)
|
|
56
|
+
inquiry_response = client.account_inquiry.call(transaction_id, "1010", "12345678")
|
|
57
|
+
|
|
58
|
+
# Step 3: Debit Request (customer provides OTP)
|
|
59
|
+
debit_response = client.debit_request.call(transaction_id, "123456")
|
|
60
|
+
|
|
61
|
+
puts "Payment successful!"
|
|
62
|
+
rescue Rma::Payment::Gateway::Error => e
|
|
63
|
+
puts "Payment failed: #{e.message}"
|
|
64
|
+
end
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Rails Integration
|
|
68
|
+
|
|
69
|
+
### Configuration
|
|
70
|
+
|
|
71
|
+
Create an initializer `config/initializers/rma_payment_gateway.rb`:
|
|
72
|
+
|
|
73
|
+
```ruby
|
|
74
|
+
Rma::Payment::Gateway.configure do |config|
|
|
75
|
+
config.base_url = ENV['RMA_BASE_URL']
|
|
76
|
+
config.rsa_key_path = Rails.root.join('config', 'rma_private_key.pem').to_s
|
|
77
|
+
config.beneficiary_id = ENV['RMA_BENEFICIARY_ID']
|
|
78
|
+
config.payment_description = ENV['RMA_PAYMENT_DESCRIPTION']
|
|
79
|
+
config.timeout = 30
|
|
80
|
+
config.open_timeout = 10
|
|
81
|
+
end
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Service Object Pattern
|
|
85
|
+
|
|
86
|
+
Create a payment service `app/services/rma_payment_service.rb`:
|
|
87
|
+
|
|
88
|
+
```ruby
|
|
89
|
+
class RmaPaymentService
|
|
90
|
+
attr_reader :client, :order, :errors
|
|
91
|
+
|
|
92
|
+
def initialize(order)
|
|
93
|
+
@order = order
|
|
94
|
+
@client = Rma::Payment::Gateway::Client.new
|
|
95
|
+
@errors = []
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def authorize_payment
|
|
99
|
+
response = client.authorization.call(
|
|
100
|
+
order.order_number,
|
|
101
|
+
order.total_amount,
|
|
102
|
+
order.customer_email
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
order.update!(
|
|
106
|
+
rma_transaction_id: response["bfs_bfsTxnId"],
|
|
107
|
+
payment_status: 'authorized'
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
response
|
|
111
|
+
rescue Rma::Payment::Gateway::Error => e
|
|
112
|
+
@errors << e.message
|
|
113
|
+
Rails.logger.error("RMA Authorization failed: #{e.message}")
|
|
114
|
+
nil
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def verify_account(bank_id, account_number)
|
|
118
|
+
response = client.account_inquiry.call(
|
|
119
|
+
order.rma_transaction_id,
|
|
120
|
+
bank_id,
|
|
121
|
+
account_number
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
order.update!(
|
|
125
|
+
customer_bank_id: bank_id,
|
|
126
|
+
customer_account_number: account_number,
|
|
127
|
+
customer_account_name: response["bfs_remitterName"],
|
|
128
|
+
payment_status: 'account_verified'
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
response
|
|
132
|
+
rescue Rma::Payment::Gateway::Error => e
|
|
133
|
+
@errors << e.message
|
|
134
|
+
Rails.logger.error("RMA Account Inquiry failed: #{e.message}")
|
|
135
|
+
nil
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def complete_payment(otp)
|
|
139
|
+
response = client.debit_request.call(
|
|
140
|
+
order.rma_transaction_id,
|
|
141
|
+
otp
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
order.update!(
|
|
145
|
+
payment_status: 'completed',
|
|
146
|
+
paid_at: Time.current
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
response
|
|
150
|
+
rescue Rma::Payment::Gateway::Error => e
|
|
151
|
+
@errors << e.message
|
|
152
|
+
Rails.logger.error("RMA Debit Request failed: #{e.message}")
|
|
153
|
+
nil
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Controller Example
|
|
159
|
+
|
|
160
|
+
```ruby
|
|
161
|
+
class PaymentsController < ApplicationController
|
|
162
|
+
before_action :set_order
|
|
163
|
+
|
|
164
|
+
def new
|
|
165
|
+
# Show payment form
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def authorize
|
|
169
|
+
service = RmaPaymentService.new(@order)
|
|
170
|
+
|
|
171
|
+
if service.authorize_payment
|
|
172
|
+
redirect_to account_verification_path(@order), notice: 'Payment authorized'
|
|
173
|
+
else
|
|
174
|
+
flash[:error] = service.errors.join(', ')
|
|
175
|
+
render :new
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def verify_account
|
|
180
|
+
service = RmaPaymentService.new(@order)
|
|
181
|
+
|
|
182
|
+
if service.verify_account(params[:bank_id], params[:account_number])
|
|
183
|
+
redirect_to otp_verification_path(@order), notice: 'OTP sent to your mobile'
|
|
184
|
+
else
|
|
185
|
+
flash[:error] = service.errors.join(', ')
|
|
186
|
+
render :account_form
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def complete
|
|
191
|
+
service = RmaPaymentService.new(@order)
|
|
192
|
+
|
|
193
|
+
if service.complete_payment(params[:otp])
|
|
194
|
+
redirect_to order_path(@order), notice: 'Payment completed successfully'
|
|
195
|
+
else
|
|
196
|
+
flash[:error] = service.errors.join(', ')
|
|
197
|
+
render :otp_form
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
private
|
|
202
|
+
|
|
203
|
+
def set_order
|
|
204
|
+
@order = Order.find(params[:order_id])
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Background Job Example
|
|
210
|
+
|
|
211
|
+
For handling payment processing asynchronously:
|
|
212
|
+
|
|
213
|
+
```ruby
|
|
214
|
+
class ProcessRmaPaymentJob < ApplicationJob
|
|
215
|
+
queue_as :payments
|
|
216
|
+
|
|
217
|
+
def perform(order_id, step, params = {})
|
|
218
|
+
order = Order.find(order_id)
|
|
219
|
+
service = RmaPaymentService.new(order)
|
|
220
|
+
|
|
221
|
+
case step
|
|
222
|
+
when 'authorize'
|
|
223
|
+
service.authorize_payment
|
|
224
|
+
when 'verify_account'
|
|
225
|
+
service.verify_account(params[:bank_id], params[:account_number])
|
|
226
|
+
when 'complete'
|
|
227
|
+
service.complete_payment(params[:otp])
|
|
228
|
+
end
|
|
229
|
+
rescue StandardError => e
|
|
230
|
+
Rails.logger.error("RMA Payment Job failed: #{e.message}")
|
|
231
|
+
# Send notification to admin
|
|
232
|
+
AdminMailer.payment_failed(order, e.message).deliver_later
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Sinatra Integration
|
|
238
|
+
|
|
239
|
+
### Configuration
|
|
240
|
+
|
|
241
|
+
```ruby
|
|
242
|
+
require 'sinatra'
|
|
243
|
+
require 'rma/payment/gateway'
|
|
244
|
+
|
|
245
|
+
configure do
|
|
246
|
+
Rma::Payment::Gateway.configure do |config|
|
|
247
|
+
config.base_url = ENV['RMA_BASE_URL']
|
|
248
|
+
config.rsa_key_path = File.join(settings.root, 'config', 'rma_private_key.pem')
|
|
249
|
+
config.beneficiary_id = ENV['RMA_BENEFICIARY_ID']
|
|
250
|
+
config.payment_description = ENV['RMA_PAYMENT_DESCRIPTION']
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
helpers do
|
|
255
|
+
def rma_client
|
|
256
|
+
@rma_client ||= Rma::Payment::Gateway::Client.new
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Routes Example
|
|
262
|
+
|
|
263
|
+
```ruby
|
|
264
|
+
post '/payments/authorize' do
|
|
265
|
+
begin
|
|
266
|
+
response = rma_client.authorization.call(
|
|
267
|
+
params[:order_no],
|
|
268
|
+
params[:amount].to_f,
|
|
269
|
+
params[:email]
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
session[:transaction_id] = response["bfs_bfsTxnId"]
|
|
273
|
+
redirect '/payments/account-verification'
|
|
274
|
+
rescue Rma::Payment::Gateway::Error => e
|
|
275
|
+
flash[:error] = e.message
|
|
276
|
+
redirect '/payments/new'
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
post '/payments/verify-account' do
|
|
281
|
+
begin
|
|
282
|
+
response = rma_client.account_inquiry.call(
|
|
283
|
+
session[:transaction_id],
|
|
284
|
+
params[:bank_id],
|
|
285
|
+
params[:account_number]
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
session[:account_name] = response["bfs_remitterName"]
|
|
289
|
+
redirect '/payments/otp-verification'
|
|
290
|
+
rescue Rma::Payment::Gateway::Error => e
|
|
291
|
+
flash[:error] = e.message
|
|
292
|
+
redirect '/payments/account-verification'
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
post '/payments/complete' do
|
|
297
|
+
begin
|
|
298
|
+
response = rma_client.debit_request.call(
|
|
299
|
+
session[:transaction_id],
|
|
300
|
+
params[:otp]
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
flash[:success] = 'Payment completed successfully'
|
|
304
|
+
redirect '/orders/confirmation'
|
|
305
|
+
rescue Rma::Payment::Gateway::Error => e
|
|
306
|
+
flash[:error] = e.message
|
|
307
|
+
redirect '/payments/otp-verification'
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## Common Use Cases
|
|
313
|
+
|
|
314
|
+
### 1. E-commerce Checkout
|
|
315
|
+
|
|
316
|
+
```ruby
|
|
317
|
+
class CheckoutService
|
|
318
|
+
def process_payment(cart, customer)
|
|
319
|
+
client = Rma::Payment::Gateway::Client.new
|
|
320
|
+
|
|
321
|
+
# Step 1: Create order
|
|
322
|
+
order = create_order(cart, customer)
|
|
323
|
+
|
|
324
|
+
# Step 2: Authorize payment
|
|
325
|
+
auth_response = client.authorization.call(
|
|
326
|
+
order.number,
|
|
327
|
+
order.total,
|
|
328
|
+
customer.email
|
|
329
|
+
)
|
|
330
|
+
|
|
331
|
+
order.update!(transaction_id: auth_response["bfs_bfsTxnId"])
|
|
332
|
+
|
|
333
|
+
# Return order for customer to complete payment
|
|
334
|
+
order
|
|
335
|
+
end
|
|
336
|
+
end
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### 2. Subscription Payments
|
|
340
|
+
|
|
341
|
+
```ruby
|
|
342
|
+
class SubscriptionPaymentService
|
|
343
|
+
def charge_subscription(subscription)
|
|
344
|
+
client = Rma::Payment::Gateway::Client.new
|
|
345
|
+
|
|
346
|
+
# Generate unique order number
|
|
347
|
+
order_no = "SUB-#{subscription.id}-#{Time.now.to_i}"
|
|
348
|
+
|
|
349
|
+
# Authorize payment
|
|
350
|
+
response = client.authorization.call(
|
|
351
|
+
order_no,
|
|
352
|
+
subscription.plan.price,
|
|
353
|
+
subscription.user.email
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
# Store transaction for later completion
|
|
357
|
+
subscription.payments.create!(
|
|
358
|
+
transaction_id: response["bfs_bfsTxnId"],
|
|
359
|
+
amount: subscription.plan.price,
|
|
360
|
+
status: 'pending'
|
|
361
|
+
)
|
|
362
|
+
end
|
|
363
|
+
end
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### 3. Refund Handling
|
|
367
|
+
|
|
368
|
+
```ruby
|
|
369
|
+
class RefundService
|
|
370
|
+
def process_refund(payment)
|
|
371
|
+
# Note: Refunds may need to be handled through RMA's admin interface
|
|
372
|
+
# This is a placeholder for your refund logic
|
|
373
|
+
|
|
374
|
+
payment.update!(
|
|
375
|
+
status: 'refund_requested',
|
|
376
|
+
refund_requested_at: Time.current
|
|
377
|
+
)
|
|
378
|
+
|
|
379
|
+
# Notify admin to process refund manually
|
|
380
|
+
AdminMailer.refund_requested(payment).deliver_later
|
|
381
|
+
end
|
|
382
|
+
end
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
## Best Practices
|
|
386
|
+
|
|
387
|
+
### 1. Error Handling
|
|
388
|
+
|
|
389
|
+
Always handle specific exceptions:
|
|
390
|
+
|
|
391
|
+
```ruby
|
|
392
|
+
begin
|
|
393
|
+
client.authorization.call(order_no, amount, email)
|
|
394
|
+
rescue Rma::Payment::Gateway::InvalidParameterError => e
|
|
395
|
+
# Handle validation errors - show to user
|
|
396
|
+
flash[:error] = "Invalid input: #{e.message}"
|
|
397
|
+
rescue Rma::Payment::Gateway::NetworkError => e
|
|
398
|
+
# Handle network errors - retry or show maintenance message
|
|
399
|
+
flash[:error] = "Service temporarily unavailable. Please try again."
|
|
400
|
+
rescue Rma::Payment::Gateway::Error => e
|
|
401
|
+
# Handle all other errors
|
|
402
|
+
flash[:error] = "Payment failed. Please contact support."
|
|
403
|
+
logger.error("RMA Payment Error: #{e.message}")
|
|
404
|
+
end
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### 2. Logging
|
|
408
|
+
|
|
409
|
+
Log transactions with masked sensitive data:
|
|
410
|
+
|
|
411
|
+
```ruby
|
|
412
|
+
def log_transaction(step, transaction_id, response)
|
|
413
|
+
Rails.logger.info({
|
|
414
|
+
step: step,
|
|
415
|
+
transaction_id: transaction_id,
|
|
416
|
+
response_code: response["bfs_responseCode"],
|
|
417
|
+
timestamp: Time.current
|
|
418
|
+
}.to_json)
|
|
419
|
+
end
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
### 3. Idempotency
|
|
423
|
+
|
|
424
|
+
Prevent duplicate payments:
|
|
425
|
+
|
|
426
|
+
```ruby
|
|
427
|
+
def authorize_payment(order)
|
|
428
|
+
return if order.rma_transaction_id.present?
|
|
429
|
+
|
|
430
|
+
# Proceed with authorization
|
|
431
|
+
response = client.authorization.call(...)
|
|
432
|
+
order.update!(rma_transaction_id: response["bfs_bfsTxnId"])
|
|
433
|
+
end
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
### 4. Validation
|
|
437
|
+
|
|
438
|
+
Validate inputs before API calls:
|
|
439
|
+
|
|
440
|
+
```ruby
|
|
441
|
+
def validate_payment_params(amount, email)
|
|
442
|
+
errors = []
|
|
443
|
+
|
|
444
|
+
unless Rma::Payment::Gateway::Utils.valid_amount?(amount)
|
|
445
|
+
errors << "Invalid amount"
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
unless Rma::Payment::Gateway::Utils.valid_email?(email)
|
|
449
|
+
errors << "Invalid email"
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
raise ArgumentError, errors.join(', ') if errors.any?
|
|
453
|
+
end
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
## Troubleshooting
|
|
457
|
+
|
|
458
|
+
### Common Issues
|
|
459
|
+
|
|
460
|
+
#### 1. Configuration Error
|
|
461
|
+
|
|
462
|
+
**Error:** `Missing required configuration fields`
|
|
463
|
+
|
|
464
|
+
**Solution:**
|
|
465
|
+
```ruby
|
|
466
|
+
# Check configuration
|
|
467
|
+
config = Rma::Payment::Gateway.configuration
|
|
468
|
+
puts config.missing_fields
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
#### 2. Network Timeout
|
|
472
|
+
|
|
473
|
+
**Error:** `Network error: execution expired`
|
|
474
|
+
|
|
475
|
+
**Solution:**
|
|
476
|
+
```ruby
|
|
477
|
+
# Increase timeout
|
|
478
|
+
Rma::Payment::Gateway.configure do |config|
|
|
479
|
+
config.timeout = 60
|
|
480
|
+
config.open_timeout = 20
|
|
481
|
+
end
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
#### 3. Invalid OTP
|
|
485
|
+
|
|
486
|
+
**Error:** `Debit request failed: Invalid OTP`
|
|
487
|
+
|
|
488
|
+
**Solution:**
|
|
489
|
+
- Verify OTP is entered correctly
|
|
490
|
+
- Check if OTP has expired
|
|
491
|
+
- Restart the payment flow if needed
|
|
492
|
+
|
|
493
|
+
#### 4. Transaction Not Found
|
|
494
|
+
|
|
495
|
+
**Error:** `Invalid transaction`
|
|
496
|
+
|
|
497
|
+
**Solution:**
|
|
498
|
+
- Verify transaction ID is stored correctly
|
|
499
|
+
- Check if transaction has expired
|
|
500
|
+
- Ensure all three steps use the same transaction ID
|
|
501
|
+
|
|
502
|
+
### Debug Mode
|
|
503
|
+
|
|
504
|
+
Enable detailed logging:
|
|
505
|
+
|
|
506
|
+
```ruby
|
|
507
|
+
# In Rails
|
|
508
|
+
Rails.logger.level = :debug
|
|
509
|
+
|
|
510
|
+
# Log all requests/responses
|
|
511
|
+
client = Rma::Payment::Gateway::Client.new
|
|
512
|
+
response = client.authorization.call(...)
|
|
513
|
+
Rails.logger.debug("RMA Response: #{response.inspect}")
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
## Support
|
|
517
|
+
|
|
518
|
+
For additional help:
|
|
519
|
+
|
|
520
|
+
- GitHub Issues: https://github.com/dcplbt/rma-payment-gateway/issues
|
|
521
|
+
- Email: tashii.dendupp@gmail.com
|
|
522
|
+
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "uri"
|
|
4
|
+
require "securerandom"
|
|
5
|
+
|
|
6
|
+
module Rma
|
|
7
|
+
module Payment
|
|
8
|
+
module Gateway
|
|
9
|
+
# Account Inquiry class for RMA Payment Gateway.
|
|
10
|
+
# Handles account inquiry for the RMA Payment Gateway client.
|
|
11
|
+
#
|
|
12
|
+
# @example
|
|
13
|
+
# auth = Rma::Payment::Gateway::AccountInquiry.new(client)
|
|
14
|
+
# auth.call(transaction_id, bank_id, account_no)
|
|
15
|
+
#
|
|
16
|
+
# @param client [Rma::Payment::Gateway::Client] Client instance
|
|
17
|
+
class AccountInquiry
|
|
18
|
+
attr_reader :client, :transaction_id, :bank_id, :account_no
|
|
19
|
+
|
|
20
|
+
def initialize(client)
|
|
21
|
+
@client = client
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Fetch account inquiry
|
|
25
|
+
# Returns the account inquiry response
|
|
26
|
+
def call(transaction_id, bank_id, account_no)
|
|
27
|
+
@transaction_id = transaction_id
|
|
28
|
+
@bank_id = bank_id
|
|
29
|
+
@account_no = account_no
|
|
30
|
+
response = client.post(
|
|
31
|
+
body: account_inquiry_request_body
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
validate_account_inquiry_response!(response)
|
|
35
|
+
|
|
36
|
+
response["result"]
|
|
37
|
+
rescue StandardError => e
|
|
38
|
+
raise AuthenticationError, "Failed to fetch account inquiry: #{e.message}"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def account_inquiry_request_body
|
|
44
|
+
params = {
|
|
45
|
+
bfs_bfsTxnId: transaction_id,
|
|
46
|
+
bfs_remitterBankId: bank_id,
|
|
47
|
+
bfs_remitterAccNo: account_no,
|
|
48
|
+
bfs_benfId: client.config.beneficiary_id,
|
|
49
|
+
bfs_msgType: "AE"
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
# Convert to URL-encoded format
|
|
53
|
+
URI.encode_www_form(params)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def validate_account_inquiry_response!(response)
|
|
57
|
+
unless response.is_a?(Hash) && response["result"]["bfs_responseCode"] == "00"
|
|
58
|
+
error_detail = response["result"]["bfs_responseDesc"] || "Unknown error"
|
|
59
|
+
raise AuthenticationError, "Account inquiry failed: #{error_detail}"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
return if response["result"]
|
|
63
|
+
|
|
64
|
+
raise AuthenticationError, "No response data in response"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
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.authorize
|
|
15
|
+
#
|
|
16
|
+
# @param client [Rma::Payment::Gateway::Client] Client instance
|
|
17
|
+
class Authorization
|
|
18
|
+
attr_reader :client, :order_no, :amount, :email
|
|
19
|
+
|
|
20
|
+
def initialize(client)
|
|
21
|
+
@client = client
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Fetch authorization token
|
|
25
|
+
# Returns the authorization response
|
|
26
|
+
def call(order_no, amount, email)
|
|
27
|
+
@order_no = order_no
|
|
28
|
+
@amount = amount
|
|
29
|
+
@email = email
|
|
30
|
+
validate_authorization_request!
|
|
31
|
+
response = client.post(body: authorization_request_body)
|
|
32
|
+
|
|
33
|
+
validate_authorization_response!(response)
|
|
34
|
+
|
|
35
|
+
response["result"]
|
|
36
|
+
rescue StandardError => e
|
|
37
|
+
raise AuthenticationError, "Failed to authorize: #{e.message}"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def authorization_request_body
|
|
43
|
+
params = {
|
|
44
|
+
bfs_benfTxnTime: Utils.generate_timestamp,
|
|
45
|
+
bfs_orderNo: order_no,
|
|
46
|
+
bfs_benfBankCode: "01",
|
|
47
|
+
bfs_txnCurrency: "BTN",
|
|
48
|
+
bfs_txnAmount: Utils.format_amount(amount),
|
|
49
|
+
bfs_remitterEmail: email,
|
|
50
|
+
bfs_paymentDesc: client.config.payment_description,
|
|
51
|
+
bfs_benfId: client.config.beneficiary_id,
|
|
52
|
+
bfs_msgType: "AR",
|
|
53
|
+
bfs_version: "5.0"
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
# Convert to URL-encoded format
|
|
57
|
+
URI.encode_www_form(params)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def validate_authorization_request!
|
|
61
|
+
raise InvalidParameterError, "Order number is required" if order_no.nil? || order_no.empty?
|
|
62
|
+
raise InvalidParameterError, "Amount is required" if amount.nil? || amount.empty?
|
|
63
|
+
raise InvalidParameterError, "Email is required" if email.nil? || email.empty?
|
|
64
|
+
raise InvalidParameterError, "Amount must be a number" unless Utils.valid_amount?(amount)
|
|
65
|
+
raise InvalidParameterError, "Email must be a valid email" unless Utils.valid_email?(email)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def validate_authorization_response!(response)
|
|
69
|
+
unless response.is_a?(Hash) && response["result"]["bfs_responseCode"] == "00"
|
|
70
|
+
error_detail = response["result"]["bfs_responseDesc"] || "Unknown error"
|
|
71
|
+
raise AuthenticationError, "Authorization failed: #{error_detail}"
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
return if response["result"]
|
|
75
|
+
|
|
76
|
+
raise AuthenticationError, "No response data in response"
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|