bloom_remit_client 0.12.0 → 0.16.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/push.yml +27 -0
  3. data/.ruby-version +1 -1
  4. data/CHANGELOG.md +27 -0
  5. data/Gemfile +2 -1
  6. data/README.md +61 -0
  7. data/bloom_remit_client.gemspec +5 -5
  8. data/lib/bloom_remit_client.rb +40 -48
  9. data/lib/bloom_remit_client/client.rb +6 -126
  10. data/lib/bloom_remit_client/factories.rb +23 -0
  11. data/lib/bloom_remit_client/models/txn.rb +39 -0
  12. data/lib/bloom_remit_client/models/txn_preview.rb +15 -0
  13. data/lib/bloom_remit_client/requests/base_request.rb +18 -0
  14. data/lib/bloom_remit_client/requests/create_txn_preview_request.rb +24 -0
  15. data/lib/bloom_remit_client/requests/create_txn_request.rb +79 -0
  16. data/lib/bloom_remit_client/responses/base_response.rb +18 -0
  17. data/lib/bloom_remit_client/responses/create_txn_preview_response.rb +16 -0
  18. data/lib/bloom_remit_client/responses/create_txn_response.rb +11 -0
  19. data/lib/bloom_remit_client/version.rb +1 -1
  20. metadata +23 -48
  21. data/.travis.yml +0 -9
  22. data/lib/bloom_remit_client/coercers/path.rb +0 -11
  23. data/lib/bloom_remit_client/concerns/has_base_authentification.rb +0 -16
  24. data/lib/bloom_remit_client/models/biller.rb +0 -16
  25. data/lib/bloom_remit_client/models/credit.rb +0 -12
  26. data/lib/bloom_remit_client/models/deposit_strategy.rb +0 -11
  27. data/lib/bloom_remit_client/models/payment.rb +0 -23
  28. data/lib/bloom_remit_client/models/recipient.rb +0 -17
  29. data/lib/bloom_remit_client/models/remittance.rb +0 -22
  30. data/lib/bloom_remit_client/models/user.rb +0 -21
  31. data/lib/bloom_remit_client/requests/base.rb +0 -55
  32. data/lib/bloom_remit_client/requests/billers/list.rb +0 -23
  33. data/lib/bloom_remit_client/requests/credit/history.rb +0 -20
  34. data/lib/bloom_remit_client/requests/credit/list.rb +0 -20
  35. data/lib/bloom_remit_client/requests/deposit_strategies/list.rb +0 -21
  36. data/lib/bloom_remit_client/requests/payments/create.rb +0 -31
  37. data/lib/bloom_remit_client/requests/rate/show.rb +0 -29
  38. data/lib/bloom_remit_client/requests/recipients/create.rb +0 -32
  39. data/lib/bloom_remit_client/requests/remittances/calculate.rb +0 -33
  40. data/lib/bloom_remit_client/requests/remittances/create.rb +0 -30
  41. data/lib/bloom_remit_client/requests/requests_sender.rb +0 -35
  42. data/lib/bloom_remit_client/requests/senders/create.rb +0 -30
  43. data/lib/bloom_remit_client/requests/txns/create.rb +0 -30
  44. data/lib/bloom_remit_client/requests/url_builder.rb +0 -51
  45. data/lib/bloom_remit_client/responses/base.rb +0 -31
  46. data/lib/bloom_remit_client/responses/billers/list.rb +0 -17
  47. data/lib/bloom_remit_client/responses/deposit_strategies/list.rb +0 -20
  48. data/lib/bloom_remit_client/responses/payments/create.rb +0 -17
  49. data/lib/bloom_remit_client/responses/recipients/create.rb +0 -20
  50. data/lib/bloom_remit_client/responses/remittances/calculate.rb +0 -69
  51. data/lib/bloom_remit_client/responses/remittances/create.rb +0 -20
  52. data/lib/bloom_remit_client/responses/senders/create.rb +0 -21
  53. data/lib/bloom_remit_client/responses/txns/create.rb +0 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: cdba69cae9f6859697db89f1db640dab97be5e26
