malipopay 1.0.0 → 1.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6492c53849e03b8431bfc390b4418b1077c18d7aa8098fc4aedb8507aeb0489b
4
- data.tar.gz: dd706e99038d9fede2fd15a7777192087d6ab3b1b8b429b60635911e7e05ee7a
3
+ metadata.gz: e472a0e35ebdb2ad9aa143d0eb17be62a2f9b3c7bec38953c0f846c43c2e6fa4
4
+ data.tar.gz: c2ffc9936a1e8b99945f7e076cfb7347f56d51180ea9b3f047fd4ad9b9ebeda1
5
5
  SHA512:
6
- metadata.gz: 00a447b13ed9b346df7ec49320179839fef574d44ef8c6e4faa16dc1ce2f26c948e6db20b014321ab83e0f5b4545f72e0ee0da0da53dc983f3868491974fe6ae
7
- data.tar.gz: 158b3238b9f5a93ece0b32a078390733864ba04277be4bdab54ca789ce2e405f1931b9e693e44507bcfebb08a32ea878ce928deaeed982a623ea0228aa09b948
6
+ metadata.gz: 5f52cb4533c575fee99dc51e84e2194d2a6879eb533899b15d936db30e0e599757886e1aae530aca77c9c847e13fd631b707898dae5587772e4cc311ed760b41
7
+ data.tar.gz: 1baff51a27700c5f6ea005ab114a1356e7dc0af9542e799c893697223027c9554862826988196c877133815f0f6c1fbd8f0ebaf0daa86d00f94cf6781410b6b7
data/CLAUDE.md ADDED
@@ -0,0 +1,89 @@
1
+ # Malipopay SDK Development Rules
2
+
3
+ ## Naming Convention — CRITICAL
4
+
5
+ The brand name is **Malipopay** (single capital M, all lowercase after). Never use "MaliPoPay" with capital P-o-P.
6
+
7
+ | Context | Correct | Wrong |
8
+ |---------|---------|-------|
9
+ | PascalCase class | `Malipopay` | `MaliPoPay` |
10
+ | Error class | `MalipopayError` | `MaliPoPayError` |
11
+ | Exception class | `MalipopayException` | `MaliPoPayException` |
12
+ | Config type | `MalipopayConfig` | `MaliPoPayConfig` |
13
+ | Options type | `MalipopayOptions` | `MaliPoPayOptions` |
14
+ | Client class | `MalipopayClient` | `MaliPoPayClient` |
15
+ | Module/package | `malipopay` | ✅ already correct |
16
+ | In docs/prose | "Malipopay" or "malipopay" | "MaliPoPay" |
17
+ | URLs/paths | `malipopay` | ✅ already correct |
18
+
19
+ ### Per-Language Examples
20
+
21
+ ```typescript
22
+ // Node.js / TypeScript
23
+ import { Malipopay, MalipopayError } from "malipopay";
24
+ const client = new Malipopay("api-key");
25
+ ```
26
+
27
+ ```python
28
+ # Python
29
+ from malipopay import Malipopay, AsyncMalipopay, MalipopayError
30
+ client = Malipopay("api-key")
31
+ ```
32
+
33
+ ```php
34
+ // PHP
35
+ use Malipopay\Malipopay;
36
+ use Malipopay\Exceptions\MalipopayException;
37
+ $client = new Malipopay("api-key");
38
+ ```
39
+
40
+ ```java
41
+ // Java
42
+ import co.tz.malipopay.Malipopay;
43
+ import co.tz.malipopay.MalipopayConfig;
44
+ Malipopay client = new Malipopay("api-key");
45
+ ```
46
+
47
+ ```csharp
48
+ // C# / .NET
49
+ using Malipopay;
50
+ var client = new MalipopayClient("api-key");
51
+ ```
52
+
53
+ ```ruby
54
+ # Ruby
55
+ require "malipopay"
56
+ client = Malipopay::Client.new(api_key: "api-key")
57
+ ```
58
+
59
+ ## SDK Architecture
60
+
61
+ - **Resource-oriented:** `client.payments.collect()`, `client.customers.create()`
62
+ - **Auth:** `apiToken` header (API key from dashboard)
63
+ - **Base URLs:**
64
+ - Production: `https://core-prod.malipopay.co.tz`
65
+ - UAT: `https://core-uat.malipopay.co.tz`
66
+ - **Error hierarchy:** `MalipopayError` → `AuthenticationError`, `ValidationError`, `NotFoundError`, `PermissionError`, `RateLimitError`, `ApiError`, `ConnectionError`
67
+
68
+ ## GitHub Organization
69
+
70
+ https://github.com/Malipopay
71
+
72
+ ## Package Registries
73
+
74
+ | Language | Package | Registry |
75
+ |----------|---------|----------|
76
+ | Node.js | `malipopay` | npm |
77
+ | Python | `malipopay` | PyPI |
78
+ | PHP | `malipopay/malipopay-php` | Packagist |
79
+ | Java | `co.tz.malipopay:malipopay-java` | Maven Central |
80
+ | .NET | `Malipopay` | NuGet |
81
+ | Ruby | `malipopay` | RubyGems |
82
+
83
+ ## Company
84
+
85
+ - **Company:** Lockwood Technology Ltd
86
+ - **Product:** Malipopay
87
+ - **Website:** malipopay.co.tz
88
+ - **Developer Docs:** developers.malipopay.co.tz
89
+ - **Support:** support@malipopay.co.tz
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # MaliPoPay Ruby SDK
1
+ # Malipopay Ruby SDK
2
2
 
