lipwa 0.1.2 → 0.1.3

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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -0
  3. data/README.md +219 -204
  4. data/Rakefile +11 -0
  5. data/docs/README.md +15 -0
  6. data/docs/_config.yml +11 -0
  7. data/docs/_layouts/default.html +37 -0
  8. data/docs/assets/css/style.css +8 -0
  9. data/docs/capabilities.md +116 -0
  10. data/docs/gateways.md +158 -0
  11. data/docs/getting-started.md +64 -0
  12. data/docs/index.md +46 -0
  13. data/docs/reliability.md +50 -0
  14. data/docs/webhooks.md +72 -0
  15. data/lib/lipwa/auth_strategies/api_key.rb +28 -0
  16. data/lib/lipwa/auth_strategies/base.rb +4 -0
  17. data/lib/lipwa/auth_strategies/bearer_token.rb +5 -0
  18. data/lib/lipwa/auth_strategies/jenga.rb +58 -0
  19. data/lib/lipwa/auth_strategies.rb +2 -0
  20. data/lib/lipwa/capabilities/authorize.rb +26 -0
  21. data/lib/lipwa/capabilities/bank_transfer.rb +66 -0
  22. data/lib/lipwa/capabilities/c2b.rb +11 -10
  23. data/lib/lipwa/capabilities/capture.rb +25 -0
  24. data/lib/lipwa/capabilities/disbursement.rb +16 -17
  25. data/lib/lipwa/capabilities/lightning_invoice.rb +75 -0
  26. data/lib/lipwa/capabilities/lightning_payment.rb +71 -0
  27. data/lib/lipwa/capabilities/purchase.rb +26 -0
  28. data/lib/lipwa/capabilities/refund.rb +14 -14
  29. data/lib/lipwa/capabilities/status_query.rb +21 -12
  30. data/lib/lipwa/capabilities/stk_push.rb +8 -5
  31. data/lib/lipwa/capabilities/void.rb +25 -0
  32. data/lib/lipwa/configuration_snapshot.rb +50 -0
  33. data/lib/lipwa/context.rb +60 -0
  34. data/lib/lipwa/contracts/bank_transfer_contract.rb +61 -0
  35. data/lib/lipwa/contracts/card_payment_contract.rb +59 -0
  36. data/lib/lipwa/contracts/card_transaction_contract.rb +21 -0
  37. data/lib/lipwa/contracts/lightning_invoice_check_contract.rb +18 -0
  38. data/lib/lipwa/contracts/lightning_invoice_contract.rb +27 -0
  39. data/lib/lipwa/contracts/lightning_payment_check_contract.rb +18 -0
  40. data/lib/lipwa/contracts/lightning_payment_contract.rb +14 -0
  41. data/lib/lipwa/contracts/status_query_contract.rb +29 -6
  42. data/lib/lipwa/errors.rb +4 -2
  43. data/lib/lipwa/gateway.rb +24 -5
  44. data/lib/lipwa/gateways/coop_bank/auth.rb +68 -0
  45. data/lib/lipwa/gateways/coop_bank.rb +115 -0
  46. data/lib/lipwa/gateways/flutterwave.rb +160 -0
  47. data/lib/lipwa/gateways/jenga/auth.rb +76 -0
  48. data/lib/lipwa/gateways/jenga.rb +282 -0
  49. data/lib/lipwa/gateways/lnbits.rb +67 -0
  50. data/lib/lipwa/gateways/mpesa/auth.rb +18 -2
  51. data/lib/lipwa/gateways/mpesa.rb +16 -11
  52. data/lib/lipwa/gateways/paystack.rb +119 -0
  53. data/lib/lipwa/gateways/pesapal/auth.rb +72 -0
  54. data/lib/lipwa/gateways/pesapal.rb +123 -0
  55. data/lib/lipwa/gateways.rb +7 -1
  56. data/lib/lipwa/http_adapter.rb +56 -17
  57. data/lib/lipwa/logging.rb +100 -0
  58. data/lib/lipwa/money.rb +33 -4
  59. data/lib/lipwa/types.rb +3 -3
  60. data/lib/lipwa/version.rb +1 -1
  61. data/lib/lipwa/webhooks/coop_bank.rb +28 -0
  62. data/lib/lipwa/webhooks/jenga.rb +55 -0
  63. data/lib/lipwa/webhooks/lnbits.rb +46 -0
  64. data/lib/lipwa.rb +29 -0
  65. metadata +42 -1
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "base64"
4
+ require "openssl"
5
+ require_relative "../webhook"
6
+
7
+ module Lipwa
8
+ module Webhooks
9
+ # Parses Jenga HQ receive-payment Instant Payment Notifications (IPNs).
10
+ module Jenga
11
+ module_function
12
+
13
+ # rubocop:disable Metrics/MethodLength
14
+ def call(body:, headers: {})
15
+ payload = parse(body)
16
+ transaction = payload.fetch("transaction", {})
17
+ authorization = header(headers, "Authorization")
18
+
19
+ Lipwa::WebhookEvent.new(
20
+ provider: :jenga,
21
+ event_type: :receive_payment,
22
+ success: transaction["status"].to_s.casecmp?("SUCCESS"),
23
+ provider_reference: transaction["reference"],
24
+ message: transaction["remarks"],
25
+ raw: payload,
26
+ verifier: lambda do |raw:, username:, password:, **|
27
+ verify_signature(raw: raw, authorization: authorization, username: username, password: password)
28
+ end
29
+ )
30
+ end
31
+ # rubocop:enable Metrics/MethodLength
32
+
33
+ def parse(body)
34
+ body.is_a?(String) ? JSON.parse(body) : body
35
+ end
36
+
37
+ def verify_signature(raw:, authorization:, username:, password:) # rubocop:disable Lint/UnusedMethodArgument
38
+ return false unless authorization.is_a?(String) && username.is_a?(String) && password.is_a?(String)
39
+ return false if username.strip.empty? || password.strip.empty?
40
+
41
+ expected = "Basic #{Base64.strict_encode64("#{username}:#{password}")}"
42
+ return false unless authorization.bytesize == expected.bytesize
43
+
44
+ OpenSSL.fixed_length_secure_compare(authorization, expected)
45
+ end
46
+
47
+ def header(headers, name)
48
+ pair = headers.find { |key, _| key.to_s.casecmp?(name) }
49
+ pair&.last
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ Lipwa::Webhook.register(:jenga, Lipwa::Webhooks::Jenga)
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openssl"
4
+ require_relative "../webhook"
5
+
6
+ module Lipwa
7
+ module Webhooks
8
+ # Parses LNbits invoice-payment callbacks. LNbits does not sign webhook
9
+ # bodies by default; the verifier compares a per-invoice token supplied in
10
+ # the webhook URL instead. Treat the callback only as a notification and
11
+ # independently confirm payment with #check_invoice before crediting it.
12
+ module Lnbits
13
+ module_function
14
+
15
+ def call(body:, headers: {}) # rubocop:disable Lint/UnusedMethodArgument
16
+ payload = parse(body)
17
+
18
+ Lipwa::WebhookEvent.new(
19
+ provider: :lnbits,
20
+ event_type: :payment,
21
+ success: !payload.key?("paid") || payload["paid"] == true,
22
+ provider_reference: payload.fetch("payment_hash"),
23
+ message: payload["memo"],
24
+ raw: payload,
25
+ verifier: method(:verify_signature)
26
+ )
27
+ end
28
+
29
+ def parse(body)
30
+ body.is_a?(String) ? JSON.parse(body) : body
31
+ end
32
+
33
+ # This verifies knowledge of a shared URL token, not authenticity of the
34
+ # body. The ** passthrough preserves the API for a future HMAC mode.
35
+ def verify_signature(raw: nil, expected_token: nil, provided_token: nil, **) # rubocop:disable Lint/UnusedMethodArgument
36
+ return false unless expected_token.is_a?(String) && provided_token.is_a?(String)
37
+ return false if expected_token.strip.empty?
38
+ return false unless expected_token.bytesize == provided_token.bytesize
39
+
40
+ OpenSSL.fixed_length_secure_compare(expected_token, provided_token)
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ Lipwa::Webhook.register(:lnbits, Lipwa::Webhooks::Lnbits)
data/lib/lipwa.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative "lipwa/version"
4
4
  require_relative "lipwa/errors"
