diff --git a/lib/momoapi-ruby.rb b/lib/momoapi-ruby.rb index f6ad45a..4387225 100644 --- a/lib/momoapi-ruby.rb +++ b/lib/momoapi-ruby.rb @@ -5,6 +5,7 @@ require 'momoapi-ruby/cli' require 'momoapi-ruby/collection' require 'momoapi-ruby/disbursement' +require 'momoapi-ruby/remittance' module Momoapi class << self diff --git a/lib/momoapi-ruby/remittance.rb b/lib/momoapi-ruby/remittance.rb index e86c46a..f564375 100644 --- a/lib/momoapi-ruby/remittance.rb +++ b/lib/momoapi-ruby/remittance.rb @@ -6,7 +6,7 @@ module Momoapi class Remittance < Client def get_auth_token - path = 'remittance/token' + path = 'remittance/token/' super(path, Momoapi.config.remittance_primary_key) end @@ -20,6 +20,29 @@ def get_transaction_status(transaction_id) super(path, Momoapi.config.remittance_primary_key) end - def transfer; end + def transfer(phone_number, amount, external_id, + payee_note = '', payer_message = '', currency = 'EUR') + uuid = SecureRandom.uuid + headers = { + "X-Target-Environment": Momoapi.config.environment || 'sandbox', + "Content-Type": 'application/json', + "X-Reference-Id": uuid, + "Ocp-Apim-Subscription-Key": Momoapi.config.disbursement_primary_key + } + body = { + "payer": { + "partyIdType": 'MSISDN', + "partyId": phone_number + }, + "payeeNote": payee_note, + "payerMessage": payer_message, + "externalId": external_id, + "currency": currency, + "amount": amount.to_s + } + path = '/remittance/v1_0/transfer' + send_request('post', path, headers, body) + { transaction_reference: uuid } + end end end diff --git a/spec/cassettes/Momoapi_Disbursement/remittances/gets_balance.yml b/spec/cassettes/Momoapi_Disbursement/remittances/gets_balance.yml new file mode 100644 index 0000000..82fcdf0 --- /dev/null +++ b/spec/cassettes/Momoapi_Disbursement/remittances/gets_balance.yml @@ -0,0 +1,120 @@ +--- +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: 302 + message: Found + headers: + Content-Length: + - '0' + Location: + - https://52.236.59.28:8080/token/ + Request-Context: + - appId=cid-v1:e996501c-e721-4ac1-97ff-dc6887b85e8c + Date: + - Thu, 27 Feb 2020 13:23:45 GMT + body: + encoding: UTF-8 + string: '' + http_version: null + recorded_at: Thu, 27 Feb 2020 13:23:45 GMT +- 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: + - Thu, 27 Feb 2020 13:29:36 GMT + body: + encoding: UTF-8 + string: '{"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSMjU2In0.eyJjbGllbnRJZCI6Ijc4M2E4ZjIxLTNmYzYtNGUzOS1hYTc2LWRhOGU1NjJmYmE3ZSIsImV4cGlyZXMiOiIyMDIwLTAyLTI3VDE0OjI5OjM2LjM1MyIsInNlc3Npb25JZCI6IjZkNTY0ZDM0LTk4YjAtNDYwOC05NGJkLTkyM2JlYzM1MmRjYyJ9.e2lvLTU5Oi2KjoVp7BggMNurcLC4DtqjrEaCGWRpLQCpPbnDFHI_FHFS1tvOLTxNWSb3gAzH5KvxTmmqFkDatph4EpnubmkcuFRcXzyrpAz1IxOQlZ7zYK0ufI-k4KUCMYwxHb9g5s48YtdQJdUXtspbSVVfuTomGaWUHiheAMPDp7Nz83FVGD5TcGJxnprotXs0kfNoZofX-aqhKFHfnBxPiGOcmA1EceNNsHR_r30La3PqfpSGp5EWtr96VGyG6chjYLldMZi_ENhT5qIrDkMjd-Hr7orrJ7f5_yVlSL5ssEsk1GSTxCQWcyiK6uIwo_eAPn8P5-si0Cw0nPN85Q","token_type":"access_token","expires_in":3600}' + http_version: null + recorded_at: Thu, 27 Feb 2020 13:29:36 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.eyJjbGllbnRJZCI6Ijc4M2E4ZjIxLTNmYzYtNGUzOS1hYTc2LWRhOGU1NjJmYmE3ZSIsImV4cGlyZXMiOiIyMDIwLTAyLTI3VDE0OjI5OjM2LjM1MyIsInNlc3Npb25JZCI6IjZkNTY0ZDM0LTk4YjAtNDYwOC05NGJkLTkyM2JlYzM1MmRjYyJ9.e2lvLTU5Oi2KjoVp7BggMNurcLC4DtqjrEaCGWRpLQCpPbnDFHI_FHFS1tvOLTxNWSb3gAzH5KvxTmmqFkDatph4EpnubmkcuFRcXzyrpAz1IxOQlZ7zYK0ufI-k4KUCMYwxHb9g5s48YtdQJdUXtspbSVVfuTomGaWUHiheAMPDp7Nz83FVGD5TcGJxnprotXs0kfNoZofX-aqhKFHfnBxPiGOcmA1EceNNsHR_r30La3PqfpSGp5EWtr96VGyG6chjYLldMZi_ENhT5qIrDkMjd-Hr7orrJ7f5_yVlSL5ssEsk1GSTxCQWcyiK6uIwo_eAPn8P5-si0Cw0nPN85Q + 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: + - '96' + Content-Type: + - application/json;charset=utf-8 + Request-Context: + - appId=cid-v1:e996501c-e721-4ac1-97ff-dc6887b85e8c + Date: + - Thu, 27 Feb 2020 13:29:36 GMT + body: + encoding: UTF-8 + string: '{"message":"Access to target environment is forbidden.","code":"NOT_ALLOWED_TARGET_ENVIRONMENT"}' + http_version: null + recorded_at: Thu, 27 Feb 2020 13:29:37 GMT +recorded_with: VCR 5.1.0 diff --git a/spec/cassettes/Momoapi_Disbursement/remittances/gets_transaction_status.yml b/spec/cassettes/Momoapi_Disbursement/remittances/gets_transaction_status.yml new file mode 100644 index 0000000..739a6f4 --- /dev/null +++ b/spec/cassettes/Momoapi_Disbursement/remittances/gets_transaction_status.yml @@ -0,0 +1,118 @@ +--- +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: 302 + message: Found + headers: + Content-Length: + - '0' + Location: + - https://52.236.59.28:8080/token/ + Request-Context: + - appId=cid-v1:e996501c-e721-4ac1-97ff-dc6887b85e8c + Date: + - Thu, 27 Feb 2020 13:23:46 GMT + body: + encoding: UTF-8 + string: '' + http_version: null + recorded_at: Thu, 27 Feb 2020 13:23:46 GMT +- 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: + - Thu, 27 Feb 2020 13:29:38 GMT + body: + encoding: UTF-8 + string: '{"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSMjU2In0.eyJjbGllbnRJZCI6Ijc4M2E4ZjIxLTNmYzYtNGUzOS1hYTc2LWRhOGU1NjJmYmE3ZSIsImV4cGlyZXMiOiIyMDIwLTAyLTI3VDE0OjI5OjM4LjA5NSIsInNlc3Npb25JZCI6IjlmMTBiOTI5LTFhZGUtNDE2ZS1iNjQzLWZjOTM1NTc3NDQ0ZiJ9.k8yj-7UX13bwyySxNyrZzN7R3iu2FbDJlsFJl0JqxB79dMlWWQGvwB6Gxin7KmGFXYw87XZNzuFsAKe3s5SThrjIsKtlBIQ_CVcjnWcxxtXOH43VxH4E0A3UPyVEpTt6xeQJ-Xloe0x7mjYtFUaEIg32Nihqfv781Xqq9zuaeNfzBuHA2vHIv-wvmAsr5dnrOwmzEujXV58_rya_ZE5rkkb15ZDwOJ2WzTlrjbUow13vuVKwdT3s7_kwoxV_ObnZHVOsB-e32AHR56Aa_8C99lNFvRIF913xSsDXF-H18B-PoBDLcNz4xNoMLZb2GWz5wLsNLGWGkW2k4DiWCYMfEQ","token_type":"access_token","expires_in":3600}' + http_version: null + recorded_at: Thu, 27 Feb 2020 13:29:38 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.eyJjbGllbnRJZCI6Ijc4M2E4ZjIxLTNmYzYtNGUzOS1hYTc2LWRhOGU1NjJmYmE3ZSIsImV4cGlyZXMiOiIyMDIwLTAyLTI3VDE0OjI5OjM4LjA5NSIsInNlc3Npb25JZCI6IjlmMTBiOTI5LTFhZGUtNDE2ZS1iNjQzLWZjOTM1NTc3NDQ0ZiJ9.k8yj-7UX13bwyySxNyrZzN7R3iu2FbDJlsFJl0JqxB79dMlWWQGvwB6Gxin7KmGFXYw87XZNzuFsAKe3s5SThrjIsKtlBIQ_CVcjnWcxxtXOH43VxH4E0A3UPyVEpTt6xeQJ-Xloe0x7mjYtFUaEIg32Nihqfv781Xqq9zuaeNfzBuHA2vHIv-wvmAsr5dnrOwmzEujXV58_rya_ZE5rkkb15ZDwOJ2WzTlrjbUow13vuVKwdT3s7_kwoxV_ObnZHVOsB-e32AHR56Aa_8C99lNFvRIF913xSsDXF-H18B-PoBDLcNz4xNoMLZb2GWz5wLsNLGWGkW2k4DiWCYMfEQ + 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: + - Thu, 27 Feb 2020 13:29:38 GMT + body: + encoding: UTF-8 + string: '' + http_version: null + recorded_at: Thu, 27 Feb 2020 13:29:39 GMT +recorded_with: VCR 5.1.0 diff --git a/spec/cassettes/Momoapi_Disbursement/remittances/makes_transfer.yml b/spec/cassettes/Momoapi_Disbursement/remittances/makes_transfer.yml new file mode 100644 index 0000000..241c467 --- /dev/null +++ b/spec/cassettes/Momoapi_Disbursement/remittances/makes_transfer.yml @@ -0,0 +1,127 @@ +--- +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: 302 + message: Found + headers: + Content-Length: + - '0' + Location: + - https://52.236.59.28:8080/token/ + Request-Context: + - appId=cid-v1:e996501c-e721-4ac1-97ff-dc6887b85e8c + Date: + - Thu, 27 Feb 2020 13:23:46 GMT + body: + encoding: UTF-8 + string: '' + http_version: null + recorded_at: Thu, 27 Feb 2020 13:23:47 GMT +- 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: + - Thu, 27 Feb 2020 13:29:40 GMT + body: + encoding: UTF-8 + string: '{"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSMjU2In0.eyJjbGllbnRJZCI6Ijc4M2E4ZjIxLTNmYzYtNGUzOS1hYTc2LWRhOGU1NjJmYmE3ZSIsImV4cGlyZXMiOiIyMDIwLTAyLTI3VDE0OjI5OjQwLjAzOSIsInNlc3Npb25JZCI6IjVmMjVkNGQ1LWI1ZWItNDU3My05YjIyLTc2MDRiNDk2MTg5ZCJ9.d8yxHi3XfB5Zm0CjfZmBoyYlvInE6xmHnGjAm2n8Dr-G8JPBGCWuZvD_VkPOZJW23RdbyqRVjYzsTK5GaWukraXVoT4Sgym4cxGEJbHbe9qH_PwhQY8KQIlr1ae6HufE53-lMELn-nuCMzfK8YCX18gf84DIBSZFsNDuCy3nZUMbQgrrg0VrmAevX4Zr_M86D4weluhxc7c_LS27qnIH9PjJzOcANSSs8nWuaJ-5l3rc9WK4zEcVe08yViZYgFHoyQ70F5OFEhWzb3b5zdD15PbFVJgvphB05aavqEujLeZPVHDMat3gexVCyS_dKvyPNFabuaMnBuk3yShmpn6F5A","token_type":"access_token","expires_in":3600}' + http_version: null + recorded_at: Thu, 27 Feb 2020 13:29:40 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: + - 80f458da-fd56-4a76-90f2-df65cfcdaef3 + Ocp-Apim-Subscription-Key: + - 0c74e0a1cf344d45a3d02b1da52c12f5 + Authorization: + - Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSMjU2In0.eyJjbGllbnRJZCI6Ijc4M2E4ZjIxLTNmYzYtNGUzOS1hYTc2LWRhOGU1NjJmYmE3ZSIsImV4cGlyZXMiOiIyMDIwLTAyLTI3VDE0OjI5OjQwLjAzOSIsInNlc3Npb25JZCI6IjVmMjVkNGQ1LWI1ZWItNDU3My05YjIyLTc2MDRiNDk2MTg5ZCJ9.d8yxHi3XfB5Zm0CjfZmBoyYlvInE6xmHnGjAm2n8Dr-G8JPBGCWuZvD_VkPOZJW23RdbyqRVjYzsTK5GaWukraXVoT4Sgym4cxGEJbHbe9qH_PwhQY8KQIlr1ae6HufE53-lMELn-nuCMzfK8YCX18gf84DIBSZFsNDuCy3nZUMbQgrrg0VrmAevX4Zr_M86D4weluhxc7c_LS27qnIH9PjJzOcANSSs8nWuaJ-5l3rc9WK4zEcVe08yViZYgFHoyQ70F5OFEhWzb3b5zdD15PbFVJgvphB05aavqEujLeZPVHDMat3gexVCyS_dKvyPNFabuaMnBuk3yShmpn6F5A + 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: + - Thu, 27 Feb 2020 13:29:41 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: Thu, 27 Feb 2020 13:29:41 GMT +recorded_with: VCR 5.1.0 diff --git a/spec/features/remittance_spec.rb b/spec/features/remittance_spec.rb new file mode 100644 index 0000000..8c966b6 --- /dev/null +++ b/spec/features/remittance_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Momoapi::Disbursement do + before(:all) do + Momoapi.configure do |config| + config.base_url = 'https://sandbox.momodeveloper.mtn.com' + config.callback_host = 'https://webhook.site/8e412414-2154-4d06-90c4-5e141c9f2910' + config.remittance_primary_key = 'd314b91c889340b682a9a3144a9ffd1b' + config.remittance_user_id = 'cf028de4-7341-41c0-b4ff-3fa190b77236' + config.remittance_api_secret = 'dcacc115e6fd4669b1db622d4b949947' + end + end + + describe 'remittances', vcr: { record: :new_episodes } do + it 'gets balance' do + expect { Momoapi::Remittance.new.get_balance } + .to raise_error(Error::APIError) + end + + it 'gets transaction status' do + ref = '888a79ff-0535-4a9f-8a66-457f7903bd8ab' + expect { Momoapi::Remittance.new.get_transaction_status(ref) } + .to raise_error(Error::APIError) + end + + it 'makes transfer' do + expect do + Momoapi::Remittance.new.transfer( + '0775671360', + '5.0', '6353636', + 'testing', 'testing', 'EUR' + ) + end .to raise_error(Error::APIError) + end + end +end