4
- data.tar.gz: 6cb6990e89202acdec82e8cceea2f33fa578cbdf
2
+ SHA256:
3
+ metadata.gz: 3d05d4bbb0ec183ac5431dfd8e23b41cfa495bdab6cd63d5ccd262027f9c28e4
4
+ data.tar.gz: ea90abde2f013faa52e46c1899fbd2c737f4793826ce6a328448293385eeafef
5
5
  SHA512:
6
- metadata.gz: 7c41ee07a343defcab42bc347b6e9db8fef3dcd98726e0f9eb1f5c107904637e6fa72e1fb3b8fa7ae821cc562836f62977c7b7362a5847bcbcdee4646b8106be
7
- data.tar.gz: 7f63e7f357eaa84f5314adac1b62ba315949515604ba4cf3cf15d7b89838fd084358d36f98f29c88a40c7eb1bcf558f1c9e11172fe992b7dda171311336019e1
6
+ metadata.gz: c80276da94593218d43021c48527140979f70b52b8988ec26a91defde9448fc762bfe714bde5433e569b72e0771dba649eaf61aa010af0a5935b2758141c9c44
7
+ data.tar.gz: 37b74d5855caca1c94c5a4072aefcc0977ca19463c7f4603093a4d9b9585638c5aea7caa26dcef9b83cf8aa3848ea3bed11fe01e42ee416e9532ef571effa553
@@ -0,0 +1,27 @@
1
+ name: Ruby Gem
2
+
3
+ on:
4
+ pull_request:
5
+ branches:
6
+ - master
7
+ push:
8
+ branches:
9
+ - master
10
+
11
+ jobs:
12
+ test:
13
+
14
+ runs-on: ubuntu-latest
15
+
16
+ steps:
17
+ - uses: actions/checkout@v2
18
+ - name: Set up Ruby
19
+ uses: ruby/setup-ruby@v1
20
+ with:
21
+ ruby-version: 2.7.2
22
+ - name: Bundle install
23
+ run: bundle install
24
+ - name: Copy spec config
25
+ run: cp spec/config.yml{.sample,}
26
+ - name: Run tests
27
+ run: bundle exec rspec
@@ -1 +1 @@
1
- ruby-2.3.1
1
+ ruby-2.7.2
@@ -2,6 +2,33 @@
2
2
  All notable changes to this project will be documented in this file.