5
+ require_relative "lipwa/logging"
5
6
  require_relative "lipwa/types"
6
7
  require_relative "lipwa/money"
7
8
  require_relative "lipwa/response"
@@ -11,8 +12,12 @@ require_relative "lipwa/configuration"
11
12
  require_relative "lipwa/capability"
12
13
  require_relative "lipwa/gateway"
13
14
  require_relative "lipwa/gateways"
15
+ require_relative "lipwa/context"
14
16
  require_relative "lipwa/webhook"
15
17
  require_relative "lipwa/webhooks/mpesa"
18
+ require_relative "lipwa/webhooks/jenga"
19
+ require_relative "lipwa/webhooks/coop_bank"
20
+ require_relative "lipwa/webhooks/lnbits"
16
21
  require_relative "lipwa/contracts/c2b_register_urls_contract"
17
22
  require_relative "lipwa/contracts/c2b_simulate_contract"
18
23
  require_relative "lipwa/capabilities/c2b"
@@ -22,10 +27,34 @@ require_relative "lipwa/contracts/disbursement_contract"
22
27
  require_relative "lipwa/capabilities/disbursement"
23
28
  require_relative "lipwa/contracts/status_query_contract"
24
29
  require_relative "lipwa/capabilities/status_query"
30
+ require_relative "lipwa/contracts/lightning_invoice_contract"
31
+ require_relative "lipwa/contracts/lightning_invoice_check_contract"
32
+ require_relative "lipwa/contracts/lightning_payment_contract"
33
+ require_relative "lipwa/contracts/lightning_payment_check_contract"
34
+ require_relative "lipwa/capabilities/lightning_invoice"
35
+ require_relative "lipwa/capabilities/lightning_payment"
36
+ require_relative "lipwa/gateways/lnbits"
37
+ require_relative "lipwa/contracts/bank_transfer_contract"
38
+ require_relative "lipwa/capabilities/bank_transfer"
39
+ require_relative "lipwa/contracts/card_payment_contract"
40
+ require_relative "lipwa/contracts/card_transaction_contract"
41
+ require_relative "lipwa/capabilities/purchase"
42
+ require_relative "lipwa/capabilities/authorize"
43
+ require_relative "lipwa/capabilities/capture"
44
+ require_relative "lipwa/capabilities/void"
25
45
  require_relative "lipwa/gateways/mpesa"
