diff --git a/.coveralls.yml b/.coveralls.yml new file mode 100644 index 0000000..3571887 --- /dev/null +++ b/.coveralls.yml @@ -0,0 +1 @@ +repo_token: bYVvifY6POXhFwOja3SZIX1nUxtWrUxKj diff --git a/.rubocop.yml b/.rubocop.yml index dc4c4b0..2b681be 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -5,10 +5,14 @@ Naming/FileName: Metrics/MethodLength: Max: 25 Metrics/BlockLength: - Max: 30 + Max: 35 Metrics/ParameterLists: Max: 8 Lint/DuplicateMethods: Enabled: false Naming/AccessorMethodName: + Enabled: false +Naming/PredicateName: + Enabled: false +Style/AsciiComments: Enabled: false \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index 8cebab8..98defcd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -9,12 +9,20 @@ GEM addressable (2.7.0) public_suffix (>= 2.0.2, < 5.0) coderay (1.1.2) + coveralls (0.8.23) + json (>= 1.8, < 3) + simplecov (~> 0.16.1) + term-ansicolor (~> 1.3) + thor (>= 0.19.4, < 2.0) + tins (~> 1.6) crack (0.4.3) safe_yaml (~> 1.0.0) diff-lcs (1.3) + docile (1.3.2) faraday (1.0.0) multipart-post (>= 1.2, < 3) hashdiff (1.0.0) + json (2.3.0) method_source (0.9.2) multipart-post (2.1.1) pry (0.12.2) @@ -36,6 +44,17 @@ GEM rspec-support (~> 3.9.0) rspec-support (3.9.2) safe_yaml (1.0.5) + simplecov (0.16.1) + docile (~> 1.1) + json (>= 1.8, < 3) + simplecov-html (~> 0.10.0) + simplecov-html (0.10.2) + sync (0.5.0) + term-ansicolor (1.7.1) + tins (~> 1.0) + thor (1.0.1) + tins (1.24.1) + sync vcr (5.1.0) webmock (2.3.2) addressable (>= 2.3.6) @@ -47,6 +66,7 @@ PLATFORMS DEPENDENCIES bundler (~> 2.0) + coveralls (~> 0.8.15) faraday momoapi-ruby! pry (~> 0.12) diff --git a/README.md b/README.md index 97647c6..1e1db94 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # MTN MoMo API Ruby Gem [![Build Status](https://travis-ci.com/sparkplug/momoapi-ruby.svg?branch=master)](https://travis-ci.com/sparkplug/momoapi-ruby) - +[![Coverage Status](https://coveralls.io/repos/github/sparkplug/momoapi-ruby/badge.svg?branch=master)](https://coveralls.io/github/sparkplug/momoapi-ruby?branch=master) +[![Join the community on Spectrum](https://withspectrum.github.io/badge/badge.svg)](https://spectrum.chat/momo-api-developers/) ## Usage @@ -43,14 +44,18 @@ Add the following configurations in an initializer file (for example, `config/in Momoapi.configure do |config| config.base_url = 'Your MoMo account base URL' config.callback_host = 'Your Provider Callback Host' - config.collection_primary_key = 'Your Collection Subscription Key' - config.collection_user_id = 'Your Collection User ID' - config.collection_api_secret = 'Your Collection API Key' end ``` ## Collections -The collections client can be created with the following paramaters. Note that the `COLLECTION_USER_ID` and `COLLECTION_API_SECRET` for production are provided on the MTN OVA dashboard; +The collections client can be created with the following paramaters. Note that the `COLLECTION_USER_ID` and `COLLECTION_API_SECRET` for production are provided on the MTN OVA dashboard. + +Add the following to your configuration block: +``` + config.collection_primary_key = 'Your Collection Subscription Key' + config.collection_user_id = 'Your Collection User ID' + config.collection_api_secret = 'Your Collection API Key' +``` * `collection_primary_key`: Primary Key for the `Collection` product on the developer portal. * `collection_user_id`: For sandbox, use the one generated with the `momoapi-ruby` command. @@ -77,9 +82,91 @@ collection = Momoapi::Collection.new require 'momoapi-ruby' collection = Momoapi::Collection.new -collection.requestToPay( +collection.request_to_pay( mobile="256772123456", amount="600", external_id="123456789", payee_note="dd", payer_message="dd", currency="EUR") ``` +An extra argument, `callback_url`, can be passed to this method, denoting the URL to the server where the callback should be sent. + +## Disbursements +The disbursements client can be created with the following paramaters. The `DISBURSEMENT_USER_ID` and `DISBURSEMENT_API_SECRET` for production are provided on the MTN OVA dashboard. + +Add the following to your configuration block: +``` + config.disbursement_primary_key = 'Your Disbursement Subscription Key' + config.disbursement_user_id = 'Your Disbursement User ID' + config.disbursement_api_secret = 'Your Disbursement API Key' +``` + +* `disbursement_primary_key`: Primary Key for the `Disbursement` product on the developer portal. +* `disbursement_user_id`: For sandbox, use the one generated with the `momoapi-ruby` command. +* `disbursement_api_secret`: For sandbox, use the one generated with the `momoapi-ruby` command. + +You can create a disbursement client with the following: + +```ruby +require 'momoapi-ruby' + +disbursement = Momoapi::Disbursement.new +``` + +### Methods +1. `transfer`: Used to transfer an amount from the owner’s account to a payee account. Status of the transaction can be validated by using the `get_transaction_status` method. + +2. `get_transaction_status`: Retrieve transaction information using the `transaction_id` returned by `transfer`. You can invoke it at intervals until the transaction fails or succeeds. If the transaction has failed, it will throw an appropriate error. + +3. `get_balance`: Get the balance of the account. + +### Sample Code + +```ruby +require 'momoapi-ruby' + +disbursement = Momoapi::Disbursement.new +disbursement.transfer( + mobile="256772123456", amount="600", external_id="123456789", payee_note="dd", payer_message="dd", currency="EUR") +``` +An extra argument, `callback_url`, can be passed to this method, denoting the URL to the server where the callback should be sent. + +## Remittances +The remittances client can be created with the following paramaters. The `REMITTANCES_USER_ID` and `REMITTANCES_API_SECRET` for production are provided on the MTN OVA dashboard. + +Add the following to your configuration block: +``` + config.remittance_primary_key = 'Your Remittance Subscription Key' + config.remittance_user_id = 'Your Remittance User ID' + config.remittance_api_secret = 'Your Remittance API Key' +``` + +* `remittance_primary_key`: Primary Key for the `Remittance` product on the developer portal. +* `remittance_user_id`: For sandbox, use the one generated with the `momoapi-ruby` command. +* `remittance_api_secret`: For sandbox, use the one generated with the `momoapi-ruby` command. + +You can create a remittance client with the following: + +```ruby +require 'momoapi-ruby' + +remittance = Momoapi::Remittance.new +``` + +### Methods +1. `transfer`: Used to transfer an amount from the owner’s account to a payee account. Status of the transaction can be validated by using the `get_transaction_status` method. + +2. `get_transaction_status`: Retrieve transaction information using the `transaction_id` returned by `transfer`. You can invoke it at intervals until the transaction fails or succeeds. If the transaction has failed, it will throw an appropriate error. + +3. `get_balance`: Get the balance of the account. + +### Sample Code + +```ruby +require 'momoapi-ruby' + +remittance = Momoapi::Remittance.new +remittance.transfer( + mobile="256772123456", amount="600", external_id="123456789", payee_note="dd", payer_message="dd", currency="EUR") +``` +An extra argument, `callback_url`, can be passed to this method, denoting the URL to the server where the callback should be sent. + ## Contributing diff --git a/lib/momoapi-ruby/cli.rb b/lib/momoapi-ruby/cli.rb index 5b31b1f..1fe2f15 100644 --- a/lib/momoapi-ruby/cli.rb +++ b/lib/momoapi-ruby/cli.rb @@ -1,5 +1,9 @@ # frozen_string_literal: true +# This is an executable file allowing a user to use the command line interface +# to pass in a callback host url and a subscription key +# and get back a generated user id and API key + require 'faraday' require 'json' require 'securerandom' diff --git a/lib/momoapi-ruby/client.rb b/lib/momoapi-ruby/client.rb index 0f6c570..6ecefae 100644 --- a/lib/momoapi-ruby/client.rb +++ b/lib/momoapi-ruby/client.rb @@ -1,5 +1,9 @@ # frozen_string_literal: true +# Base implementation of the MTN API client + +# Includes methods common to collections, disbursements and remittances + require 'faraday' require 'momoapi-ruby/config' @@ -23,8 +27,9 @@ def send_request(method, path, headers, *_body) end def interpret_response(resp) + body = resp.body.empty? ? '' : JSON.parse(resp.body) response = { - body: resp.body, + body: body, code: resp.status } unless resp.status >= 200 && resp.status < 300 @@ -37,6 +42,8 @@ def handle_error(response_body, response_code) raise Error::APIError.new(response_body, response_code) end + # Create an access token which can then be used to + # authorize and authenticate towards the other end-points of the API def get_auth_token(path, subscription_key) headers = { "Ocp-Apim-Subscription-Key": subscription_key @@ -55,7 +62,7 @@ def get_auth_token(path, subscription_key) end end - def get_balance(path, subscription_key) + def prepare_get_request(path, subscription_key) headers = { "X-Target-Environment": Momoapi.config.environment || 'sandbox', "Content-Type": 'application/json', @@ -64,13 +71,19 @@ def get_balance(path, subscription_key) send_request('get', path, headers) end + # get the balance on an account + def get_balance(path, subscription_key) + prepare_get_request(path, subscription_key) + end + + # retrieve transaction information, for transfer and payments def get_transaction_status(path, subscription_key) - headers = { - "X-Target-Environment": Momoapi.config.environment || 'sandbox', - "Content-Type": 'application/json', - "Ocp-Apim-Subscription-Key": subscription_key - } - send_request('get', path, headers) + prepare_get_request(path, subscription_key) + end + + # check if an account holder is registered and active in the system + def is_user_active(path, subscription_key) + prepare_get_request(path, subscription_key) end end end diff --git a/lib/momoapi-ruby/collection.rb b/lib/momoapi-ruby/collection.rb index 71c8450..0240164 100644 --- a/lib/momoapi-ruby/collection.rb +++ b/lib/momoapi-ruby/collection.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +# Implementation of the MTN API collections client + require 'securerandom' require 'momoapi-ruby/config' @@ -22,8 +24,16 @@ def get_transaction_status(transaction_id) super(path, Momoapi.config.collection_primary_key) end + # This method is used to request a payment from a consumer (Payer). + # The payer will be asked to authorize the payment. The transaction will + # be executed once the payer has authorized the payment. + # The requesttopay will be in status PENDING until the transaction + # is authorized or declined by the payer or it is timed out by the system. + # The status of the transaction can be validated + # by using `get_transation_status` def request_to_pay(phone_number, amount, external_id, - payee_note = '', payer_message = '', currency = 'EUR') + payee_note = '', payer_message = '', + currency = 'EUR', **options) uuid = SecureRandom.uuid headers = { "X-Target-Environment": Momoapi.config.environment || 'sandbox', @@ -31,6 +41,9 @@ def request_to_pay(phone_number, amount, external_id, "X-Reference-Id": uuid, "Ocp-Apim-Subscription-Key": Momoapi.config.collection_primary_key } + if options[:callback_url] + headers['X-Callback-Url'] = options[:callback_url] + end body = { "payer": { "partyIdType": 'MSISDN', @@ -46,5 +59,10 @@ def request_to_pay(phone_number, amount, external_id, send_request('post', path, headers, body) { transaction_reference: uuid } end + + def is_user_active(phone_number) + path = "/collection/v1_0/accountholder/msisdn/#{phone_number}/active" + super(path, Momoapi.config.collection_primary_key) + end end end diff --git a/lib/momoapi-ruby/config.rb b/lib/momoapi-ruby/config.rb index c38362b..53c07b8 100644 --- a/lib/momoapi-ruby/config.rb +++ b/lib/momoapi-ruby/config.rb @@ -1,5 +1,8 @@ # frozen_string_literal: true +# Configurations are set up in this file +# for a user's MTN MoMo API user credentials + module Momoapi class Config attr_accessor :environment, :base_url, diff --git a/lib/momoapi-ruby/disbursement.rb b/lib/momoapi-ruby/disbursement.rb index c1a5537..0e7ee62 100644 --- a/lib/momoapi-ruby/disbursement.rb +++ b/lib/momoapi-ruby/disbursement.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +# Implementation of the MTN API disbursements client + require 'momoapi-ruby/config' require 'momoapi-ruby/client' @@ -20,8 +22,13 @@ def get_transaction_status(transaction_id) super(path, Momoapi.config.disbursement_primary_key) end + # The transfer operation is used to transfer an amount from the owner’s + # account to a payee account. + # The status of the transaction can be validated + # by using `get_transation_status` def transfer(phone_number, amount, external_id, - payee_note = '', payer_message = '', currency = 'EUR') + payee_note = '', payer_message = '', + currency = 'EUR', **options) uuid = SecureRandom.uuid headers = { "X-Target-Environment": Momoapi.config.environment || 'sandbox', @@ -29,6 +36,9 @@ def transfer(phone_number, amount, external_id, "X-Reference-Id": uuid, "Ocp-Apim-Subscription-Key": Momoapi.config.disbursement_primary_key } + if options[:callback_url] + headers['X-Callback-Url'] = options[:callback_url] + end body = { "payer": { "partyIdType": 'MSISDN', @@ -44,5 +54,10 @@ def transfer(phone_number, amount, external_id, send_request('post', path, headers, body) { transaction_reference: uuid } end + + def is_user_active(phone_number) + path = "/disbursement/v1_0/accountholder/msisdn/#{phone_number}/active" + super(path, Momoapi.config.disbursement_primary_key) + end end end diff --git a/lib/momoapi-ruby/errors.rb b/lib/momoapi-ruby/errors.rb index debc076..f229521 100644 --- a/lib/momoapi-ruby/errors.rb +++ b/lib/momoapi-ruby/errors.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +# Error handling for unsuccessful responses from the MTN Momo API + module Error class APIError < StandardError def initialize(message, code) diff --git a/lib/momoapi-ruby/remittance.rb b/lib/momoapi-ruby/remittance.rb index f564375..2a008ca 100644 --- a/lib/momoapi-ruby/remittance.rb +++ b/lib/momoapi-ruby/remittance.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +# Implementation of the MTN API remittances client + require 'momoapi-ruby/config' require 'momoapi-ruby/client' @@ -20,8 +22,13 @@ def get_transaction_status(transaction_id) super(path, Momoapi.config.remittance_primary_key) end + # The transfer operation is used to transfer an amount from the owner’s + # account to a payee account. + # The status of the transaction can be validated + # by using `get_transation_status` def transfer(phone_number, amount, external_id, - payee_note = '', payer_message = '', currency = 'EUR') + payee_note = '', payer_message = '', + currency = 'EUR', **options) uuid = SecureRandom.uuid headers = { "X-Target-Environment": Momoapi.config.environment || 'sandbox', @@ -29,6 +36,9 @@ def transfer(phone_number, amount, external_id, "X-Reference-Id": uuid, "Ocp-Apim-Subscription-Key": Momoapi.config.disbursement_primary_key } + if options[:callback_url] + headers['X-Callback-Url'] = options[:callback_url] + end body = { "payer": { "partyIdType": 'MSISDN', @@ -44,5 +54,10 @@ def transfer(phone_number, amount, external_id, send_request('post', path, headers, body) { transaction_reference: uuid } end + + def is_user_active(phone_number) + path = "/remittance/v1_0/accountholder/msisdn/#{phone_number}/active" + super(path, Momoapi.config.remittance_primary_key) + end end end diff --git a/momoapi-ruby.gemspec b/momoapi-ruby.gemspec index 477afb6..94b355a 100644 --- a/momoapi-ruby.gemspec +++ b/momoapi-ruby.gemspec @@ -9,17 +9,9 @@ Gem::Specification.new do |spec| spec.version = Momoapi::VERSION spec.authors = ['Lydia Sanyu Naggayi'] spec.email = ['lydiansanyu@gmail.com'] - - spec.summary = 'MTN MoMo API gem' - # spec.description = %q{TODO: Write a longer description} - # spec.homepage = "TODO: Put your gem's website or public repo URL here." - # spec.license = "MIT" - - # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'" - - # spec.metadata["homepage_uri"] = spec.homepage - # spec.metadata["source_code_uri"] = "" - # spec.metadata["changelog_uri"] = "" + spec.summary = 'MTN MoMo gem' + spec.description = 'MTN MoMo API Client for Ruby' + spec.license = 'MIT' # Specify which files should be added to the gem when it is released. # The `git ls-files -z` loads the files in the @@ -33,6 +25,7 @@ Gem::Specification.new do |spec| spec.require_paths = ['lib'] spec.add_development_dependency 'bundler', '~> 2.0' + spec.add_development_dependency 'coveralls', '~> 0.8.15' spec.add_development_dependency 'faraday' spec.add_development_dependency 'pry', '~> 0.12' spec.add_development_dependency 'rake', '~> 10.0' diff --git a/spec/cassettes/Momoapi_Collection/collections/checks_is_user_is_active.yml b/spec/cassettes/Momoapi_Collection/collections/checks_is_user_is_active.yml new file mode 100644 index 0000000..0041499 --- /dev/null +++ b/spec/cassettes/Momoapi_Collection/collections/checks_is_user_is_active.yml @@ -0,0 +1,83 @@ +--- +http_interactions: +- request: + method: post + uri: https://sandbox.momodeveloper.mtn.com/collection/token/ + body: + encoding: UTF-8 + string: '' + headers: + Ocp-Apim-Subscription-Key: + - b5e0f061fa5a4cbbbd2192530b7cedfb + Authorization: + - Basic NzgzYThmMjEtM2ZjNi00ZTM5LWFhNzYtZGE4ZTU2MmZiYTdlOjMxM2NmYWY5YTQwYjQwMjliNzEzOWY0YzlkOGFmYjIz + Content-Length: + - '0' + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Cache-Control: + - no-store + Pragma: + - no-cache + Content-Length: + - '628' + Content-Type: + - application/json;charset=utf-8 + Request-Context: + - appId=cid-v1:e996501c-e721-4ac1-97ff-dc6887b85e8c + Date: + - Mon, 02 Mar 2020 11:29:47 GMT + body: + encoding: UTF-8 + string: '{"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSMjU2In0.eyJjbGllbnRJZCI6Ijc4M2E4ZjIxLTNmYzYtNGUzOS1hYTc2LWRhOGU1NjJmYmE3ZSIsImV4cGlyZXMiOiIyMDIwLTAzLTAyVDEyOjI5OjQ3LjUxMCIsInNlc3Npb25JZCI6IjA3NDk2NmEzLWZhYzktNDMzNC1iYWM0LTM3ZDk1NzRkZDBlYSJ9.d29q6K1ne03SSOdSVaQ_ofTL8mkhXxjoLgRl92h9Dboo5dSyP-pvXW7plMEuU_9yqCRV3B3wGcb0y9791vZAbjgag9cixJBUJY9vktPr_O32VoTB-wnMzy44xUJc3pfqCnne4U8jkm3C3uYrZnEp3jJGh9Ac7mC-SPASEcRRb2g2l9dH8gU1BG43zjkr3MWY7LIk6ZWZ0qDMc6zughjKldp93aphLMvL-WGcwufjtkej6XrXbHw_6maFGdsz5RdYIIHUbGobphOAL9zqEqW0n4Cbr-AC2BGuMI0k_B94Iy4csZ-knbtsDy1819cInW2Fxg_K88rhQZPvRDhf6LvDZA","token_type":"access_token","expires_in":3600}' + http_version: null + recorded_at: Mon, 02 Mar 2020 11:29:47 GMT +- request: + method: get + uri: https://sandbox.momodeveloper.mtn.com/collection/v1_0/accountholder/msisdn/0243656543/active + body: + encoding: US-ASCII + string: '' + headers: + X-Target-Environment: + - sandbox + Content-Type: + - application/json + Ocp-Apim-Subscription-Key: + - b5e0f061fa5a4cbbbd2192530b7cedfb + Authorization: + - Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSMjU2In0.eyJjbGllbnRJZCI6Ijc4M2E4ZjIxLTNmYzYtNGUzOS1hYTc2LWRhOGU1NjJmYmE3ZSIsImV4cGlyZXMiOiIyMDIwLTAzLTAyVDEyOjI5OjQ3LjUxMCIsInNlc3Npb25JZCI6IjA3NDk2NmEzLWZhYzktNDMzNC1iYWM0LTM3ZDk1NzRkZDBlYSJ9.d29q6K1ne03SSOdSVaQ_ofTL8mkhXxjoLgRl92h9Dboo5dSyP-pvXW7plMEuU_9yqCRV3B3wGcb0y9791vZAbjgag9cixJBUJY9vktPr_O32VoTB-wnMzy44xUJc3pfqCnne4U8jkm3C3uYrZnEp3jJGh9Ac7mC-SPASEcRRb2g2l9dH8gU1BG43zjkr3MWY7LIk6ZWZ0qDMc6zughjKldp93aphLMvL-WGcwufjtkej6XrXbHw_6maFGdsz5RdYIIHUbGobphOAL9zqEqW0n4Cbr-AC2BGuMI0k_B94Iy4csZ-knbtsDy1819cInW2Fxg_K88rhQZPvRDhf6LvDZA + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Content-Length: + - '15' + Content-Type: + - application/json;charset=utf-8 + Request-Context: + - appId=cid-v1:e996501c-e721-4ac1-97ff-dc6887b85e8c + Date: + - Mon, 02 Mar 2020 11:29:49 GMT + body: + encoding: UTF-8 + string: '{"result":true}' + http_version: null + recorded_at: Mon, 02 Mar 2020 11:29:49 GMT +recorded_with: VCR 5.1.0 diff --git a/spec/cassettes/Momoapi_Remittance/remittances/gets_balance.yml b/spec/cassettes/Momoapi_Remittance/remittances/gets_balance.yml new file mode 100644 index 0000000..6032575 --- /dev/null +++ b/spec/cassettes/Momoapi_Remittance/remittances/gets_balance.yml @@ -0,0 +1,83 @@ +--- +http_interactions: +- request: + method: post + uri: https://sandbox.momodeveloper.mtn.com/remittance/token/ + body: + encoding: UTF-8 + string: '' + headers: + Ocp-Apim-Subscription-Key: + - d314b91c889340b682a9a3144a9ffd1b + Authorization: + - Basic NzgzYThmMjEtM2ZjNi00ZTM5LWFhNzYtZGE4ZTU2MmZiYTdlOjMxM2NmYWY5YTQwYjQwMjliNzEzOWY0YzlkOGFmYjIz + Content-Length: + - '0' + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Cache-Control: + - no-store + Pragma: + - no-cache + Content-Length: + - '628' + Content-Type: + - application/json;charset=utf-8 + Request-Context: + - appId=cid-v1:e996501c-e721-4ac1-97ff-dc6887b85e8c + Date: + - Mon, 02 Mar 2020 12:07:55 GMT + body: + encoding: UTF-8 + string: '{"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSMjU2In0.eyJjbGllbnRJZCI6Ijc4M2E4ZjIxLTNmYzYtNGUzOS1hYTc2LWRhOGU1NjJmYmE3ZSIsImV4cGlyZXMiOiIyMDIwLTAzLTAyVDEzOjA3OjU1LjE0MyIsInNlc3Npb25JZCI6IjgzY2Y3Zjg3LWNlN2EtNDlmYi04ZDU4LTdiMTFmODA0NWE1NSJ9.gT1-u80gziEk8_DaT3y4T14PJdJ2tfPYdK1yJAlIMTA-g3eIfIVmCQ7PIo1SnHhRHcJN-CIL0kRsk9lBxSWN5r2aUWLHrZQoTrnE0HkmSZtAsofzKJOhpHgk4K_L2H9aFnSHISDGqFnosRh6RcNOsactnVw4YPxKvbs9ysZ8Vh5eJPpqQ7KdhDRnILuBzikN1cJe-kOjsv0nKWOp88peDHy_HtXPzrAXJBzP0a5ElodnjnlXLu0J-TQET0l-Sll26YN4T9FdnC-3teJIwwNWSufndy0ynvHbagrG6VB_im27wa4Z7EwXhXmOgJe0PsnEAdzbmEEF87kSQ2rb-FnYdw","token_type":"access_token","expires_in":3600}' + http_version: null + recorded_at: Mon, 02 Mar 2020 12:07:55 GMT +- request: + method: get + uri: https://sandbox.momodeveloper.mtn.com/remittance/v1_0/account/balance + body: + encoding: US-ASCII + string: '' + headers: + X-Target-Environment: + - sandbox + Content-Type: + - application/json + Ocp-Apim-Subscription-Key: + - d314b91c889340b682a9a3144a9ffd1b + Authorization: + - Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSMjU2In0.eyJjbGllbnRJZCI6Ijc4M2E4ZjIxLTNmYzYtNGUzOS1hYTc2LWRhOGU1NjJmYmE3ZSIsImV4cGlyZXMiOiIyMDIwLTAzLTAyVDEzOjA3OjU1LjE0MyIsInNlc3Npb25JZCI6IjgzY2Y3Zjg3LWNlN2EtNDlmYi04ZDU4LTdiMTFmODA0NWE1NSJ9.gT1-u80gziEk8_DaT3y4T14PJdJ2tfPYdK1yJAlIMTA-g3eIfIVmCQ7PIo1SnHhRHcJN-CIL0kRsk9lBxSWN5r2aUWLHrZQoTrnE0HkmSZtAsofzKJOhpHgk4K_L2H9aFnSHISDGqFnosRh6RcNOsactnVw4YPxKvbs9ysZ8Vh5eJPpqQ7KdhDRnILuBzikN1cJe-kOjsv0nKWOp88peDHy_HtXPzrAXJBzP0a5ElodnjnlXLu0J-TQET0l-Sll26YN4T9FdnC-3teJIwwNWSufndy0ynvHbagrG6VB_im27wa4Z7EwXhXmOgJe0PsnEAdzbmEEF87kSQ2rb-FnYdw + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 500 + message: Server Error + headers: + Content-Length: + - '93' + Content-Type: + - application/json;charset=utf-8 + Request-Context: + - appId=cid-v1:e996501c-e721-4ac1-97ff-dc6887b85e8c + Date: + - Mon, 02 Mar 2020 12:07:56 GMT + body: + encoding: UTF-8 + string: '{"message":"An internal error occurred while processing.","code":"INTERNAL_PROCESSING_ERROR"}' + http_version: null + recorded_at: Mon, 02 Mar 2020 12:07:56 GMT +recorded_with: VCR 5.1.0 diff --git a/spec/cassettes/Momoapi_Remittance/remittances/gets_transaction_status.yml b/spec/cassettes/Momoapi_Remittance/remittances/gets_transaction_status.yml new file mode 100644 index 0000000..ea71bf2 --- /dev/null +++ b/spec/cassettes/Momoapi_Remittance/remittances/gets_transaction_status.yml @@ -0,0 +1,81 @@ +--- +http_interactions: +- request: + method: post + uri: https://sandbox.momodeveloper.mtn.com/remittance/token/ + body: + encoding: UTF-8 + string: '' + headers: + Ocp-Apim-Subscription-Key: + - d314b91c889340b682a9a3144a9ffd1b + Authorization: + - Basic NzgzYThmMjEtM2ZjNi00ZTM5LWFhNzYtZGE4ZTU2MmZiYTdlOjMxM2NmYWY5YTQwYjQwMjliNzEzOWY0YzlkOGFmYjIz + Content-Length: + - '0' + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Cache-Control: + - no-store + Pragma: + - no-cache + Content-Length: + - '628' + Content-Type: + - application/json;charset=utf-8 + Request-Context: + - appId=cid-v1:e996501c-e721-4ac1-97ff-dc6887b85e8c + Date: + - Mon, 02 Mar 2020 12:07:57 GMT + body: + encoding: UTF-8 + string: '{"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSMjU2In0.eyJjbGllbnRJZCI6Ijc4M2E4ZjIxLTNmYzYtNGUzOS1hYTc2LWRhOGU1NjJmYmE3ZSIsImV4cGlyZXMiOiIyMDIwLTAzLTAyVDEzOjA3OjU3LjQ0NyIsInNlc3Npb25JZCI6ImE1MjM3NzJkLTQ2ZTQtNGRiNy05YjliLWZjYzQyMTMyOTVmNyJ9.hck9MYcTndOMH45kMoqhQO7-Ml0a6fBtwZOtB-Xax_Ru-FP-1efBLnpbTIWzC9H888o6NieyZPHpecnMoak1OwgudseSsF8cW5W0cYVWgqe1YEBppJlSvo6vTLBWIpR0nJ6QhHew3uZMl6CJoya5Zgu1DDNpfbNOOatNy-ae_1TDqsGbTi7eGZQ0ePzsgJ88EMpUekyjP5gbwlvWO1SWcsrAG3kgzmWb6twHdTN355izeQ4iXYt_bCyHdmKJhb2M2Bz_M9CDpq4QWXhXdUIeFqv0bRk9ReLnUoIM2bMtaXzwb6JX4ouulYuhP3knvYbzikb8HEjDr_h3Bke5KPIGjw","token_type":"access_token","expires_in":3600}' + http_version: null + recorded_at: Mon, 02 Mar 2020 12:07:57 GMT +- request: + method: get + uri: https://sandbox.momodeveloper.mtn.com/remittance/v1_0/transfer/888a79ff-0535-4a9f-8a66-457f7903bd8ab + body: + encoding: US-ASCII + string: '' + headers: + X-Target-Environment: + - sandbox + Content-Type: + - application/json + Ocp-Apim-Subscription-Key: + - d314b91c889340b682a9a3144a9ffd1b + Authorization: + - Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSMjU2In0.eyJjbGllbnRJZCI6Ijc4M2E4ZjIxLTNmYzYtNGUzOS1hYTc2LWRhOGU1NjJmYmE3ZSIsImV4cGlyZXMiOiIyMDIwLTAzLTAyVDEzOjA3OjU3LjQ0NyIsInNlc3Npb25JZCI6ImE1MjM3NzJkLTQ2ZTQtNGRiNy05YjliLWZjYzQyMTMyOTVmNyJ9.hck9MYcTndOMH45kMoqhQO7-Ml0a6fBtwZOtB-Xax_Ru-FP-1efBLnpbTIWzC9H888o6NieyZPHpecnMoak1OwgudseSsF8cW5W0cYVWgqe1YEBppJlSvo6vTLBWIpR0nJ6QhHew3uZMl6CJoya5Zgu1DDNpfbNOOatNy-ae_1TDqsGbTi7eGZQ0ePzsgJ88EMpUekyjP5gbwlvWO1SWcsrAG3kgzmWb6twHdTN355izeQ4iXYt_bCyHdmKJhb2M2Bz_M9CDpq4QWXhXdUIeFqv0bRk9ReLnUoIM2bMtaXzwb6JX4ouulYuhP3knvYbzikb8HEjDr_h3Bke5KPIGjw + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 400 + message: Bad Request + headers: + Content-Length: + - '0' + Request-Context: + - appId=cid-v1:e996501c-e721-4ac1-97ff-dc6887b85e8c + Date: + - Mon, 02 Mar 2020 12:07:57 GMT + body: + encoding: UTF-8 + string: '' + http_version: null + recorded_at: Mon, 02 Mar 2020 12:07:58 GMT +recorded_with: VCR 5.1.0 diff --git a/spec/cassettes/Momoapi_Remittance/remittances/makes_transfer.yml b/spec/cassettes/Momoapi_Remittance/remittances/makes_transfer.yml new file mode 100644 index 0000000..093649e --- /dev/null +++ b/spec/cassettes/Momoapi_Remittance/remittances/makes_transfer.yml @@ -0,0 +1,90 @@ +--- +http_interactions: +- request: + method: post + uri: https://sandbox.momodeveloper.mtn.com/remittance/token/ + body: + encoding: UTF-8 + string: '' + headers: + Ocp-Apim-Subscription-Key: + - d314b91c889340b682a9a3144a9ffd1b + Authorization: + - Basic NzgzYThmMjEtM2ZjNi00ZTM5LWFhNzYtZGE4ZTU2MmZiYTdlOjMxM2NmYWY5YTQwYjQwMjliNzEzOWY0YzlkOGFmYjIz + Content-Length: + - '0' + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Cache-Control: + - no-store + Pragma: + - no-cache + Content-Length: + - '628' + Content-Type: + - application/json;charset=utf-8 + Request-Context: + - appId=cid-v1:e996501c-e721-4ac1-97ff-dc6887b85e8c + Date: + - Mon, 02 Mar 2020 12:07:59 GMT + body: + encoding: UTF-8 + string: '{"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSMjU2In0.eyJjbGllbnRJZCI6Ijc4M2E4ZjIxLTNmYzYtNGUzOS1hYTc2LWRhOGU1NjJmYmE3ZSIsImV4cGlyZXMiOiIyMDIwLTAzLTAyVDEzOjA3OjU5LjQ4MyIsInNlc3Npb25JZCI6Ijg2NGU2ZTdmLTBkZmMtNGM3MS04ODIyLWZjY2Y1NDgxMGI0OCJ9.MDAyvP439yl-G-O9hiO8AjDxgO7R-nreq2eSiEf13B9xz4HjmyulUa0cp1Ls_8mtkrdIgeYXXAV-L0d4L6u_02hUC5MGzA5IbNxwfd9Lt74LlEUn7TvVkhfK1hbBUA_D_vrH1Imgmt7KT5SZC54WaEmWTUHRx5OS_acrekeny0oV1DhQuCoA1ArA_W6-sZLzXG7S8N6QZy6usU8fWD9Fs7hiuS8B9lMthg2EjXpqa5UWdmlNUuQdzh5ri0_nxzeWLHsq64OPYeFlppKQXYHUf6Lrd4YSMCNq9ktSHSSNjmWSrWwrUPMuji5NZ2uB7djCDZ7LmLWUfxhEmZwIigjg5w","token_type":"access_token","expires_in":3600}' + http_version: null + recorded_at: Mon, 02 Mar 2020 12:07:59 GMT +- request: + method: post + uri: https://sandbox.momodeveloper.mtn.com/remittance/v1_0/transfer + body: + encoding: UTF-8 + string: '' + headers: + X-Target-Environment: + - sandbox + Content-Type: + - application/json + X-Reference-Id: + - df2b6f54-114f-4588-8dce-a4c50734f9e4 + Ocp-Apim-Subscription-Key: + - 0c74e0a1cf344d45a3d02b1da52c12f5 + Authorization: + - Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSMjU2In0.eyJjbGllbnRJZCI6Ijc4M2E4ZjIxLTNmYzYtNGUzOS1hYTc2LWRhOGU1NjJmYmE3ZSIsImV4cGlyZXMiOiIyMDIwLTAzLTAyVDEzOjA3OjU5LjQ4MyIsInNlc3Npb25JZCI6Ijg2NGU2ZTdmLTBkZmMtNGM3MS04ODIyLWZjY2Y1NDgxMGI0OCJ9.MDAyvP439yl-G-O9hiO8AjDxgO7R-nreq2eSiEf13B9xz4HjmyulUa0cp1Ls_8mtkrdIgeYXXAV-L0d4L6u_02hUC5MGzA5IbNxwfd9Lt74LlEUn7TvVkhfK1hbBUA_D_vrH1Imgmt7KT5SZC54WaEmWTUHRx5OS_acrekeny0oV1DhQuCoA1ArA_W6-sZLzXG7S8N6QZy6usU8fWD9Fs7hiuS8B9lMthg2EjXpqa5UWdmlNUuQdzh5ri0_nxzeWLHsq64OPYeFlppKQXYHUf6Lrd4YSMCNq9ktSHSSNjmWSrWwrUPMuji5NZ2uB7djCDZ7LmLWUfxhEmZwIigjg5w + Content-Length: + - '0' + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 401 + message: Access Denied + headers: + Content-Length: + - '143' + Content-Type: + - application/json + Request-Context: + - appId=cid-v1:e996501c-e721-4ac1-97ff-dc6887b85e8c + Www-Authenticate: + - AzureApiManagementKey realm="https://sandbox.momodeveloper.mtn.com/remittance",name="Ocp-Apim-Subscription-Key",type="header" + Date: + - Mon, 02 Mar 2020 12:07:59 GMT + body: + encoding: UTF-8 + string: '{ "statusCode": 401, "message": "Access denied due to invalid subscription + key. Make sure to provide a valid key for an active subscription." }' + http_version: null + recorded_at: Mon, 02 Mar 2020 12:08:00 GMT +recorded_with: VCR 5.1.0 diff --git a/spec/features/collection_spec.rb b/spec/features/collection_spec.rb index 3a9f3a1..fc30a6e 100644 --- a/spec/features/collection_spec.rb +++ b/spec/features/collection_spec.rb @@ -14,9 +14,12 @@ end describe 'collections', vcr: { record: :new_episodes } do + it 'checks is user is active' do + response = Momoapi::Collection.new.is_user_active('0243656543') + expect(response[:code]).to eq(200) + end + it 'gets balance' do - # response = Momoapi::Collection.new.get_balance - # expect(response).to have_http_status 200 expect { Momoapi::Collection.new.get_balance } .to raise_error(Error::APIError) end diff --git a/spec/features/remittance_spec.rb b/spec/features/remittance_spec.rb index 8c966b6..33b26bc 100644 --- a/spec/features/remittance_spec.rb +++ b/spec/features/remittance_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Momoapi::Disbursement do +RSpec.describe Momoapi::Remittance do before(:all) do Momoapi.configure do |config| config.base_url = 'https://sandbox.momodeveloper.mtn.com' diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index c2ce482..473a5da 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,8 @@ # frozen_string_literal: true +require 'coveralls' +Coveralls.wear! + require 'bundler/setup' require 'momoapi-ruby' require 'webmock/rspec'