3
- Official Ruby SDK for the [MaliPoPay](https://malipopay.co.tz) payment platform (Tanzania).
3
+ Official Ruby SDK for the [Malipopay](https://malipopay.co.tz) payment platform (Tanzania).
4
4
 
5
5
  ## Installation
6
6
 
@@ -27,7 +27,7 @@ gem install malipopay
27
27
  ```ruby
28
28
  require "malipopay"
29
29
 
30
- client = MaliPoPay::Client.new(
30
+ client = Malipopay::Client.new(
31
31
  api_key: "your_api_token",
32
32
  environment: :production # or :uat for testing
33
33
  )
@@ -37,7 +37,7 @@ client = MaliPoPay::Client.new(
37
37
 
38
38
  | Option | Default | Description |
39
39
  |------------------|---------------|--------------------------------------|
40
- | `api_key` | *required* | Your MaliPoPay API token |
40
+ | `api_key` | *required* | Your Malipopay API token |
41
41
  | `environment` | `:production` | `:production` or `:uat` |
42
42
  | `base_url` | `nil` | Override the base URL |
43
43
  | `timeout` | `30` | Request timeout in seconds |
@@ -201,7 +201,7 @@ client.account.trial_balance
201
201
  client.sms.send_sms(
202
202
  to: "255712345678",
203
203
  message: "Your payment of TZS 10,000 has been received.",
204
- senderId: "MaliPoPay"
204
+ senderId: "Malipopay"
205
205
  )
206
206
 
207
207
  # Send bulk SMS
@@ -210,14 +210,14 @@ client.sms.send_bulk(
210
210
  { to: "255712345678", message: "Hello John!" },
211
211
  { to: "255798765432", message: "Hello Jane!" }
212
212
  ],
213
- senderId: "MaliPoPay"
213
+ senderId: "Malipopay"
214
214
  )
215
215
 
216
216
  # Schedule SMS
217
217
  client.sms.schedule(
218
218
  to: "255712345678",
219
219
  message: "Reminder: Your invoice is due tomorrow.",
220
- senderId: "MaliPoPay",
220
+ senderId: "Malipopay",
221
221
  scheduledAt: "2026-04-15T09:00:00Z"
222
222
  )
223
223
  ```
@@ -235,15 +235,15 @@ business_types = client.references.business_types
235
235
  ## Webhooks
236
236
 
237
237
  ```ruby
238
- client = MaliPoPay::Client.new(
238
+ client = Malipopay::Client.new(
239
239
  api_key: "your_api_token",
240
240
  webhook_secret: "whsec_your_secret"
241
241
  )
242
242
 
243
243
  # In your webhook endpoint (e.g., Sinatra, Rails controller)
244
244
  payload = request.body.read
245
- signature = request.headers["X-MaliPoPay-Signature"]
246
- timestamp = request.headers["X-MaliPoPay-Timestamp"]
245
+ signature = request.headers["X-Malipopay-Signature"]
246
+ timestamp = request.headers["X-Malipopay-Timestamp"]
247
247
 
248
248
  event = client.webhooks.construct_event(payload, signature, timestamp: timestamp)
249
249
 
@@ -260,20 +260,20 @@ end
260
260
  ```ruby
261
261
  begin
262
262
  client.payments.collect(amount: 10_000, phone: "255712345678")
263
- rescue MaliPoPay::AuthenticationError => e
263
+ rescue Malipopay::AuthenticationError => e
264
264
  # Invalid API key (401)
265
- rescue MaliPoPay::PermissionError => e
265
+ rescue Malipopay::PermissionError => e
266
266
  # Insufficient permissions (403)
267
- rescue MaliPoPay::NotFoundError => e
267
+ rescue Malipopay::NotFoundError => e
268
268
  # Resource not found (404)
269
- rescue MaliPoPay::ValidationError => e
269
+ rescue Malipopay::ValidationError => e
270
270
  # Invalid parameters (400/422)
271
271
  puts e.errors
272
- rescue MaliPoPay::RateLimitError => e
272
+ rescue Malipopay::RateLimitError => e
273
273
  # Rate limited (429) - retry after e.retry_after seconds
274
- rescue MaliPoPay::ApiError => e
274
+ rescue Malipopay::ApiError => e
275
275
  # Server error (5xx)
276
- rescue MaliPoPay::ConnectionError => e
276
+ rescue Malipopay::ConnectionError => e
277
277
  # Network error
278
278
  end
279
279
  ```
@@ -305,7 +305,7 @@ MIT License - Copyright (c) 2026 [Lockwood Technology Ltd](https://lockwood.co.t
305
305
  | [Python](https://github.com/Malipopay/malipopay-python) | `pip install malipopay` |
306
306
  | [PHP](https://github.com/Malipopay/malipopay-php) | `composer require malipopay/malipopay-php` |
307
307
  | [Java](https://github.com/Malipopay/malipopay-java) | Maven / Gradle |
308
- | [.NET](https://github.com/Malipopay/malipopay-dotnet) | `dotnet add package MaliPoPay` |
308
+ | [.NET](https://github.com/Malipopay/malipopay-dotnet) | `dotnet add package Malipopay` |
309
309
  | [Ruby](https://github.com/Malipopay/malipopay-ruby) | `gem install malipopay` |
310
310
 
311
311
  [API Reference](https://developers.malipopay.co.tz) | [OpenAPI Spec](https://github.com/Malipopay/malipopay-openapi) | [Test Scenarios](https://github.com/Malipopay/malipopay-sdk-tests)
@@ -1,13 +1,13 @@
1
1
  # Configuration
2
2
 
3
- This guide covers all the ways to configure the MaliPoPay Ruby SDK, from basic client setup to Rails integration.
3
+ This guide covers all the ways to configure the Malipopay Ruby SDK, from basic client setup to Rails integration.
4
4
 
5
- ## MaliPoPay::Client Options
5
+ ## Malipopay::Client Options
6
6
 
7
- The `MaliPoPay::Client.new` constructor accepts the following options:
7
+ The `Malipopay::Client.new` constructor accepts the following options:
8
8
 
9
9
  ```ruby
10
- client = MaliPoPay::Client.new(
10
+ client = Malipopay::Client.new(
11
11
  api_key: 'your_api_key',
12
12
  environment: :production, # or :uat
13
13
  base_url: nil, # overrides environment if set
@@ -21,7 +21,7 @@ client = MaliPoPay::Client.new(
21
21
 
22
22
  | Option | Type | Default | Description |
23
23
  |--------|------|---------|-------------|
24
- | `api_key` | `String` | *required* | Your MaliPoPay API key |
24
+ | `api_key` | `String` | *required* | Your Malipopay API key |
25
25
  | `environment` | `Symbol` | `:production` | `:production` or `:uat` |
26
26
  | `base_url` | `String` | `nil` | Custom base URL; overrides `environment` when set |
27
27
  | `timeout` | `Integer` | `30` | HTTP request timeout in seconds |
@@ -41,10 +41,10 @@ The SDK accepts both symbols and strings for the `environment` option. Symbols a
41
41
 
42
42
  ```ruby
43
43
  # Preferred (symbol)
44
- client = MaliPoPay::Client.new(api_key: key, environment: :uat)
44
+ client = Malipopay::Client.new(api_key: key, environment: :uat)
45
45
 
46
46
  # Also works (string)
47
- client = MaliPoPay::Client.new(api_key: key, environment: 'uat')
47
+ client = Malipopay::Client.new(api_key: key, environment: 'uat')
48
48
  ```
49
49
 
50
50
  The same applies to provider names in payment methods -- you can use either:
@@ -61,13 +61,13 @@ client.payments.collect(provider: :'M-Pesa', ...)
61
61
 
62
62
  ```ruby
63
63
  # Production with defaults (30s timeout, 2 retries)
64
- client = MaliPoPay::Client.new(api_key: ENV['MALIPOPAY_API_KEY'])
64
+ client = Malipopay::Client.new(api_key: ENV['MALIPOPAY_API_KEY'])
65
65
  ```
66
66
 
67
67
  ### UAT for Testing
68
68
 
69
69
  ```ruby
70
- client = MaliPoPay::Client.new(
70
+ client = Malipopay::Client.new(
71
71
  api_key: ENV['MALIPOPAY_UAT_API_KEY'],
72
72
  environment: :uat
73
73
  )
@@ -76,7 +76,7 @@ client = MaliPoPay::Client.new(
76
76
  ### Custom Timeout and Retries
77
77
 
78
78
  ```ruby
79
- client = MaliPoPay::Client.new(
79
+ client = Malipopay::Client.new(
80
80
  api_key: ENV['MALIPOPAY_API_KEY'],
81
81
  environment: :production,
82
82
  timeout: 60, # longer timeout for slow networks
@@ -88,7 +88,7 @@ client = MaliPoPay::Client.new(
88
88
 
89
89
  ### Automatic Based on RACK_ENV / RAILS_ENV
90
90
 
91
- Tie the MaliPoPay environment to your application environment:
91
+ Tie the Malipopay environment to your application environment:
92
92
 
93
93
  ```ruby
94
94
  malipopay_env = if ENV['RACK_ENV'] == 'production' || ENV['RAILS_ENV'] == 'production'
@@ -103,7 +103,7 @@ api_key = if malipopay_env == :production
103
103
  ENV.fetch('MALIPOPAY_UAT_API_KEY')
104
104
  end
105
105
 
106
- client = MaliPoPay::Client.new(
106
+ client = Malipopay::Client.new(
107
107
  api_key: api_key,
108
108
  environment: malipopay_env
109
109
  )
@@ -114,7 +114,7 @@ client = MaliPoPay::Client.new(
114
114
  For proxies or custom routing:
115
115
 
116
116
  ```ruby
117
- client = MaliPoPay::Client.new(
117
+ client = Malipopay::Client.new(
118
118
  api_key: ENV['MALIPOPAY_API_KEY'],
119
119
  base_url: 'https://custom-proxy.example.com'
120
120
  )
@@ -131,7 +131,7 @@ Create a Rails initializer to configure the client globally:
131
131
  ```ruby
132
132
  # config/initializers/malipopay.rb
133
133
 
134
- MALIPOPAY_CLIENT = MaliPoPay::Client.new(
134
+ MALIPOPAY_CLIENT = Malipopay::Client.new(
135
135
  api_key: Rails.application.credentials.dig(:malipopay, :api_key) ||
136
136
  ENV.fetch('MALIPOPAY_API_KEY'),
137
137
  environment: Rails.env.production? ? :production : :uat,
@@ -161,7 +161,7 @@ class PaymentsController < ApplicationController
161
161
  else
162
162
  render json: { error: result['message'] }, status: :unprocessable_entity
163
163
  end
164
- rescue MaliPoPay::Error => e
164
+ rescue Malipopay::Error => e
165
165
  render json: { error: e.message }, status: :service_unavailable
166
166
  end
167
167
  end
@@ -175,7 +175,7 @@ Store your API keys securely with Rails credentials:
175
175
  EDITOR=vim rails credentials:edit
176
176
  ```
177
177
 
178
- Add your MaliPoPay keys:
178
+ Add your Malipopay keys:
179
179
 
180
180
  ```yaml
181
181
  malipopay:
@@ -224,7 +224,7 @@ require 'sinatra'
224
224
  require 'malipopay'
225
225
 
226
226
  configure do
227
- set :malipopay, MaliPoPay::Client.new(
227
+ set :malipopay, Malipopay::Client.new(
228
228
  api_key: ENV.fetch('MALIPOPAY_API_KEY'),
229
229
  environment: settings.production? ? :production : :uat
230
230
  )
@@ -248,14 +248,14 @@ end
248
248
 
249
249
  ### Timeout
250
250
 
251
- The `timeout` option controls how long the SDK waits for an API response before raising `MaliPoPay::ConnectionError`:
251
+ The `timeout` option controls how long the SDK waits for an API response before raising `Malipopay::ConnectionError`:
252
252
 
253
253
  ```ruby
254
254
  # Short timeout for fast-fail scenarios
255
- client = MaliPoPay::Client.new(api_key: key, timeout: 10)
255
+ client = Malipopay::Client.new(api_key: key, timeout: 10)
256
256
 
257
257
  # Longer timeout for slow networks or large batch operations
258
- client = MaliPoPay::Client.new(api_key: key, timeout: 120)
258
+ client = Malipopay::Client.new(api_key: key, timeout: 120)
259
259
  ```
260
260
 
261
261
  ### Retries
@@ -264,10 +264,10 @@ The `retries` option controls how many times the SDK retries on transient errors
264
264
 
265
265
  ```ruby
266
266
  # No automatic retries (handle retries yourself)
267
- client = MaliPoPay::Client.new(api_key: key, retries: 0)
267
+ client = Malipopay::Client.new(api_key: key, retries: 0)
268
268
 
269
269
  # Aggressive retries for critical operations
270
- client = MaliPoPay::Client.new(api_key: key, retries: 5)
270
+ client = Malipopay::Client.new(api_key: key, retries: 5)
271
271
  ```
272
272
 
273
273
  The SDK uses exponential backoff between retries (1s, 2s, 4s, ...).
data/docs/customers.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Customers
2
2
 
3
- The `customers` resource lets you create, retrieve, search, and verify customer records. Customers are linked to payments, invoices, and transaction history in MaliPoPay.
3
+ The `customers` resource lets you create, retrieve, search, and verify customer records. Customers are linked to payments, invoices, and transaction history in Malipopay.
4
4
 
5
5
  ## Create a Customer
6
6
 
@@ -71,7 +71,7 @@ end
71
71
 
72
72
  ## Get a Customer by Customer Number
73
73
 
74
- Look up using the MaliPoPay-assigned customer number:
74
+ Look up using the Malipopay-assigned customer number:
75
75
 
76
76
  ```ruby
77
77
  customer = client.customers.get_by_number('CUST-2024-001')
@@ -118,11 +118,11 @@ begin
118
118
  name: 'Incomplete Customer'
119
119
  # missing phone -- will trigger validation error
120
120
  )
121
- rescue MaliPoPay::ValidationError => e
121
+ rescue Malipopay::ValidationError => e
122
122
  puts "Missing required fields: #{e.message}"
123
- rescue MaliPoPay::NotFoundError
123
+ rescue Malipopay::NotFoundError
124
124
  puts 'Customer not found.'
125
- rescue MaliPoPay::Error => e
125
+ rescue Malipopay::Error => e
126
126
  puts "Error: #{e.message}"
127
127
  end
128
128
  ```
@@ -1,18 +1,18 @@
1
1
  # Error Handling
2
2
 
3
- The MaliPoPay Ruby SDK uses a structured exception hierarchy so you can rescue specific error types and respond appropriately. All exceptions inherit from `MaliPoPay::Error`.
3
+ The Malipopay Ruby SDK uses a structured exception hierarchy so you can rescue specific error types and respond appropriately. All exceptions inherit from `Malipopay::Error`.
4
4
 
5
5
  ## Exception Hierarchy
6
6
 
7
7
  ```
8
- MaliPoPay::Error (base)
9
- ├── MaliPoPay::AuthenticationError (HTTP 401 -- invalid or missing API key)
10
- ├── MaliPoPay::PermissionError (HTTP 403 -- insufficient permissions)
11
- ├── MaliPoPay::NotFoundError (HTTP 404 -- resource does not exist)
12
- ├── MaliPoPay::ValidationError (HTTP 422 -- invalid request parameters)
13
- ├── MaliPoPay::RateLimitError (HTTP 429 -- too many requests)
14
- ├── MaliPoPay::ApiError (HTTP 5xx -- server-side error)
15
- └── MaliPoPay::ConnectionError (network timeout, DNS failure, etc.)
8
+ Malipopay::Error (base)
9
+ ├── Malipopay::AuthenticationError (HTTP 401 -- invalid or missing API key)
10
+ ├── Malipopay::PermissionError (HTTP 403 -- insufficient permissions)
11
+ ├── Malipopay::NotFoundError (HTTP 404 -- resource does not exist)
12
+ ├── Malipopay::ValidationError (HTTP 422 -- invalid request parameters)
13
+ ├── Malipopay::RateLimitError (HTTP 429 -- too many requests)
14
+ ├── Malipopay::ApiError (HTTP 5xx -- server-side error)
15
+ └── Malipopay::ConnectionError (network timeout, DNS failure, etc.)
16
16
  ```
17
17
 
18
18
  ## Rescuing Specific Exceptions
@@ -32,34 +32,34 @@ begin
32
32
 
33
33
  puts "Collection initiated: #{result['reference']}"
34
34
 
35
- rescue MaliPoPay::AuthenticationError
35
+ rescue Malipopay::AuthenticationError
36
36
  # API key is invalid or expired
37
37
  puts 'Authentication failed. Rotate your API key at app.malipopay.co.tz'
38
38
 
39
- rescue MaliPoPay::PermissionError
39
+ rescue Malipopay::PermissionError
40
40
  # API key lacks permission for this operation
41
41
  puts 'Insufficient permissions. Check your API key scopes.'
42
42
 
43
- rescue MaliPoPay::ValidationError => e
43
+ rescue Malipopay::ValidationError => e
44
44
  # The request had invalid fields
45
45
  puts "Invalid request: #{e.message}"
46
46
  # e.message might say: "phone must be a valid Tanzanian number (255xxxxxxxxx)"
47
47
 
48
- rescue MaliPoPay::NotFoundError
48
+ rescue Malipopay::NotFoundError
49
49
  puts 'The requested resource was not found.'
50
50
 
51
- rescue MaliPoPay::RateLimitError
51
+ rescue Malipopay::RateLimitError
52
52
  puts 'Too many requests. Back off and retry.'
53
53
 
54
- rescue MaliPoPay::ApiError => e
55
- # MaliPoPay server error -- transient, safe to retry
54
+ rescue Malipopay::ApiError => e
55
+ # Malipopay server error -- transient, safe to retry
56
56
  puts "Server error (#{e.message}). Retrying..."
57
57
 
58
- rescue MaliPoPay::ConnectionError => e
58
+ rescue Malipopay::ConnectionError => e
59
59
  # Network-level failure
60
60
  puts "Connection failed: #{e.message}"
61
61
 
62
- rescue MaliPoPay::Error => e
62
+ rescue Malipopay::Error => e
63
63
  # Catch-all for any other SDK error
64
64
  puts "Unexpected error: #{e.message}"
65
65
  end
@@ -67,7 +67,7 @@ end
67
67
 
68
68
  ## Exception Properties
69
69
 
70
- Every `MaliPoPay::Error` includes:
70
+ Every `Malipopay::Error` includes:
71
71
 
72
72
  | Property | Type | Description |
73
73
  |----------|------|-------------|
@@ -81,15 +81,15 @@ The SDK automatically retries transient errors (5xx, connection timeouts) based
81
81
  ### Built-in Retries
82
82
 
83
83
  ```ruby
84
- client = MaliPoPay::Client.new(
84
+ client = Malipopay::Client.new(
85
85
  api_key: ENV['MALIPOPAY_API_KEY'],
86
86
  retries: 3 # retry up to 3 times on transient failures (default: 2)
87
87
  )
88
88
  ```
89
89
 
90
90
  The SDK uses exponential backoff between retries. It will only retry on:
91
- - `MaliPoPay::ApiError` (5xx responses)
92
- - `MaliPoPay::ConnectionError` (network timeouts and DNS failures)
91
+ - `Malipopay::ApiError` (5xx responses)
92
+ - `Malipopay::ConnectionError` (network timeouts and DNS failures)
93
93
 
94
94
  It will **not** retry on:
95
95
  - `AuthenticationError` (fix your API key)
@@ -106,7 +106,7 @@ def with_rate_limit_retry(max_retries: 3)
106
106
 
107
107
  begin
108
108
  yield
109
- rescue MaliPoPay::RateLimitError
109
+ rescue Malipopay::RateLimitError
110
110
  attempts += 1
111
111
  raise if attempts > max_retries
112
112
 
@@ -133,7 +133,7 @@ end
133
133
  ### Generic Retry Helper
134
134
 
135
135
  ```ruby
136
- def with_retry(max_retries: 3, on: [MaliPoPay::ApiError, MaliPoPay::ConnectionError])
136
+ def with_retry(max_retries: 3, on: [Malipopay::ApiError, Malipopay::ConnectionError])
137
137
  attempts = 0
138
138
 
139
139
  begin
@@ -186,7 +186,7 @@ end
186
186
  | "amount must be greater than 0" | Zero or negative amount | Provide a positive integer amount in TZS |
187
187
  | "provider is required" | Missing `provider` field | Specify one of: `M-Pesa`, `Airtel Money`, `Mixx`, `Halopesa`, `T-Pesa`, `CRDB`, `NMB` |
188
188
  | "reference must be unique" | Duplicate reference string | Generate a unique reference per transaction |
189
- | "currency must be TZS" | Unsupported currency | MaliPoPay currently supports TZS only |
189
+ | "currency must be TZS" | Unsupported currency | Malipopay currently supports TZS only |
190
190
 
191
191
  ### NotFoundError (404)
192
192
 
@@ -234,8 +234,8 @@ begin
234
234
  reference: 'ORD-2024-300',
235
235
  description: 'Logging example'
236
236
  )
237
- rescue MaliPoPay::Error => e
238
- logger.error("MaliPoPay API error: status=#{e.status_code} message=#{e.message}")
237
+ rescue Malipopay::Error => e
238
+ logger.error("Malipopay API error: status=#{e.status_code} message=#{e.message}")
239
239
  raise
240
240
  end
241
241
  ```
@@ -250,17 +250,17 @@ module MalipopayErrorHandling
250
250
  extend ActiveSupport::Concern
251
251
 
252
252
  included do
253
- rescue_from MaliPoPay::AuthenticationError do |e|
254
- Rails.logger.error("MaliPoPay auth error: #{e.message}")
253
+ rescue_from Malipopay::AuthenticationError do |e|
254
+ Rails.logger.error("Malipopay auth error: #{e.message}")
255
255
  render json: { error: 'Payment service authentication failed' }, status: :service_unavailable
256
256
  end
257
257
 
258
- rescue_from MaliPoPay::ValidationError do |e|
258
+ rescue_from Malipopay::ValidationError do |e|
259
259
  render json: { error: e.message }, status: :unprocessable_entity
260
260
  end
261
261
 
262
- rescue_from MaliPoPay::Error do |e|
263
- Rails.logger.error("MaliPoPay error: #{e.class} - #{e.message}")
262
+ rescue_from Malipopay::Error do |e|
263
+ Rails.logger.error("Malipopay error: #{e.class} - #{e.message}")
264
264
  render json: { error: 'Payment service error' }, status: :service_unavailable
265
265
  end
266
266
  end
@@ -1,14 +1,14 @@
1
- # Getting Started with MaliPoPay Ruby SDK
1
+ # Getting Started with Malipopay Ruby SDK
2
2
 
3
3
  ## Prerequisites
4
4
 
5
5
  - **Ruby 3.0** or later
6
6
  - **Bundler** (included with Ruby)
7
- - A MaliPoPay merchant account with API credentials
7
+ - A Malipopay merchant account with API credentials
8
8
 
9
9
  ## Installation
10
10
 
11
- Add MaliPoPay to your Gemfile:
11
+ Add Malipopay to your Gemfile:
12
12
 
13
13
  ```ruby
14
14
  gem 'malipopay'
@@ -43,7 +43,7 @@ Collect TZS 50,000 from an M-Pesa customer in five lines:
43
43
  ```ruby
44
44
  require 'malipopay'
45
45
 
46
- client = MaliPoPay::Client.new(api_key: ENV['MALIPOPAY_API_KEY'])
46
+ client = Malipopay::Client.new(api_key: ENV['MALIPOPAY_API_KEY'])
47
47
 
48
48
  result = client.payments.collect(
49
49
  amount: 50_000,
@@ -61,7 +61,7 @@ When this runs, the customer at `255712345678` receives a USSD push prompt on th
61
61
 
62
62
  ## Environment Selection
63
63
 
64
- MaliPoPay provides two environments:
64
+ Malipopay provides two environments:
65
65
 
66
66
  | Environment | Base URL | Purpose |
67
67
  |-------------|----------|---------|
@@ -73,7 +73,7 @@ MaliPoPay provides two environments:
73
73
  Always develop and test against UAT before going live:
74
74
 
75
75
  ```ruby
76
- client = MaliPoPay::Client.new(
76
+ client = Malipopay::Client.new(
77
77
  api_key: ENV['MALIPOPAY_UAT_API_KEY'],
78
78
  environment: :uat
79
79
  )
@@ -84,7 +84,7 @@ client = MaliPoPay::Client.new(
84
84
  For advanced setups (proxies, custom routing), you can override the base URL:
85
85
 
86
86
  ```ruby
87
- client = MaliPoPay::Client.new(
87
+ client = Malipopay::Client.new(
88
88
  api_key: ENV['MALIPOPAY_API_KEY'],
89
89
  base_url: 'https://custom-proxy.example.com'
90
90
  )
@@ -97,7 +97,7 @@ When `base_url` is set, it takes precedence over the `environment` setting.
97
97
  The SDK automatically retries transient failures. You can adjust timeout and retry behavior:
98
98
 
99
99
  ```ruby
100
- client = MaliPoPay::Client.new(
100
+ client = Malipopay::Client.new(
101
101
  api_key: ENV['MALIPOPAY_API_KEY'],
102
102
  environment: :production,
103
103
  timeout: 60, # seconds (default: 30)
@@ -114,7 +114,7 @@ require 'malipopay'
114
114
 
115
115
  api_key = ENV.fetch('MALIPOPAY_API_KEY') { raise 'Set the MALIPOPAY_API_KEY environment variable' }
116
116
 
117
- client = MaliPoPay::Client.new(
117
+ client = Malipopay::Client.new(
118
118
  api_key: api_key,
119
119
  environment: :uat
120
120
  )
@@ -143,11 +143,11 @@ begin
143
143
 
144
144
  puts "Payment status: #{verification['status']}"
145
145
 
146
- rescue MaliPoPay::AuthenticationError
146
+ rescue Malipopay::AuthenticationError
147
147
  puts 'Invalid API key. Check your credentials.'
148
- rescue MaliPoPay::ValidationError => e
148
+ rescue Malipopay::ValidationError => e
149
149
  puts "Invalid request: #{e.message}"
150
- rescue MaliPoPay::Error => e
150
+ rescue Malipopay::Error => e
151
151
  puts "Payment error: #{e.message}"
152
152
  end
153
153
  ```
data/docs/invoices.md CHANGED
@@ -39,7 +39,7 @@ In this example, the subtotal is TZS 3,175,000 (2,500,000 + 75,000 + 600,000), a
39
39
 
40
40
  ## Tax Calculation
41
41
 
42
- MaliPoPay calculates tax automatically based on the `tax_rate` you provide:
42
+ Malipopay calculates tax automatically based on the `tax_rate` you provide:
43
43
 
44
44
  ```ruby
45
45
  # Invoice with 18% VAT (Tanzania standard rate)
@@ -184,11 +184,11 @@ begin
184
184
  { description: 'Test', quantity: 1, unit_price: 1_000 }
185
185
  ]
186
186
  )
187
- rescue MaliPoPay::ValidationError => e
187
+ rescue Malipopay::ValidationError => e
188
188
  puts "Invalid invoice data: #{e.message}"
189
- rescue MaliPoPay::NotFoundError
189
+ rescue Malipopay::NotFoundError
190
190
  puts 'Customer not found. Create the customer first.'
191
- rescue MaliPoPay::Error => e
191
+ rescue Malipopay::Error => e
192
192
  puts "Invoice error: #{e.message}"
193
193
  end
194
194
  ```
data/docs/payments.md CHANGED
@@ -4,7 +4,7 @@ The `payments` resource handles all payment operations: mobile money collections
4
4
 
5
5
  ## How Payments Work in Tanzania
6
6
 
7
- MaliPoPay integrates with Tanzania's major mobile money and banking networks:
7
+ Malipopay integrates with Tanzania's major mobile money and banking networks:
8
8
 
9
9
  - **Vodacom M-Pesa** -- largest mobile money network
10
10
  - **Airtel Money** -- second-largest MNO
@@ -18,16 +18,16 @@ MaliPoPay integrates with Tanzania's major mobile money and banking networks:
18
18
  ### Collection Flow
19
19
 
20
20
  1. Your app calls `collect` with the customer's phone number and amount
21
- 2. MaliPoPay sends a USSD push to the customer's phone
21
+ 2. Malipopay sends a USSD push to the customer's phone
22
22
  3. The customer sees a prompt like: *"Pay TZS 50,000 to ACME Ltd? Enter PIN to confirm"*
23
23
  4. The customer enters their mobile money PIN
24
- 5. MaliPoPay receives the confirmation and notifies you via webhook
24
+ 5. Malipopay receives the confirmation and notifies you via webhook
25
25
  6. You can also poll using `verify`
26
26
 
27
27
  ### Disbursement Flow
28
28
 
29
29
  1. Your app calls `disburse` with the recipient's phone/account and amount
30
- 2. MaliPoPay processes the transfer from your merchant float
30
+ 2. Malipopay processes the transfer from your merchant float
31
31
  3. The recipient receives the funds in their mobile money or bank account
32
32
  4. You receive a webhook notification with the result
33
33
 
@@ -259,19 +259,19 @@ begin
259
259
  reference: 'ORDER-001',
260
260
  description: 'Test payment'
261
261
  )
262
- rescue MaliPoPay::ValidationError => e
262
+ rescue Malipopay::ValidationError => e
263
263
  # Invalid parameters (wrong phone format, missing fields, etc.)
264
264
  puts "Validation error: #{e.message}"
265
- rescue MaliPoPay::AuthenticationError
265
+ rescue Malipopay::AuthenticationError
266
266
  # Bad API key
267
267
  puts 'Check your API key.'
268
- rescue MaliPoPay::RateLimitError
268
+ rescue Malipopay::RateLimitError
269
269
  # Too many requests -- back off and retry
270
270
  puts 'Rate limited. Please wait and retry.'
271
- rescue MaliPoPay::ConnectionError => e
271
+ rescue Malipopay::ConnectionError => e
272
272
  # Network issue
273
273
  puts "Network error: #{e.message}"
274
- rescue MaliPoPay::Error => e
274
+ rescue Malipopay::Error => e
275
275
  # Catch-all for other SDK errors
276
276
  puts "Payment error: #{e.message}"
277
277
  end
data/docs/sms.md CHANGED
@@ -29,9 +29,9 @@ begin
29
29
  )
30
30
 
31
31
  puts "Message delivered: #{sms['data']}"
32
- rescue MaliPoPay::ValidationError => e
32
+ rescue Malipopay::ValidationError => e
33
33
  puts "Invalid request: #{e.message}"
34
- rescue MaliPoPay::Error => e
34
+ rescue Malipopay::Error => e
35
35
  puts "SMS error: #{e.message}"
36
36
  end
37
37
  ```
@@ -122,12 +122,12 @@ The `sender_id` field controls what appears as the sender on the recipient's pho
122
122
 
123
123
  | Sender ID | Description |
124
124
  |-----------|-------------|
125
- | `MALIPOPAY` | Default MaliPoPay sender ID |
125
+ | `MALIPOPAY` | Default Malipopay sender ID |
126
126
  | Custom (e.g., `ACME`) | Your registered brand name |
127
127
 
128
128
  ### Registering a Custom Sender ID
129
129
 
130
- Custom sender IDs must be registered and approved in your MaliPoPay dashboard:
130
+ Custom sender IDs must be registered and approved in your Malipopay dashboard:
131
131
 
132
132
  1. Go to [app.malipopay.co.tz](https://app.malipopay.co.tz) > **Settings > SMS > Sender IDs**
133
133
  2. Click **Request New Sender ID**
data/docs/webhooks.md CHANGED
@@ -1,14 +1,14 @@
1
1
  # Webhooks
2
2
 
3
- Webhooks let you receive real-time notifications when events happen in MaliPoPay -- payment completed, payment failed, disbursement processed, etc. Instead of polling the API, you register a URL and MaliPoPay sends HTTP POST requests to it.
3
+ Webhooks let you receive real-time notifications when events happen in Malipopay -- payment completed, payment failed, disbursement processed, etc. Instead of polling the API, you register a URL and Malipopay sends HTTP POST requests to it.
4
4
 
5
5
  ## How Webhooks Work
6
6
 
7
- 1. You register a webhook URL in your MaliPoPay dashboard at [app.malipopay.co.tz](https://app.malipopay.co.tz) under **Settings > Webhooks**
8
- 2. MaliPoPay generates a **webhook signing secret** for you
9
- 3. When an event occurs, MaliPoPay sends a POST request to your URL with:
7
+ 1. You register a webhook URL in your Malipopay dashboard at [app.malipopay.co.tz](https://app.malipopay.co.tz) under **Settings > Webhooks**
8
+ 2. Malipopay generates a **webhook signing secret** for you
9
+ 3. When an event occurs, Malipopay sends a POST request to your URL with:
10
10
  - The event payload as JSON in the request body
11
- - An `X-MaliPoPay-Signature` header containing the HMAC-SHA256 signature
11
+ - An `X-Malipopay-Signature` header containing the HMAC-SHA256 signature
12
12
  4. Your endpoint verifies the signature and processes the event
13
13
 
14
14
  ## Event Types
@@ -32,7 +32,7 @@ require 'json'
32
32
  require 'malipopay'
33
33
 
34
34
  WEBHOOK_SECRET = ENV.fetch('MALIPOPAY_WEBHOOK_SECRET')
35
- verifier = MaliPoPay::Webhooks::Verifier.new(WEBHOOK_SECRET)
35
+ verifier = Malipopay::Webhooks::Verifier.new(WEBHOOK_SECRET)
36
36
 
37
37
  post '/webhooks/malipopay' do
38
38
  payload = request.body.read
@@ -63,7 +63,7 @@ post '/webhooks/malipopay' do
63
63
 
64
64
  status 200
65
65
  'OK'
66
- rescue MaliPoPay::Error => e
66
+ rescue Malipopay::Error => e
67
67
  puts "Webhook verification failed: #{e.message}"
68
68
  halt 401, 'Invalid signature'
69
69
  end
@@ -72,7 +72,7 @@ end
72
72
 
73
73
  ## Rails Controller Example
74
74
 
75
- A full Rails controller for handling MaliPoPay webhooks:
75
+ A full Rails controller for handling Malipopay webhooks:
76
76
 
77
77
  ```ruby
78
78
  # app/controllers/webhooks/malipopay_controller.rb
@@ -82,7 +82,7 @@ module Webhooks
82
82
 
83
83
  def create
84
84
  payload = request.body.read
85
- signature = request.headers['X-MaliPoPay-Signature']
85
+ signature = request.headers['X-Malipopay-Signature']
86
86
 
87
87
  unless signature.present?
88
88
  render json: { error: 'Missing signature' }, status: :bad_request
@@ -93,7 +93,7 @@ module Webhooks
93
93
  event = webhook_verifier.construct_event(payload, signature)
94
94
  handle_event(event)
95
95
  head :ok
96
- rescue MaliPoPay::Error => e
96
+ rescue Malipopay::Error => e
97
97
  Rails.logger.error("Webhook verification failed: #{e.message}")
98
98
  head :unauthorized
99
99
  end
@@ -102,7 +102,7 @@ module Webhooks
102
102
  private
103
103
 
104
104
  def webhook_verifier
105
- @webhook_verifier ||= MaliPoPay::Webhooks::Verifier.new(
105
+ @webhook_verifier ||= Malipopay::Webhooks::Verifier.new(
106
106
  ENV.fetch('MALIPOPAY_WEBHOOK_SECRET')
107
107
  )
108
108
  end
@@ -164,12 +164,12 @@ end
164
164
 
165
165
  ## Signature Verification
166
166
 
167
- Every webhook request includes an `X-MaliPoPay-Signature` header. The signature is an HMAC-SHA256 hash of the raw request body, signed with your webhook secret.
167
+ Every webhook request includes an `X-Malipopay-Signature` header. The signature is an HMAC-SHA256 hash of the raw request body, signed with your webhook secret.
168
168
 
169
- The `MaliPoPay::Webhooks::Verifier` handles this for you:
169
+ The `Malipopay::Webhooks::Verifier` handles this for you:
170
170
 
171
171
  ```ruby
172
- verifier = MaliPoPay::Webhooks::Verifier.new('your_webhook_secret')
172
+ verifier = Malipopay::Webhooks::Verifier.new('your_webhook_secret')
173
173
 
174
174
  # Just verify (returns true/false)
175
175
  valid = verifier.verify(payload, signature)
@@ -195,7 +195,7 @@ end
195
195
 
196
196
  1. **Always verify signatures.** Never process a webhook without checking the signature. This prevents spoofed requests.
197
197
 
198
- 2. **Return 200 quickly.** Process the event asynchronously if needed (e.g., with Sidekiq or ActiveJob). MaliPoPay expects a response within 30 seconds. If you don't return 200, the webhook will be retried.
198
+ 2. **Return 200 quickly.** Process the event asynchronously if needed (e.g., with Sidekiq or ActiveJob). Malipopay expects a response within 30 seconds. If you don't return 200, the webhook will be retried.
199
199
 
200
200
  3. **Handle duplicates.** Webhooks may be delivered more than once. Use the `reference` or `transaction_id` as an idempotency key.
201
201
 
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module MaliPoPay
3
+ module Malipopay
4
4
  class Client
5
5
  attr_reader :http_client, :webhook_secret
6
6
 
7
- # Initialize a new MaliPoPay client
7
+ # Initialize a new Malipopay client
8
8
  #
9
- # @param api_key [String] Your MaliPoPay API token
9
+ # @param api_key [String] Your Malipopay API token
10
10
  # @param environment [Symbol] :production or :uat (default: :production)
11
11
  # @param base_url [String, nil] Override the base URL
12
12
  # @param timeout [Integer] Request timeout in seconds (default: 30)
@@ -25,47 +25,47 @@ module MaliPoPay
25
25
  @webhook_secret = webhook_secret
26
26
  end
27
27
 
28
- # @return [MaliPoPay::Resources::Payments]
28
+ # @return [Malipopay::Resources::Payments]
29
29
  def payments
30
30
  @payments ||= Resources::Payments.new(@http_client)
31
31
  end
32
32
 
33
- # @return [MaliPoPay::Resources::Customers]
33
+ # @return [Malipopay::Resources::Customers]
34
34
  def customers
35
35
  @customers ||= Resources::Customers.new(@http_client)
36
36
  end
37
37
 
38
- # @return [MaliPoPay::Resources::Invoices]
38
+ # @return [Malipopay::Resources::Invoices]
39
39
  def invoices
40
40
  @invoices ||= Resources::Invoices.new(@http_client)
41
41
  end
42
42
 
43
- # @return [MaliPoPay::Resources::Products]
43
+ # @return [Malipopay::Resources::Products]
44
44
  def products
45
45
  @products ||= Resources::Products.new(@http_client)
46
46
  end
47
47
 
48
- # @return [MaliPoPay::Resources::Transactions]
48
+ # @return [Malipopay::Resources::Transactions]
49
49
  def transactions
50
50
  @transactions ||= Resources::Transactions.new(@http_client)
51
51
  end
52
52
 
53
- # @return [MaliPoPay::Resources::Account]
53
+ # @return [Malipopay::Resources::Account]
54
54
  def account
55
55
  @account ||= Resources::Account.new(@http_client)
56
56
  end
57
57
 
58
- # @return [MaliPoPay::Resources::Sms]
58
+ # @return [Malipopay::Resources::Sms]
59
59
  def sms
60
60
  @sms ||= Resources::Sms.new(@http_client)
61
61
  end
62
62
 
63
- # @return [MaliPoPay::Resources::References]
63
+ # @return [Malipopay::Resources::References]
64
64
  def references
65
65
  @references ||= Resources::References.new(@http_client)
66
66
  end
67
67
 
68
- # @return [MaliPoPay::Webhooks::Verifier]
68
+ # @return [Malipopay::Webhooks::Verifier]
69
69
  # @raise [ArgumentError] if webhook_secret was not provided
70
70
  def webhooks
71
71
  raise ArgumentError, "webhook_secret is required for webhook verification" unless @webhook_secret
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module MaliPoPay
4
- # Base error class for all MaliPoPay errors
3
+ module Malipopay
4
+ # Base error class for all Malipopay errors
5
5
  class Error < StandardError
6
6
  attr_reader :http_status, :response_body
7
7
 
@@ -4,7 +4,7 @@ require "faraday"
4
4
  require "faraday/retry"
5
5
  require "json"
6
6
 
7
- module MaliPoPay
7
+ module Malipopay
8
8
  class HttpClient
9
9
  BASE_URLS = {
10
10
  production: "https://core-prod.malipopay.co.tz",
@@ -59,7 +59,7 @@ module MaliPoPay
59
59
  conn.headers["apiToken"] = @api_key
60
60
  conn.headers["Content-Type"] = "application/json"
61
61
  conn.headers["Accept"] = "application/json"
62
- conn.headers["User-Agent"] = "malipopay-ruby/#{MaliPoPay::VERSION}"
62
+ conn.headers["User-Agent"] = "malipopay-ruby/#{Malipopay::VERSION}"
63
63
 
64
64
  conn.options.timeout = @timeout
65
65
  conn.options.open_timeout = 10
@@ -82,9 +82,9 @@ module MaliPoPay
82
82
 
83
83
  handle_response(response)
84
84
  rescue Faraday::ConnectionFailed => e
85
- raise MaliPoPay::ConnectionError.new("Connection failed: #{e.message}")
85
+ raise Malipopay::ConnectionError.new("Connection failed: #{e.message}")
86
86
  rescue Faraday::TimeoutError => e
87
- raise MaliPoPay::ConnectionError.new("Request timed out: #{e.message}")
87
+ raise Malipopay::ConnectionError.new("Request timed out: #{e.message}")
88
88
  end
89
89
 
90
90
  def handle_response(response)
@@ -92,46 +92,46 @@ module MaliPoPay
92
92
  when 200..299
93
93
  response.body
94
94
  when 400
95
- raise MaliPoPay::ValidationError.new(
95
+ raise Malipopay::ValidationError.new(
96
96
  error_message(response),
97
97
  errors: response.body&.dig("errors"),
98
98
  http_status: response.status,
99
99
  response_body: response.body
100
100
  )
101
101
  when 401
102
- raise MaliPoPay::AuthenticationError.new(
102
+ raise Malipopay::AuthenticationError.new(
103
103
  error_message(response),
104
104
  http_status: response.status,
105
105
  response_body: response.body
106
106
  )
107
107
  when 403
108
- raise MaliPoPay::PermissionError.new(
108
+ raise Malipopay::PermissionError.new(
109
109
  error_message(response),
110
110
  http_status: response.status,
111
111
  response_body: response.body
112
112
  )
113
113
  when 404
114
- raise MaliPoPay::NotFoundError.new(
114
+ raise Malipopay::NotFoundError.new(
115
115
  error_message(response),
116
116
  http_status: response.status,
117
117
  response_body: response.body
118
118
  )
119
119
  when 422
120
- raise MaliPoPay::ValidationError.new(
120
+ raise Malipopay::ValidationError.new(
121
121
  error_message(response),
122
122
  errors: response.body&.dig("errors"),
123
123
  http_status: response.status,
124
124
  response_body: response.body
125
125
  )
126
126
  when 429
127
- raise MaliPoPay::RateLimitError.new(
127
+ raise Malipopay::RateLimitError.new(
128
128
  error_message(response),
129
129
  retry_after: response.headers["Retry-After"]&.to_i,
130
130
  http_status: response.status,
131
131
  response_body: response.body
132
132
  )
133
133
  else
134
- raise MaliPoPay::ApiError.new(
134
+ raise Malipopay::ApiError.new(
135
135
  error_message(response),
136
136
  http_status: response.status,
137
137
  response_body: response.body
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module MaliPoPay
3
+ module Malipopay
4
4
  module Resources
5
5
  class Account
6
6
  def initialize(http_client)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module MaliPoPay
3
+ module Malipopay
4
4
  module Resources
5
5
  class Customers
6
6
  def initialize(http_client)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module MaliPoPay
3
+ module Malipopay
4
4
  module Resources
5
5
  class Invoices
6
6
  def initialize(http_client)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module MaliPoPay
3
+ module Malipopay
4
4
  module Resources
5
5
  class Payments
6
6
  def initialize(http_client)
@@ -81,7 +81,7 @@ module MaliPoPay
81
81
  # @param params [Hash] Payment link parameters
82
82
  # @return [Hash] Payment link response
83
83
  def create_link(params)
84
- @http.post("/api/v1/pay", body: params)
84
+ @http.post("/api/v1/payment/link", body: params)
85
85
  end
86
86
  end
87
87
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module MaliPoPay
3
+ module Malipopay
4
4
  module Resources
5
5
  class Products
6
6
  def initialize(http_client)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module MaliPoPay
3
+ module Malipopay
4
4
  module Resources
5
5
  class References
6
6
  def initialize(http_client)
@@ -11,35 +11,35 @@ module MaliPoPay
11
11
  # @param params [Hash] Query parameters
12
12
  # @return [Hash] List of banks
13
13
  def banks(params = {})
14
- @http.get("/api/v1/banks", params: params)
14
+ @http.get("/api/v1/standard/banks", params: params)
15
15
  end
16
16
 
17
17
  # List all supported financial institutions
18
18
  # @param params [Hash] Query parameters
19
19
  # @return [Hash] List of institutions
20
20
  def institutions(params = {})
21
- @http.get("/api/v1/banks", params: params)
21
+ @http.get("/api/v1/standard/institutions", params: params)
22
22
  end
23
23
 
24
24
  # List all supported currencies
25
25
  # @param params [Hash] Query parameters
26
26
  # @return [Hash] List of currencies
27
27
  def currencies(params = {})
28
- @http.get("/api/v1/currency", params: params)
28
+ @http.get("/api/v1/standard/currency", params: params)
29
29
  end
30
30
 
31
31
  # List all supported countries
32
32
  # @param params [Hash] Query parameters
33
33
  # @return [Hash] List of countries
34
34
  def countries(params = {})
35
- @http.get("/api/v1/countries", params: params)
35
+ @http.get("/api/v1/standard/countries", params: params)
36
36
  end
37
37
 
38
38
  # List business types
39
39
  # @param params [Hash] Query parameters
40
40
  # @return [Hash] List of business types
41
41
  def business_types(params = {})
42
- @http.get("/api/v1/countries", params: params.merge(type: "business"))
42
+ @http.get("/api/v1/standard/businessType", params: params)
43
43
  end
44
44
  end
45
45
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module MaliPoPay
3
+ module Malipopay
4
4
  module Resources
5
5
  class Sms
6
6
  def initialize(http_client)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module MaliPoPay
3
+ module Malipopay
4
4
  module Resources
5
5
  class Transactions
6
6
  def initialize(http_client)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module MaliPoPay
4
- VERSION = "1.0.0"
3
+ module Malipopay
4
+ VERSION = "1.1.0"
5
5
  end
@@ -3,7 +3,7 @@
3
3
  require "openssl"
4
4
  require "json"
5
5
 
6
- module MaliPoPay
6
+ module Malipopay
7
7
  module Webhooks
8
8
  class Verifier
9
9
  TOLERANCE_IN_SECONDS = 300 # 5 minutes
@@ -14,8 +14,8 @@ module MaliPoPay
14
14
 
15
15
  # Verify a webhook signature
16
16
  # @param payload [String] Raw request body
17
- # @param signature [String] Signature from X-MaliPoPay-Signature header
18
- # @param timestamp [String, nil] Timestamp from X-MaliPoPay-Timestamp header
17
+ # @param signature [String] Signature from X-Malipopay-Signature header
18
+ # @param timestamp [String, nil] Timestamp from X-Malipopay-Timestamp header
19
19
  # @return [Boolean] Whether the signature is valid
20
20
  def verify(payload, signature, timestamp: nil)
21
21
  return false if signature.nil? || signature.empty?
@@ -34,10 +34,10 @@ module MaliPoPay
34
34
  # @param signature [String] Signature from header
35
35
  # @param timestamp [String, nil] Timestamp from header
36
36
  # @return [Hash] Parsed event data
37
- # @raise [MaliPoPay::Error] If signature is invalid
37
+ # @raise [Malipopay::Error] If signature is invalid
38
38
  def construct_event(payload, signature, timestamp: nil)
39
39
  unless verify(payload, signature, timestamp: timestamp)
40
- raise MaliPoPay::AuthenticationError.new("Invalid webhook signature")
40
+ raise Malipopay::AuthenticationError.new("Invalid webhook signature")
41
41
  end
42
42
 
43
43
  JSON.parse(payload)
data/lib/malipopay.rb CHANGED
@@ -18,11 +18,11 @@ require_relative "malipopay/resources/references"
18
18
  # Webhooks
19
19
  require_relative "malipopay/webhooks/verifier"
20
20
 
21
- module MaliPoPay
21
+ module Malipopay
22
22
  # Convenience method to create a new client
23
23
  #
24
- # @param options [Hash] Options passed to MaliPoPay::Client.new
25
- # @return [MaliPoPay::Client]
24
+ # @param options [Hash] Options passed to Malipopay::Client.new
25
+ # @return [Malipopay::Client]
26
26
  def self.client(**options)
27
27
  Client.new(**options)
28
28
  end
data/malipopay.gemspec CHANGED
@@ -4,12 +4,12 @@ require_relative "lib/malipopay/version"
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "malipopay"
7
- spec.version = MaliPoPay::VERSION
7
+ spec.version = Malipopay::VERSION
8
8
  spec.authors = ["Lockwood Technology Ltd"]
9
9
  spec.email = ["developers@malipopay.co.tz"]
10
10
 
11
- spec.summary = "Official Ruby SDK for the MaliPoPay payment platform"
12
- spec.description = "Ruby client library for integrating with MaliPoPay payment APIs. " \
11
+ spec.summary = "Official Ruby SDK for the Malipopay payment platform"
12
+ spec.description = "Ruby client library for integrating with Malipopay payment APIs. " \
13
13
  "Supports mobile money collections, disbursements, invoicing, " \
14
14
  "SMS, customer management, and more."
15
15
  spec.homepage = "https://github.com/malipopay/malipopay-ruby"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: malipopay
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lockwood Technology Ltd
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-04-14 00:00:00.000000000 Z
11
+ date: 2026-04-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -108,7 +108,7 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '1.0'
111
- description: Ruby client library for integrating with MaliPoPay payment APIs. Supports
111
+ description: Ruby client library for integrating with Malipopay payment APIs. Supports
112
112
  mobile money collections, disbursements, invoicing, SMS, customer management, and
113
113
  more.
114
114
  email:
@@ -117,6 +117,7 @@ executables: []
117
117
  extensions: []
118
118
  extra_rdoc_files: []
119
119
  files:
120
+ - CLAUDE.md
120
121
  - Gemfile
121
122
  - LICENSE
122
123
  - README.md
@@ -170,5 +171,5 @@ requirements: []
170
171
  rubygems_version: 3.0.3.1
171
172
  signing_key:
172
173
  specification_version: 4
173
- summary: Official Ruby SDK for the MaliPoPay payment platform
174
+ summary: Official Ruby SDK for the Malipopay payment platform
174
175
  test_files: []