46
+ require_relative "lipwa/gateways/coop_bank"
26
47
 
48
+ require_relative "lipwa/gateways/jenga"
49
+ require_relative "lipwa/gateways/pesapal"
50
+ require_relative "lipwa/gateways/flutterwave"
51
+ require_relative "lipwa/gateways/paystack"
27
52
  # Unified payment gateway abstraction for African payment providers.
28
53
  module Lipwa
54
+ def self.context(&block)
55
+ Context.new(&block)
56
+ end
57
+
29
58
  def self.gateway(name)
30
59
  Gateways[name]
31
60
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lipwa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Oguda
@@ -151,36 +151,77 @@ files:
151
151
  - LICENSE.txt
152
152
  - README.md
153
153
  - Rakefile
154
+ - docs/README.md
155
+ - docs/_config.yml
156
+ - docs/_layouts/default.html
157
+ - docs/assets/css/style.css
158
+ - docs/capabilities.md
159
+ - docs/gateways.md
160
+ - docs/getting-started.md
161
+ - docs/index.md
162
+ - docs/reliability.md
163
+ - docs/webhooks.md
154
164
  - lib/lipwa.rb
155
165
  - lib/lipwa/auth_strategies.rb
166
+ - lib/lipwa/auth_strategies/api_key.rb
156
167
  - lib/lipwa/auth_strategies/base.rb