3
3
  This project adheres to [Semantic Versioning](http://semver.org/).
4
4
 
5
+ ## [0.16.1] - 2020-01-19
6
+ ### Changed
7
+ - Allow nil for both `partner_id` and `api_secret
8
+
9
+ ## [0.16.0] - 2020-01-18
10
+ ### Changed
11
+ - Removed all API methods (complete overhaul)
12
+
13
+ ### Added
14
+ - `#create_txn` to create transactions
15
+ - `#create_txn_preview` to determine fees, eta, and max amount of a transaction
16
+
17
+ ## [0.15.0] - 2017-04-26
18
+ ### Changed
19
+ - Production domain is now `www.bloomremit.net`
20
+ - Marked `pending` the failing specs:
21
+ - create payment
22
+ - fetch credits
23
+
24
+ ## [0.14.0] - 2016-10-05
25
+ ### Added
26
+ - Factories: `bloom_remit_client_responses_recipients_create`, `bloom_remit_client_responses_recipients_list`
27
+
28
+ ## [0.13.0] - 2016-10-05
29
+ ### Added
30
+ - Add `#recipient_list` to list the recipients of a sender
31
+
5
32
  ## [0.12.0] - 2016-10-04
6
33
  ### Added
7
34
  - Add `#create_txn` that uses a single endpoint to create remittances and payments
data/Gemfile CHANGED
@@ -5,4 +5,5 @@ gemspec
5
5
 
6
6
  gem "pry"
7
7
  gem "pry-byebug"
8
- gem "virtus-matchers", github: "g5/virtus-matchers"
8
+
9
+ gem "message_bus_client_worker", github: "bloom-solutions/message_bus_client_worker", branch: "feat-subscribe"
data/README.md CHANGED
@@ -22,6 +22,67 @@ Or install it yourself as:
22
22
 
23
23
  See `spec/functional` for examples.
24
24
 
25
+ To subscribe to transaction updates, configure the following (in an initializer if you're using Rails):
26
+
27
+ ```ruby
28
+ MessageBusClientWorker.configure do |c|
29
+ c.subscriptions = {
30
+ "https://bloomremit.net" => {
31
+ headers: {
32
+ # TOKEN here is a Base64.strict_encode64 string composed of
33
+ # your PARTNER_ID and API_SECRET joined by a colon character
34
+ "Authorization" => "Basic #{TOKEN}"
35
+ },
36
+ channels: {
37
+ "/v2/txns" => { processor: "ProcessBloomRemitTxnUpdate" },
38
+ }
39
+ },
40
+ }
41
+
42
+ # Consider changing MessageBusClientWorker to incrementally add subscriptions
43
+ # and not overwrite like above. Warn if a host is already defined.
44
+ # If we do this, then we can add a helper method to this gem, that adds the sub:
45
+ # BloomRemitClient.configure do |c|
46
+ # c.partner_id = ENV["BLOOM_REMIT_PARTNER_ID"]
47
+ # c.api_secret = ENV["BLOOM_REMIT_API_SECRET"]
48
+ # c.on_txn_update = "ProcessBloomRemitTxnUpdate" # setting this will trigger the MBCW subscription
49
+ # end
50
+ c.subscribe(
51
+ "https://bloomremit.net" => {
52
+ headers: { "Authorization" => "Basic #{TOKEN}" },
53
+ channels: {
54
+ "/v2/txns" => { processor: "ProcessBloomRemitTxnUpdate" },
55
+ }
56
+ },
57
+ )
58
+ end
59
+ ```
60
+
61
+ ```ruby
62
+ BloomRemitClient.configure do |c|
63
+ c.partner_id = ENV["BLOOM_REMIT_PARTNER_ID"]
64
+ c.api_secret = ENV["BLOOM_REMIT_API_SECRET"]
65
+ c.on_txn_update = "ProcessBloomRemitTxnUpdate"
66
+ end
67
+
68
+ BloomRemitClient.configure_message_bus_client_worker!
69
+ ```
70
+
71
+ Make sure `MessageBusClientWorker` (the gem used underneath this gem) is enqueued at an interval, so your app will continually fetch updates. See [Staying subscribed](https://github.com/bloom-solutions/message_bus_client_worker#staying-subscribed) in MessageBusClientWorker. Note that you will need to have Sidekiq for `MessageBusClientWorker` to function.
72
+
73
+ Somewhere in your app, define `ProcessBloomRemitTxnUpdates` to update your own database:
74
+
75
+ ```ruby
76
+ class ProcessBloomRemitTxnUpdates
77
+ def self.call(remote_txn)
78
+ # remote_txn passed to you is an instance of BloomRemitClient::Txn model
79
+ if withdrawal = Withdrawal.find_by(id: remote_txn.client_external_id)
80
+ withdrawal.update(status: remote_txn.status)
81
+ end
82
+ end
83
+ end
84
+ ```
85
+
25
86
  ## Factories
26
87
 
27
88
  To make testing easier, you may `require 'bloom_remit_client/factories'` in your app.
@@ -26,17 +26,17 @@ Gem::Specification.new do |spec|
26
26
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
27
  spec.require_paths = ["lib"]
28
28
 
29
- spec.add_dependency "activemodel"
30
29
  spec.add_dependency "activesupport"
31
- spec.add_dependency "httparty"
32
- spec.add_dependency "addressable"
30
+ spec.add_dependency "api_client_base"
31
+ spec.add_dependency "typhoeus"
32
+ spec.add_dependency "message_bus_client_worker"
33
33
 
34
- spec.add_development_dependency "bundler", "~> 1.12"
34
+ spec.add_development_dependency "bundler", "~> 2.0"
35
35
  spec.add_development_dependency "rake", "~> 10.0"
36
36
  spec.add_development_dependency "rspec", "~> 3.0"
37
37
  spec.add_development_dependency "vcr"
38
38
  spec.add_development_dependency 'faker'
39
39
  spec.add_development_dependency "webmock"
40
40
  spec.add_development_dependency "dotenv"
41
- spec.add_development_dependency "shoulda-matchers"
41
+ spec.add_development_dependency "virtus-matchers"
42
42
  end
@@ -1,64 +1,56 @@
1
1
  # frozen_string_literal: true
2
- require 'virtus'
3
- require 'httparty'
4
- require 'active_model'
2
+ require "api_client_base"
5
3
  require 'active_support/core_ext/hash/indifferent_access'
6
4
  require 'active_support/core_ext/object/try'
5
+ require "message_bus_client_worker"
7
6
  require 'bloom_remit_client/coercers/indifferent_hash'
8
- require 'bloom_remit_client/coercers/path'
9
- require 'bloom_remit_client/concerns/has_base_authentification'
10
7
  require "bloom_remit_client/version"
11
8
  require "bloom_remit_client/client"
12
- require "bloom_remit_client/models/biller"
13
- require "bloom_remit_client/models/deposit_strategy"
14
- require "bloom_remit_client/models/user"
15
- require "bloom_remit_client/models/payment"
16
- require "bloom_remit_client/models/remittance"
17
- require "bloom_remit_client/models/credit"
18
- require "bloom_remit_client/models/recipient"
9
+ require "bloom_remit_client/models/txn"
10
+ require "bloom_remit_client/models/txn_preview"
19
11
  require "bloom_remit_client/requests"
20
- require "bloom_remit_client/requests/url_builder"
21
- require "bloom_remit_client/requests/requests_sender"
22
- require "bloom_remit_client/requests/base"
23
- require "bloom_remit_client/requests/credit/list"
24
- require "bloom_remit_client/requests/credit/history"
25
- require "bloom_remit_client/requests/rate/show"
26
- require "bloom_remit_client/requests/billers/list"
27
- require "bloom_remit_client/requests/deposit_strategies/list"
28
- require "bloom_remit_client/requests/senders/create"
29
- require "bloom_remit_client/requests/payments/create"
30
- require "bloom_remit_client/requests/remittances/create"
31
- require "bloom_remit_client/requests/recipients/create"
32
- require "bloom_remit_client/requests/remittances/calculate"
33
- require "bloom_remit_client/requests/txns/create"
34
- require "bloom_remit_client/responses/base"
35
- require "bloom_remit_client/responses/billers/list"
36
- require "bloom_remit_client/responses/deposit_strategies/list"
37
- require "bloom_remit_client/responses/senders/create"
38
- require "bloom_remit_client/responses/payments/create"
39
- require "bloom_remit_client/responses/remittances/create"
40
- require "bloom_remit_client/responses/recipients/create"
41
- require "bloom_remit_client/responses/remittances/calculate"
42
- require "bloom_remit_client/responses/txns/create"
12
+ require "bloom_remit_client/requests/base_request"
13
+ require "bloom_remit_client/requests/create_txn_request"
14
+ require "bloom_remit_client/requests/create_txn_preview_request"
15
+ require "bloom_remit_client/responses/base_response"
16
+ require "bloom_remit_client/responses/create_txn_response"
17
+ require "bloom_remit_client/responses/create_txn_preview_response"
43
18
 
44
19
  module BloomRemitClient
45
- PRODUCTION = 'api.bloom.solutions'
46
- STAGING = 'bloomremit-staging.herokuapp.com'
47
20
 
48
- class << self
49
- attr_accessor :host
50
- attr_accessor :sandbox
21
+ PRODUCTION = 'https://www.bloomremit.net'
22
+ STAGING = 'https://staging.bloomremit.net'
51
23
 
52
- def new(args={})
53
- client_args = {}
54
- client_args[:host] = self.host if self.host.present?
55
- client_args[:sandbox] = self.sandbox if self.sandbox.present?
56
- client_args.merge!(args)
24
+ include APIClientBase::Base.module
57
25
 
58
- client = Client.new(client_args)
59
- raise ArgumentError, client.errors.full_messages if client.invalid?
60
- client
26
+ TXN_UPDATES_CHANNEL = "/v2/txns".freeze
27
+
28
+ with_configuration do
29
+ has :host, classes: String, default: STAGING
30
+ has :partner_id, classes: [String, NilClass]
31
+ has :api_secret, classes: [String, NilClass]
32
+ has :on_txn_update, classes: [String, NilClass]
33
+ end
34
+
35
+ def self.configure_message_bus_client_worker!
36
+ if configuration.on_txn_update.blank?
37
+ fail "`on_txn_update` must be defined"
61
38
  end
62
39
 
40
+ token = [
41
+ configuration.partner_id,
42
+ configuration.api_secret,
43
+ ].join(":")
44
+ token = Base64.strict_encode64(token)
45
+
46
+ MessageBusClientWorker.subscribe(configuration.host, {
47
+ headers: {
48
+ "HTTP_AUTHORIZATION" => "Basic #{token}"
49
+ },
50
+ channels: {
51
+ TXN_UPDATES_CHANNEL => { processor: configuration.on_txn_update },
52
+ }
53
+ })
63
54
  end
55
+
64
56
  end
@@ -1,137 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
  module BloomRemitClient
3
3
  class Client
4
- include Virtus.model
5
- include ActiveModel::Validations
4
+ include APIClientBase::Client.module(default_opts: :default_opts)
6
5
 
7
- attribute :api_token, String
6
+ attribute :partner_id, String
8
7
  attribute :api_secret, String
9
- attribute :agent_id, String
10
8
  attribute :host, String, lazy: true, default: :default_host
11
- attribute :sandbox, Boolean, default: true
12
9
 
13
- validates :host, presence: true
14
- validates :sandbox, inclusion: { in: [true, false] }
10
+ api_action :create_txn
11
+ api_action :create_txn_preview
15
12
 
16
- # GET
17
- # /api/v1/partners/:api_token/credits
18
- # Parameters: none
19
- def credits(params = {})
20
- request_params = params.merge(access_params)
21
- request = Requests::Credit::List.new(request_params)
22
- request.call!
23
- end
24
-
25
- # GET
26
- # /api/v1/partners/:api_token/credits/history
27
- # Parameters: none
28
- def credits_history(params = {})
29
- request_params = params.merge(access_params)
30
- request = Requests::Credit::History.new(request_params)
31
- request.call!
32
- end
33
-
34
- # GET
35
- # /api/v1/rates
36
- # Parameters:
37
- # partner_id:
38
- # String, required
39
- # API token
40
- # api_secret:
41
- # String, required
42
- # currency:
43
- # One of: [USDPHP, USDUSD, USDKRW, USDAUD, USDCAD, USDJPY, USDNZD, USDSGD, USDHKD,
44
- # USDCNY, USDEUR, USDVND, USDSAR, USDTWD, USDQAR, USDKWD, USDAED, USDGBP,
45
- # USDMYR, USDINR, USDIDR, USDBTC],
46
- # optional
47
- def rates(params = {})
48
- request_params = params.merge(access_params)
49
- request = Requests::Rate::Show.new(request_params)
50
- request.call!
51
- end
52
-
53
- def billers(params={})
54
- request_params = params.merge(access_params)
55
- request = Requests::Billers::List.new(request_params)
56
- raw_response = request.call!
57
- Responses::Billers::List.new(raw_response: raw_response)
58
- end
59
-
60
- def create_sender(sender_params={})
61
- params = {sender: sender_params}
62
- request_params = params.merge(default_params).merge(access_params)
63
- request = Requests::Senders::Create.new(request_params)
64
- raw_response = request.call!
65
- Responses::Senders::Create.new(raw_response: raw_response)
66
- end
67
-
68
- def create_payment(payment_params={})
69
- params = {payment: payment_params}.
70
- merge(sender_id: payment_params[:sender_id])
71
- request_params = params.merge(default_params).merge(access_params)
72
- request = Requests::Payments::Create.new(request_params)
73
- raw_response = request.call!
74
- Responses::Payments::Create.new(raw_response: raw_response)
75
- end
76
-
77
- def create_recipient(recipient_params={})
78
- params = {recipient: recipient_params}.
79
- merge(sender_id: recipient_params[:sender_id])
80
- request_params = params.merge(default_params).merge(access_params)
81
- request = Requests::Recipients::Create.new(request_params)
82
- raw_response = request.call!
83
- Responses::Recipients::Create.new(raw_response: raw_response)
84
- end
85
-
86
- def create_remittance(remittance_params={})
87
- params = {remittance: remittance_params}.
88
- merge(sender_id: remittance_params[:sender_id]).
89
- merge(recipient_id: remittance_params[:recipient_id])
90
- request_params = params.merge(default_params).merge(access_params)
91
- request = Requests::Remittances::Create.new(request_params)
92
- raw_response = request.call!
93
- Responses::Remittances::Create.new(raw_response: raw_response)
94
- end
95
-
96
- def calculate_remittance(calculate_params={})
97
- params = access_params.merge(calculate_params)
98
- request = Requests::Remittances::Calculate.new(params)
99
- raw_response = request.call!
100
- Responses::Remittances::Calculate.new(raw_response: raw_response)
101
- end
102
-
103
- def deposit_strategies_list
104
- request_params = access_params
105
- request = Requests::DepositStrategies::List.new(request_params)
106
- raw_response = request.call!
107
- Responses::DepositStrategies::List.new(raw_response: raw_response)
108
- end
109
-
110
- def create_txn(txn_params={})
111
- params = {txn: txn_params}.merge(
112
- sender_id: txn_params[:sender_id],
113
- recipient_id: txn_params[:recipient_id],
114
- )
115
- request_params = params.merge(default_params).merge(access_params)
116
- request = Requests::Txns::Create.new(request_params)
117
- raw_response = request.call!
118
- Responses::Txns::Create.new(raw_response: raw_response)
119
- end
120
-
121
- private
122
-
123
- # Should overwrite any other `:api_token`, `:api_secret`
124
- def access_params
125
- @access_params ||= attributes.slice(:host, :api_token, :api_secret)
126
- end
127
-
128
- def default_params
129
- @default_params ||= attributes.slice(:agent_id)
130
- end
131
-
132
- def default_host
133
- return BloomRemitClient::STAGING if self.sandbox.nil? || self.sandbox
134
- BloomRemitClient::PRODUCTION
13
+ def default_opts
14
+ { host: host, partner_id: partner_id, api_secret: api_secret }
135
15
  end
136
16
 
137
17
  end
@@ -25,4 +25,27 @@ FactoryGirl.define do
25
25
  body { {"json" => "value"} }
26
26
  end
27
27
 
28
+ factory(:bloom_remit_client_responses_recipients_create, {
29
+ class: "BloomRemitClient::Responses::Recipients::Create",
30
+ }) do
31
+ success true
32
+ body { {"json" => "value"} }
33
+ end
34
+
35
+ factory(:bloom_remit_client_responses_recipients_list, {
36
+ class: "BloomRemitClient::Responses::Recipients::List",
37
+ }) do
38
+ success true
39
+ recipients do
40
+ [
41
+ build(:bloom_remit_client_recipient),
42
+ build(:bloom_remit_client_recipient),
43
+ ]
44
+ end
45
+ end
46
+
47
+ factory :bloom_remit_client_recipient, class: "BloomRemitClient::Recipient" do
48
+ id { SecureRandom.uuid }
49
+ end
50
+
28
51
  end