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/API.md
ADDED
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
# API Documentation
|
|
2
|
+
|
|
3
|
+
This document provides detailed information about the RMA Payment Gateway API integration.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Overview](#overview)
|
|
8
|
+
- [Authentication](#authentication)
|
|
9
|
+
- [API Endpoints](#api-endpoints)
|
|
10
|
+
- [Request/Response Format](#requestresponse-format)
|
|
11
|
+
- [Payment Flow](#payment-flow)
|
|
12
|
+
- [Error Codes](#error-codes)
|
|
13
|
+
|
|
14
|
+
## Overview
|
|
15
|
+
|
|
16
|
+
The RMA Payment Gateway API uses a REST-like interface with URL-encoded form data for requests and JSON responses. All communication must be done over HTTPS.
|
|
17
|
+
|
|
18
|
+
**Base URL:** Configured via `RMA_BASE_URL` environment variable
|
|
19
|
+
|
|
20
|
+
**API Endpoint:** `/BFSSecure/nvpapi`
|
|
21
|
+
|
|
22
|
+
## Authentication
|
|
23
|
+
|
|
24
|
+
The API uses RSA key-based authentication. You must:
|
|
25
|
+
|
|
26
|
+
1. Obtain an RSA private key from RMA
|
|
27
|
+
2. Store the key securely
|
|
28
|
+
3. Configure the key path in your application
|
|
29
|
+
|
|
30
|
+
```ruby
|
|
31
|
+
config.rsa_key_path = '/path/to/rsa_private_key.pem'
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## API Endpoints
|
|
35
|
+
|
|
36
|
+
All requests are sent to the same endpoint with different message types (`bfs_msgType`):
|
|
37
|
+
|
|
38
|
+
### Base Endpoint
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
POST /BFSSecure/nvpapi
|
|
42
|
+
Content-Type: application/x-www-form-urlencoded
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Request/Response Format
|
|
46
|
+
|
|
47
|
+
### Request Format
|
|
48
|
+
|
|
49
|
+
All requests are sent as URL-encoded form data:
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
bfs_param1=value1&bfs_param2=value2&bfs_param3=value3
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Response Format
|
|
56
|
+
|
|
57
|
+
All responses are returned as JSON:
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"result": {
|
|
62
|
+
"bfs_responseCode": "00",
|
|
63
|
+
"bfs_responseDesc": "Success",
|
|
64
|
+
"bfs_bfsTxnId": "TXN123456789",
|
|
65
|
+
...
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Payment Flow
|
|
71
|
+
|
|
72
|
+
### 1. Payment Authorization (AR)
|
|
73
|
+
|
|
74
|
+
**Purpose:** Initiate a payment request
|
|
75
|
+
|
|
76
|
+
**Message Type:** `AR` (Authorization Request)
|
|
77
|
+
|
|
78
|
+
**Request Parameters:**
|
|
79
|
+
|
|
80
|
+
| Parameter | Type | Required | Description |
|
|
81
|
+
|-----------|------|----------|-------------|
|
|
82
|
+
| `bfs_benfTxnTime` | String | Yes | Transaction timestamp (YYYYMMDDHHmmss) |
|
|
83
|
+
| `bfs_orderNo` | String | Yes | Unique order number |
|
|
84
|
+
| `bfs_benfBankCode` | String | Yes | Beneficiary bank code (default: "01") |
|
|
85
|
+
| `bfs_txnCurrency` | String | Yes | Transaction currency (BTN) |
|
|
86
|
+
| `bfs_txnAmount` | String | Yes | Transaction amount (format: "100.00") |
|
|
87
|
+
| `bfs_remitterEmail` | String | Yes | Customer email address |
|
|
88
|
+
| `bfs_paymentDesc` | String | Yes | Payment description |
|
|
89
|
+
| `bfs_benfId` | String | Yes | Beneficiary/Merchant ID |
|
|
90
|
+
| `bfs_msgType` | String | Yes | Message type ("AR") |
|
|
91
|
+
| `bfs_version` | String | Yes | API version ("5.0") |
|
|
92
|
+
|
|
93
|
+
**Example Request:**
|
|
94
|
+
|
|
95
|
+
```ruby
|
|
96
|
+
client.authorization.call(
|
|
97
|
+
"ORDER123", # order_no
|
|
98
|
+
100.50, # amount
|
|
99
|
+
"customer@email.com" # email
|
|
100
|
+
)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Example Response:**
|
|
104
|
+
|
|
105
|
+
```json
|
|
106
|
+
{
|
|
107
|
+
"result": {
|
|
108
|
+
"bfs_responseCode": "00",
|
|
109
|
+
"bfs_responseDesc": "Success",
|
|
110
|
+
"bfs_bfsTxnId": "TXN123456789",
|
|
111
|
+
"bfs_orderNo": "ORDER123",
|
|
112
|
+
"bfs_txnAmount": "100.50",
|
|
113
|
+
"bfs_txnCurrency": "BTN",
|
|
114
|
+
"bfs_benfTxnTime": "20231215143022"
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Response Fields:**
|
|
120
|
+
|
|
121
|
+
| Field | Type | Description |
|
|
122
|
+
|-------|------|-------------|
|
|
123
|
+
| `bfs_responseCode` | String | Response code ("00" for success) |
|
|
124
|
+
| `bfs_responseDesc` | String | Response description |
|
|
125
|
+
| `bfs_bfsTxnId` | String | Transaction ID (use for subsequent steps) |
|
|
126
|
+
| `bfs_orderNo` | String | Order number |
|
|
127
|
+
| `bfs_txnAmount` | String | Transaction amount |
|
|
128
|
+
| `bfs_txnCurrency` | String | Transaction currency |
|
|
129
|
+
| `bfs_benfTxnTime` | String | Transaction timestamp |
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
### 2. Account Inquiry (AE)
|
|
134
|
+
|
|
135
|
+
**Purpose:** Verify customer's bank account and trigger OTP
|
|
136
|
+
|
|
137
|
+
**Message Type:** `AE` (Account Enquiry)
|
|
138
|
+
|
|
139
|
+
**Request Parameters:**
|
|
140
|
+
|
|
141
|
+
| Parameter | Type | Required | Description |
|
|
142
|
+
|-----------|------|----------|-------------|
|
|
143
|
+
| `bfs_bfsTxnId` | String | Yes | Transaction ID from authorization |
|
|
144
|
+
| `bfs_remitterBankId` | String | Yes | Customer's bank code |
|
|
145
|
+
| `bfs_remitterAccNo` | String | Yes | Customer's account number |
|
|
146
|
+
| `bfs_benfId` | String | Yes | Beneficiary/Merchant ID |
|
|
147
|
+
| `bfs_msgType` | String | Yes | Message type ("AE") |
|
|
148
|
+
|
|
149
|
+
**Example Request:**
|
|
150
|
+
|
|
151
|
+
```ruby
|
|
152
|
+
client.account_inquiry.call(
|
|
153
|
+
"TXN123456789", # transaction_id
|
|
154
|
+
"1010", # bank_id
|
|
155
|
+
"12345678" # account_no
|
|
156
|
+
)
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**Example Response:**
|
|
160
|
+
|
|
161
|
+
```json
|
|
162
|
+
{
|
|
163
|
+
"result": {
|
|
164
|
+
"bfs_responseCode": "00",
|
|
165
|
+
"bfs_responseDesc": "Success",
|
|
166
|
+
"bfs_bfsTxnId": "TXN123456789",
|
|
167
|
+
"bfs_remitterName": "John Doe",
|
|
168
|
+
"bfs_remitterAccNo": "12345678",
|
|
169
|
+
"bfs_remitterBankId": "1010"
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**Response Fields:**
|
|
175
|
+
|
|
176
|
+
| Field | Type | Description |
|
|
177
|
+
|-------|------|-------------|
|
|
178
|
+
| `bfs_responseCode` | String | Response code ("00" for success) |
|
|
179
|
+
| `bfs_responseDesc` | String | Response description |
|
|
180
|
+
| `bfs_bfsTxnId` | String | Transaction ID |
|
|
181
|
+
| `bfs_remitterName` | String | Account holder name |
|
|
182
|
+
| `bfs_remitterAccNo` | String | Account number |
|
|
183
|
+
| `bfs_remitterBankId` | String | Bank code |
|
|
184
|
+
|
|
185
|
+
**Note:** After successful account inquiry, an OTP is sent to the customer's registered mobile number.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
### 3. Debit Request (DR)
|
|
190
|
+
|
|
191
|
+
**Purpose:** Complete the payment transaction with OTP
|
|
192
|
+
|
|
193
|
+
**Message Type:** `DR` (Debit Request)
|
|
194
|
+
|
|
195
|
+
**Request Parameters:**
|
|
196
|
+
|
|
197
|
+
| Parameter | Type | Required | Description |
|
|
198
|
+
|-----------|------|----------|-------------|
|
|
199
|
+
| `bfs_bfsTxnId` | String | Yes | Transaction ID from authorization |
|
|
200
|
+
| `bfs_remitterOtp` | String | Yes | OTP received by customer |
|
|
201
|
+
| `bfs_benfId` | String | Yes | Beneficiary/Merchant ID |
|
|
202
|
+
| `bfs_msgType` | String | Yes | Message type ("DR") |
|
|
203
|
+
|
|
204
|
+
**Example Request:**
|
|
205
|
+
|
|
206
|
+
```ruby
|
|
207
|
+
client.debit_request.call(
|
|
208
|
+
"TXN123456789", # transaction_id
|
|
209
|
+
"123456" # otp
|
|
210
|
+
)
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**Example Response:**
|
|
214
|
+
|
|
215
|
+
```json
|
|
216
|
+
{
|
|
217
|
+
"result": {
|
|
218
|
+
"bfs_responseCode": "00",
|
|
219
|
+
"bfs_responseDesc": "Transaction Successful",
|
|
220
|
+
"bfs_bfsTxnId": "TXN123456789",
|
|
221
|
+
"bfs_txnAmount": "100.50",
|
|
222
|
+
"bfs_orderNo": "ORDER123",
|
|
223
|
+
"bfs_txnCurrency": "BTN"
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
**Response Fields:**
|
|
229
|
+
|
|
230
|
+
| Field | Type | Description |
|
|
231
|
+
|-------|------|-------------|
|
|
232
|
+
| `bfs_responseCode` | String | Response code ("00" for success) |
|
|
233
|
+
| `bfs_responseDesc` | String | Response description |
|
|
234
|
+
| `bfs_bfsTxnId` | String | Transaction ID |
|
|
235
|
+
| `bfs_txnAmount` | String | Transaction amount |
|
|
236
|
+
| `bfs_orderNo` | String | Order number |
|
|
237
|
+
| `bfs_txnCurrency` | String | Transaction currency |
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## Error Codes
|
|
242
|
+
|
|
243
|
+
### Response Codes
|
|
244
|
+
|
|
245
|
+
| Code | Description | Action Required |
|
|
246
|
+
|------|-------------|-----------------|
|
|
247
|
+
| `00` | Success | Transaction completed successfully |
|
|
248
|
+
| `01` | Invalid request | Check request parameters |
|
|
249
|
+
| `02` | Invalid beneficiary | Verify beneficiary ID configuration |
|
|
250
|
+
| `03` | Invalid transaction | Check transaction ID |
|
|
251
|
+
| `04` | Insufficient funds | Customer needs to add funds |
|
|
252
|
+
| `05` | Invalid OTP | Customer should re-enter OTP |
|
|
253
|
+
| `06` | OTP expired | Restart the transaction |
|
|
254
|
+
| `07` | Transaction timeout | Restart the transaction |
|
|
255
|
+
| `08` | Account blocked | Customer should contact their bank |
|
|
256
|
+
| `09` | Invalid account | Verify account number |
|
|
257
|
+
| `10` | Service unavailable | Retry later |
|
|
258
|
+
| `99` | System error | Contact RMA support |
|
|
259
|
+
|
|
260
|
+
### HTTP Status Codes
|
|
261
|
+
|
|
262
|
+
| Status | Description | Gem Exception |
|
|
263
|
+
|--------|-------------|---------------|
|
|
264
|
+
| 200 | Success | - |
|
|
265
|
+
| 400 | Bad Request | `InvalidParameterError` |
|
|
266
|
+
| 401 | Unauthorized | `AuthenticationError` |
|
|
267
|
+
| 403 | Forbidden | `AuthenticationError` |
|
|
268
|
+
| 404 | Not Found | `APIError` |
|
|
269
|
+
| 422 | Unprocessable Entity | `InvalidParameterError` |
|
|
270
|
+
| 500 | Internal Server Error | `APIError` |
|
|
271
|
+
| 502 | Bad Gateway | `NetworkError` |
|
|
272
|
+
| 503 | Service Unavailable | `NetworkError` |
|
|
273
|
+
| 504 | Gateway Timeout | `NetworkError` |
|
|
274
|
+
|
|
275
|
+
## Bank Codes
|
|
276
|
+
|
|
277
|
+
Supported banks in Bhutan:
|
|
278
|
+
|
|
279
|
+
| Code | Bank Name | Abbreviation |
|
|
280
|
+
|------|-----------|--------------|
|
|
281
|
+
| 1010 | Bank of Bhutan | BOBL |
|
|
282
|
+
| 1020 | Bhutan National Bank | BNBL |
|
|
283
|
+
| 1030 | Druk PNB Bank Limited | DPNBL |
|
|
284
|
+
| 1040 | Tashi Bank | TBank |
|
|
285
|
+
| 1050 | Bhutan Development Bank Limited | BDBL |
|
|
286
|
+
| 1060 | Digital Kidu | DK Bank |
|
|
287
|
+
|
|
288
|
+
## Best Practices
|
|
289
|
+
|
|
290
|
+
### 1. Transaction ID Management
|
|
291
|
+
|
|
292
|
+
- Store transaction IDs securely
|
|
293
|
+
- Use transaction IDs for reconciliation
|
|
294
|
+
- Keep transaction logs for audit purposes
|
|
295
|
+
|
|
296
|
+
### 2. Error Handling
|
|
297
|
+
|
|
298
|
+
- Always handle all exception types
|
|
299
|
+
- Log errors with masked sensitive data
|
|
300
|
+
- Provide user-friendly error messages
|
|
301
|
+
|
|
302
|
+
### 3. Timeout Handling
|
|
303
|
+
|
|
304
|
+
- Set appropriate timeout values
|
|
305
|
+
- Implement retry logic for network errors
|
|
306
|
+
- Don't retry on validation errors
|
|
307
|
+
|
|
308
|
+
### 4. Security
|
|
309
|
+
|
|
310
|
+
- Never log sensitive data (OTP, account numbers)
|
|
311
|
+
- Use HTTPS for all communications
|
|
312
|
+
- Validate all inputs before sending to API
|
|
313
|
+
- Store RSA keys securely
|
|
314
|
+
|
|
315
|
+
### 5. Testing
|
|
316
|
+
|
|
317
|
+
- Test with small amounts first
|
|
318
|
+
- Verify all three steps of the flow
|
|
319
|
+
- Test error scenarios
|
|
320
|
+
- Implement idempotency for retries
|
|
321
|
+
|
|
322
|
+
## Rate Limiting
|
|
323
|
+
|
|
324
|
+
The API may implement rate limiting. Best practices:
|
|
325
|
+
|
|
326
|
+
- Implement exponential backoff for retries
|
|
327
|
+
- Cache transaction results
|
|
328
|
+
- Don't make duplicate requests
|
|
329
|
+
- Monitor API usage
|
|
330
|
+
|
|
331
|
+
## Support
|
|
332
|
+
|
|
333
|
+
For API-related issues:
|
|
334
|
+
|
|
335
|
+
- Check error codes and messages
|
|
336
|
+
- Review request/response logs
|
|
337
|
+
- Contact RMA technical support
|
|
338
|
+
- Email: tashii.dendupp@gmail.com
|
|
339
|
+
|