157
168
  - lib/lipwa/auth_strategies/bearer_token.rb
169
+ - lib/lipwa/auth_strategies/jenga.rb
158
170
  - lib/lipwa/auth_strategies/none.rb
171
+ - lib/lipwa/capabilities/authorize.rb
172
+ - lib/lipwa/capabilities/bank_transfer.rb
159
173
  - lib/lipwa/capabilities/c2b.rb
174
+ - lib/lipwa/capabilities/capture.rb
160
175
  - lib/lipwa/capabilities/disbursement.rb
176
+ - lib/lipwa/capabilities/lightning_invoice.rb
177
+ - lib/lipwa/capabilities/lightning_payment.rb
178
+ - lib/lipwa/capabilities/purchase.rb
161
179
  - lib/lipwa/capabilities/refund.rb
162
180
  - lib/lipwa/capabilities/status_query.rb
163
181
  - lib/lipwa/capabilities/stk_push.rb
182
+ - lib/lipwa/capabilities/void.rb
164
183
  - lib/lipwa/capability.rb
165
184
  - lib/lipwa/configuration.rb
185
+ - lib/lipwa/configuration_snapshot.rb
186
+ - lib/lipwa/context.rb
187
+ - lib/lipwa/contracts/bank_transfer_contract.rb
166
188
  - lib/lipwa/contracts/c2b_register_urls_contract.rb
167
189
  - lib/lipwa/contracts/c2b_simulate_contract.rb
190
+ - lib/lipwa/contracts/card_payment_contract.rb
191
+ - lib/lipwa/contracts/card_transaction_contract.rb
168
192
  - lib/lipwa/contracts/disbursement_contract.rb
193
+ - lib/lipwa/contracts/lightning_invoice_check_contract.rb
194
+ - lib/lipwa/contracts/lightning_invoice_contract.rb
195
+ - lib/lipwa/contracts/lightning_payment_check_contract.rb
196
+ - lib/lipwa/contracts/lightning_payment_contract.rb
169
197
  - lib/lipwa/contracts/refund_contract.rb
170
198
  - lib/lipwa/contracts/status_query_contract.rb
171
199
  - lib/lipwa/contracts/stk_push_contract.rb
172
200
  - lib/lipwa/errors.rb
173
201
  - lib/lipwa/gateway.rb
174
202
  - lib/lipwa/gateways.rb
203
+ - lib/lipwa/gateways/coop_bank.rb
204
+ - lib/lipwa/gateways/coop_bank/auth.rb
205
+ - lib/lipwa/gateways/flutterwave.rb
206
+ - lib/lipwa/gateways/jenga.rb
207
+ - lib/lipwa/gateways/jenga/auth.rb
208
+ - lib/lipwa/gateways/lnbits.rb
175
209
  - lib/lipwa/gateways/mpesa.rb
176
210
  - lib/lipwa/gateways/mpesa/auth.rb
177
211
  - lib/lipwa/gateways/mpesa/security_credential.rb
212
+ - lib/lipwa/gateways/paystack.rb
213
+ - lib/lipwa/gateways/pesapal.rb
214
+ - lib/lipwa/gateways/pesapal/auth.rb
178
215
  - lib/lipwa/http_adapter.rb
216
+ - lib/lipwa/logging.rb
179
217
  - lib/lipwa/money.rb
180
218
  - lib/lipwa/response.rb
181
219
  - lib/lipwa/types.rb
182
220
  - lib/lipwa/version.rb
183
221
  - lib/lipwa/webhook.rb
222
+ - lib/lipwa/webhooks/coop_bank.rb
223
+ - lib/lipwa/webhooks/jenga.rb
224
+ - lib/lipwa/webhooks/lnbits.rb
184
225
  - lib/lipwa/webhooks/mpesa.rb
185
226
  - sig/lipwa.rbs
186
227
  homepage: https://github.com/kamalogudah/lipwa