use crate::{
common::{http_client::MomoHttpClient, token_manager::ProductType},
responses::{
refund_result::RefundResult, token_response::TokenResponse, transfer_result::TransferResult,
},
BCAuthorizeResponse, Balance, BasicUserInfoJsonResponse, Currency, DepositId, Environment,
OAuth2TokenResponse, RefundId, RefundRequest, TranserId, TransferRequest,
};
use super::account::Account;
pub struct Disbursements {
pub url: String,
pub primary_key: String,
pub secondary_key: String,
pub environment: Environment,
pub api_user: String,
pub api_key: String,
account: Account,
http_client: MomoHttpClient,
}
impl Disbursements {
pub fn new(
url: String,
environment: Environment,
api_user: String,
api_key: String,
primary_key: String,
secondary_key: String,
) -> Disbursements {
let account = Account {};
let http_client = MomoHttpClient::new(
url.clone(),
ProductType::Disbursement,
environment,
api_user.clone(),
api_key.clone(),
primary_key.clone(),
);
Disbursements {
url,
primary_key,
secondary_key,
environment,
api_key,
api_user,
account,
http_client,
}
}
async fn create_access_token(&self) -> Result<TokenResponse, Box<dyn std::error::Error>> {
let url = format!("{}/{}", self.url, "disbursement");
let auth = crate::products::auth::Authorization {};
let token = auth
.create_access_token(
url,
self.api_user.clone(),
self.api_key.clone(),
self.primary_key.clone(),
)
.await?;
Ok(token)
}
#[allow(dead_code)]
async fn create_o_auth_2_token(
&self,
auth_req_id: String,
) -> Result<OAuth2TokenResponse, Box<dyn std::error::Error>> {
let url = format!("{}/{}", self.url, "disbursement");
let auth = crate::products::auth::Authorization {};
auth.create_o_auth_2_token(
url,
self.api_user.clone(),
self.api_key.clone(),
self.environment,
self.primary_key.clone(),
auth_req_id,
)
.await
}
#[allow(dead_code)]
async fn bc_authorize(
&self,
msisdn: String,
callback_url: Option<&str>,
) -> Result<BCAuthorizeResponse, Box<dyn std::error::Error>> {
let url = format!("{}/{}", self.url, "disbursement");
let auth = crate::products::auth::Authorization {};
let access_token: TokenResponse = self.create_access_token().await?;
auth.bc_authorize(
url,
self.environment,
self.primary_key.clone(),
msisdn,
callback_url,
access_token,
)
.await
}
pub async fn deposit_v1(
&self,
transfer: TransferRequest,
callback_url: Option<&str>,
) -> Result<DepositId, Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let access_token = self.http_client.get_or_create_token().await?;
let mut req = client
.post(format!("{}/disbursement/v1_0/deposit", self.url))
.bearer_auth(access_token.access_token)
.header("Content-Type", "application/json")
.header("X-Target-Environment", self.environment.to_string())
.header("X-Reference-Id", &transfer.external_id)
.header("Cache-Control", "no-cache")
.header("Ocp-Apim-Subscription-Key", &self.primary_key)
.body(transfer.clone());
if let Some(callback_url) = callback_url {
if !callback_url.is_empty() {
req = req.header(
"X-Callback-Url",
format!("{}/disbursement_deposit_v1", callback_url),
);
}
}
let res = req.send().await?;
if res.status().is_success() {
Ok(DepositId::new(transfer.external_id))
} else {
Err(Box::new(std::io::Error::other(res.text().await?)))
}
}
pub async fn deposit_v2(
&self,
transfer: TransferRequest,
callback_url: Option<&str>,
) -> Result<DepositId, Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let access_token = self.http_client.get_or_create_token().await?;
let mut req = client
.post(format!("{}/disbursement/v2_0/deposit", self.url))
.bearer_auth(access_token.access_token)
.header("Content-Type", "application/json")
.header("X-Target-Environment", self.environment.to_string())
.header("X-Reference-Id", &transfer.external_id)
.header("Cache-Control", "no-cache")
.header("Ocp-Apim-Subscription-Key", &self.primary_key)
.body(transfer.clone());
if let Some(callback_url) = callback_url {
if !callback_url.is_empty() {
req = req.header(
"X-Callback-Url",
format!("{}/disbursement_deposit_v2", callback_url),
);
}
}
let res = req.send().await?;
if res.status().is_success() {
Ok(DepositId::new(transfer.external_id))
} else {
Err(Box::new(std::io::Error::other(res.text().await?)))
}
}
pub async fn get_deposit_status(
&self,
deposit_id: String,
) -> Result<TransferResult, Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let access_token = self.http_client.get_or_create_token().await?;
let res = client
.get(format!(
"{}/disbursement/v1_0/deposit/{}",
self.url, deposit_id
))
.bearer_auth(access_token.access_token)
.header("X-Target-Environment", self.environment.to_string())
.header("Cache-Control", "no-cache")
.header("Ocp-Apim-Subscription-Key", &self.primary_key)
.send()
.await?;
if res.status().is_success() {
let body = res.text().await?;
let transfer_result: TransferResult = serde_json::from_str(&body)?;
Ok(transfer_result)
} else {
Err(Box::new(std::io::Error::other(res.text().await?)))
}
}
pub async fn get_refund_status(
&self,
reference_id: &str,
) -> Result<RefundResult, Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let access_token = self.http_client.get_or_create_token().await?;
let res = client
.get(format!(
"{}/disbursement/v1_0/refund/{}",
self.url, reference_id
))
.bearer_auth(access_token.access_token)
.header("X-Target-Environment", self.environment.to_string())
.header("Cache-Control", "no-cache")
.header("Ocp-Apim-Subscription-Key", &self.primary_key)
.send()
.await?;
if res.status().is_success() {
let body = res.text().await?;
let refund_result: RefundResult = serde_json::from_str(&body)?;
Ok(refund_result)
} else {
Err(Box::new(std::io::Error::other(res.text().await?)))
}
}
pub async fn get_transfer_status(
&self,
transfer_id: &str,
) -> Result<TransferResult, Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let access_token = self.http_client.get_or_create_token().await?;
let res = client
.get(format!(
"{}/disbursement/v1_0/transfer/{}",
self.url, transfer_id
))
.bearer_auth(access_token.access_token)
.header("X-Target-Environment", self.environment.to_string())
.header("Cache-Control", "no-cache")
.header("Ocp-Apim-Subscription-Key", &self.primary_key)
.send()
.await?;
if res.status().is_success() {
let body = res.text().await?;
let transfer_result: TransferResult = serde_json::from_str(&body)?;
Ok(transfer_result)
} else {
Err(Box::new(std::io::Error::other(res.text().await?)))
}
}
pub async fn refund_v1(
&self,
refund: RefundRequest,
callback_url: Option<&str>,
) -> Result<RefundId, Box<dyn std::error::Error>> {
println!("Refund request: {:?}", serde_json::to_string(&refund)?);
let client = reqwest::Client::new();
let refund_id = uuid::Uuid::new_v4().to_string();
let access_token = self.http_client.get_or_create_token().await?;
let mut req = client
.post(format!("{}/disbursement/v1_0/refund", self.url))
.bearer_auth(access_token.access_token)
.header("X-Reference-Id", &refund_id)
.header("X-Target-Environment", self.environment.to_string())
.header("Content-Type", "application/json")
.header("Ocp-Apim-Subscription-Key", &self.primary_key)
.header("Cache-Control", "no-cache")
.body(serde_json::to_string(&refund)?);
if let Some(callback_url) = callback_url {
if !callback_url.is_empty() {
req = req.header(
"x-callback-url",
format!("{}/disbursement_refund_v1", callback_url),
);
}
}
let res = req.send().await?;
println!("Refund response status: {:?}", res);
if res.status().is_success() {
Ok(RefundId::new(refund_id))
} else {
Err(Box::new(std::io::Error::other(res.text().await?)))
}
}
pub async fn refund_v2(
&self,
refund: RefundRequest,
callback_url: Option<&str>,
) -> Result<RefundId, Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let refund_id = uuid::Uuid::new_v4().to_string();
let access_token = self.http_client.get_or_create_token().await?;
let mut req = client
.post(format!("{}/disbursement/v2_0/refund", self.url))
.bearer_auth(access_token.access_token)
.header("X-Reference-Id", &refund_id)
.header("X-Target-Environment", self.environment.to_string())
.header("Content-Type", "application/json")
.header("Ocp-Apim-Subscription-Key", &self.primary_key)
.body(serde_json::to_string(&refund)?);
if let Some(callback_url) = callback_url {
if !callback_url.is_empty() {
req = req.header(
"X-Callback-Url",
format!("{}/disbursement_refund_v2", callback_url),
);
}
}
let res = req.send().await?;
if res.status().is_success() {
Ok(RefundId::new(refund_id))
} else {
Err(Box::new(std::io::Error::other(res.text().await?)))
}
}
pub async fn transfer(
&self,
transfer: TransferRequest,
callback_url: Option<&str>,
) -> Result<TranserId, Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let access_token = self.http_client.get_or_create_token().await?;
let mut req = client
.post(format!("{}/disbursement/v1_0/transfer", self.url))
.bearer_auth(access_token.access_token)
.header("Content-Type", "application/json")
.header("X-Target-Environment", self.environment.to_string())
.header("X-Reference-Id", &transfer.external_id)
.header("Cache-Control", "no-cache")
.header("Ocp-Apim-Subscription-Key", &self.primary_key)
.body(transfer.clone());
if let Some(callback_url) = callback_url {
if !callback_url.is_empty() {
req = req.header(
"X-Callback-Url",
format!("{}/disbursement_transfer", callback_url),
);
}
}
let res = req.send().await?;
if res.status().is_success() {
Ok(TranserId::new(transfer.external_id))
} else {
Err(Box::new(std::io::Error::other(res.text().await?)))
}
}
pub async fn get_account_balance(&self) -> Result<Balance, Box<dyn std::error::Error>> {
let url = format!("{}/disbursement", self.url);
let access_token = self.http_client.get_or_create_token().await?;
self.account
.get_account_balance(
url,
self.environment,
self.primary_key.clone(),
access_token,
)
.await
}
pub async fn get_account_balance_in_specific_currency(
&self,
currency: Currency,
) -> Result<Balance, Box<dyn std::error::Error>> {
let url = format!("{}/disbursement", self.url);
let access_token = self.http_client.get_or_create_token().await?;
self.account
.get_account_balance_in_specific_currency(
url,
self.environment,
self.primary_key.clone(),
currency,
access_token,
)
.await
}
pub async fn get_basic_user_info(
&self,
account_holder_msisdn: &str,
) -> Result<BasicUserInfoJsonResponse, Box<dyn std::error::Error>> {
let url = format!("{}/disbursement", self.url);
let access_token = self.http_client.get_or_create_token().await?;
self.account
.get_basic_user_info(
url,
self.environment,
self.primary_key.clone(),
account_holder_msisdn,
access_token,
)
.await
}
pub async fn get_user_info_with_consent(
&self,
access_token: String,
) -> Result<BasicUserInfoJsonResponse, Box<dyn std::error::Error>> {
let url = format!("{}/disbursement", self.url);
self.account
.get_user_info_with_consent(
url,
self.environment,
self.primary_key.clone(),
access_token,
)
.await
}
pub async fn validate_account_holder_status(
&self,
account_holder_id: &str,
account_holder_type: &str,
) -> Result<(), Box<dyn std::error::Error>> {
let url = format!("{}/disbursement", self.url);
let access_token = self.http_client.get_or_create_token().await?;
self.account
.validate_account_holder_status(
url,
self.environment,
self.primary_key.clone(),
account_holder_id,
account_holder_type,
access_token,
)
.await
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{MomoCollection, Party, PartyIdType, RequestToPay, TransferRequest};
use dotenv::dotenv;
use std::env;
#[tokio::test]
async fn test_get_account_balance() {
dotenv().ok();
let mtn_url = env::var("MTN_URL").expect("MTN_COLLECTION_URL must be set");
let primary_key =
env::var("MTN_DISBURSEMENT_PRIMARY_KEY").expect("PRIMARY_KEY must be set");
let secondary_key =
env::var("MTN_DISBURSEMENT_SECONDARY_KEY").expect("SECONDARY_KEY must be set");
let api_user = env::var("MTN_API_USER").expect("API_USER must be set");
let api_key = env::var("MTN_API_KEY").expect("API_KEY must be set");
let disbursements = Disbursements::new(
mtn_url,
Environment::Sandbox,
api_user,
api_key,
primary_key,
secondary_key,
);
let balance_result = disbursements.get_account_balance().await;
if balance_result.is_ok() {
let balance = balance_result.unwrap();
assert_eq!(balance.currency, Currency::EUR);
}
}
#[tokio::test]
async fn test_get_account_balance_in_specific_currency() {
dotenv().ok();
let mtn_url = env::var("MTN_URL").expect("MTN_COLLECTION_URL must be set");
let primary_key =
env::var("MTN_DISBURSEMENT_PRIMARY_KEY").expect("PRIMARY_KEY must be set");
let secondary_key =
env::var("MTN_DISBURSEMENT_SECONDARY_KEY").expect("SECONDARY_KEY must be set");
let api_user = env::var("MTN_API_USER").expect("API_USER must be set");
let api_key = env::var("MTN_API_KEY").expect("API_KEY must be set");
let disbursements = Disbursements::new(
mtn_url,
Environment::Sandbox,
api_user,
api_key,
primary_key,
secondary_key,
);
let balance_result = disbursements
.get_account_balance_in_specific_currency(Currency::EUR)
.await;
if balance_result.is_ok() {
let balance = balance_result.unwrap();
assert_eq!(balance.currency, Currency::EUR);
}
}
#[tokio::test]
async fn test_get_basic_user_info() {
dotenv().ok();
let mtn_url = env::var("MTN_URL").expect("MTN_COLLECTION_URL must be set");
let primary_key =
env::var("MTN_DISBURSEMENT_PRIMARY_KEY").expect("PRIMARY_KEY must be set");
let secondary_key =
env::var("MTN_DISBURSEMENT_SECONDARY_KEY").expect("SECONDARY_KEY must be set");
let api_user = env::var("MTN_API_USER").expect("API_USER must be set");
let api_key = env::var("MTN_API_KEY").expect("API_KEY must be set");
let disbursements = Disbursements::new(
mtn_url,
Environment::Sandbox,
api_user,
api_key,
primary_key,
secondary_key,
);
let basic_user_info = disbursements
.get_basic_user_info("256774290781")
.await
.unwrap();
assert_ne!(basic_user_info.given_name.len(), 0);
}
#[tokio::test]
async fn test_validate_account_holder_status() {
dotenv().ok();
let mtn_url = env::var("MTN_URL").expect("MTN_COLLECTION_URL must be set");
let primary_key =
env::var("MTN_DISBURSEMENT_PRIMARY_KEY").expect("PRIMARY_KEY must be set");
let secondary_key =
env::var("MTN_DISBURSEMENT_SECONDARY_KEY").expect("SECONDARY_KEY must be set");
let api_user = env::var("MTN_API_USER").expect("API_USER must be set");
let api_key = env::var("MTN_API_KEY").expect("API_KEY must be set");
let disbursements = Disbursements::new(
mtn_url,
Environment::Sandbox,
api_user,
api_key,
primary_key,
secondary_key,
);
let validate_account_holder_status_result = disbursements
.validate_account_holder_status("256774290781", "MSISDN")
.await;
match validate_account_holder_status_result {
Ok(_) => println!("Account validation successful"),
Err(e) => {
println!(
"Account validation failed (this may be expected in test environment): {:?}",
e
);
return;
}
}
}
#[tokio::test]
async fn test_bc_authorize() {
dotenv().ok();
let mtn_url = env::var("MTN_URL").expect("MTN_COLLECTION_URL must be set");
let primary_key =
env::var("MTN_DISBURSEMENT_PRIMARY_KEY").expect("PRIMARY_KEY must be set");
let secondary_key =
env::var("MTN_DISBURSEMENT_SECONDARY_KEY").expect("SECONDARY_KEY must be set");
let api_user = env::var("MTN_API_USER").expect("API_USER must be set");
let api_key = env::var("MTN_API_KEY").expect("API_KEY must be set");
let disbursements = Disbursements::new(
mtn_url,
Environment::Sandbox,
api_user,
api_key,
primary_key,
secondary_key,
);
let bc_authorize_res = disbursements.bc_authorize("563607".to_string(), None).await;
assert!(bc_authorize_res.is_ok());
assert_ne!(bc_authorize_res.unwrap().auth_req_id.len(), 0);
}
#[tokio::test]
async fn test_create_o_auth_2_token() {
dotenv().ok();
let mtn_url = env::var("MTN_URL").expect("MTN_COLLECTION_URL must be set");
let primary_key =
env::var("MTN_DISBURSEMENT_PRIMARY_KEY").expect("PRIMARY_KEY must be set");
let secondary_key =
env::var("MTN_DISBURSEMENT_SECONDARY_KEY").expect("SECONDARY_KEY must be set");
let api_user = env::var("MTN_API_USER").expect("API_USER must be set");
let api_key = env::var("MTN_API_KEY").expect("API_KEY must be set");
let disbursements = Disbursements::new(
mtn_url,
Environment::Sandbox,
api_user,
api_key,
primary_key,
secondary_key,
);
let bc_authorize_res = disbursements.bc_authorize("563607".to_string(), None).await;
assert!(bc_authorize_res.is_ok());
let res = disbursements
.create_o_auth_2_token(bc_authorize_res.unwrap().auth_req_id)
.await
.expect("Error creating o auth 2 token");
assert_ne!(res.access_token.len(), 0);
}
#[tokio::test]
async fn test_get_user_info_with_consent() {
dotenv().ok();
let mtn_url = env::var("MTN_URL").expect("MTN_COLLECTION_URL must be set");
let primary_key =
env::var("MTN_DISBURSEMENT_PRIMARY_KEY").expect("PRIMARY_KEY must be set");
let secondary_key =
env::var("MTN_DISBURSEMENT_SECONDARY_KEY").expect("SECONDARY_KEY must be set");
let api_user = env::var("MTN_API_USER").expect("API_USER must be set");
let api_key = env::var("MTN_API_KEY").expect("API_KEY must be set");
let disbursements = Disbursements::new(
mtn_url,
Environment::Sandbox,
api_user,
api_key,
primary_key,
secondary_key,
);
let bc_authorize_res = disbursements.bc_authorize("563607".to_string(), None).await;
assert!(bc_authorize_res.is_ok());
let res = disbursements
.create_o_auth_2_token(bc_authorize_res.unwrap().auth_req_id)
.await
.expect("Error creating o auth 2 token");
assert_ne!(res.access_token.len(), 0);
let user_info_with_consent = disbursements
.get_user_info_with_consent(res.access_token)
.await
.unwrap();
assert_ne!(user_info_with_consent.family_name.len(), 0);
}
#[tokio::test]
async fn test_deposit_v1() {
dotenv().ok();
let mtn_url = env::var("MTN_URL").expect("MTN_COLLECTION_URL must be set");
let primary_key =
env::var("MTN_DISBURSEMENT_PRIMARY_KEY").expect("PRIMARY_KEY must be set");
let secondary_key =
env::var("MTN_DISBURSEMENT_SECONDARY_KEY").expect("SECONDARY_KEY must be set");
let api_user = env::var("MTN_API_USER").expect("API_USER must be set");
let api_key = env::var("MTN_API_KEY").expect("API_KEY must be set");
let disbursements = Disbursements::new(
mtn_url,
Environment::Sandbox,
api_user,
api_key,
primary_key,
secondary_key,
);
let payee = Party {
party_id_type: PartyIdType::MSISDN,
party_id: "256774290781".to_string(),
};
let transfer = TransferRequest::new(
"100".to_string(),
Currency::EUR,
payee,
"payer_message".to_string(),
"payee_note".to_string(),
);
let result = disbursements.deposit_v1(transfer.clone(), None).await;
assert!(result.is_ok());
assert_eq!(result.unwrap().as_string(), transfer.external_id);
}
#[tokio::test]
async fn test_deposit_v2() {
dotenv().ok();
let mtn_url = env::var("MTN_URL").expect("MTN_COLLECTION_URL must be set");
let primary_key =
env::var("MTN_DISBURSEMENT_PRIMARY_KEY").expect("PRIMARY_KEY must be set");
let secondary_key =
env::var("MTN_DISBURSEMENT_SECONDARY_KEY").expect("SECONDARY_KEY must be set");
let api_user = env::var("MTN_API_USER").expect("API_USER must be set");
let api_key = env::var("MTN_API_KEY").expect("API_KEY must be set");
let disbursements = Disbursements::new(
mtn_url,
Environment::Sandbox,
api_user,
api_key,
primary_key,
secondary_key,
);
let payee = Party {
party_id_type: PartyIdType::MSISDN,
party_id: "256774290781".to_string(),
};
let transfer = TransferRequest::new(
"100".to_string(),
Currency::EUR,
payee,
"payer_message".to_string(),
"payee_note".to_string(),
);
let result = disbursements.deposit_v1(transfer.clone(), None).await;
assert!(result.is_ok());
assert_eq!(result.unwrap().as_string(), transfer.external_id);
}
#[tokio::test]
async fn test_get_deposit_status() {
dotenv().ok();
let mtn_url = env::var("MTN_URL").expect("MTN_COLLECTION_URL must be set");
let primary_key =
env::var("MTN_DISBURSEMENT_PRIMARY_KEY").expect("PRIMARY_KEY must be set");
let secondary_key =
env::var("MTN_DISBURSEMENT_SECONDARY_KEY").expect("SECONDARY_KEY must be set");
let api_user = env::var("MTN_API_USER").expect("API_USER must be set");
let api_key = env::var("MTN_API_KEY").expect("API_KEY must be set");
let disbursements = Disbursements::new(
mtn_url,
Environment::Sandbox,
api_user,
api_key,
primary_key,
secondary_key,
);
let payee = Party {
party_id_type: PartyIdType::MSISDN,
party_id: "256774290781".to_string(),
};
let transfer = TransferRequest::new(
"100".to_string(),
Currency::EUR,
payee,
"payer_message".to_string(),
"payee_note".to_string(),
);
let result = disbursements.deposit_v1(transfer.clone(), None).await;
assert!(result.is_ok());
let status_result = disbursements
.get_deposit_status(result.unwrap().as_string())
.await;
assert!(status_result.is_ok());
}
#[tokio::test]
async fn test_refund_v1() {
dotenv().ok();
let mtn_url = env::var("MTN_URL").expect("MTN_COLLECTION_URL must be set");
let primary_key =
env::var("MTN_DISBURSEMENT_PRIMARY_KEY").expect("PRIMARY_KEY must be set");
let secondary_key =
env::var("MTN_DISBURSEMENT_SECONDARY_KEY").expect("SECONDARY_KEY must be set");
let api_user = env::var("MTN_API_USER").expect("API_USER must be set");
let api_key = env::var("MTN_API_KEY").expect("API_KEY must be set");
let disbursements = Disbursements::new(
mtn_url.clone(),
Environment::Sandbox,
api_user.clone(),
api_key.clone(),
primary_key,
secondary_key,
);
let refund = RefundRequest::new(
"100".to_string(),
Currency::EUR.to_string(),
"payer_message".to_string(),
"payee_note".to_string(),
uuid::Uuid::new_v4().to_string(),
);
let refund_res = disbursements.refund_v1(refund, None).await;
match refund_res {
Ok(id) => {
assert_ne!(id.as_str().len(), 0);
}
Err(e) => {
println!("Refund failed as expected in sandbox: {:?}", e);
}
}
}
#[tokio::test]
async fn test_refund_v2() {
dotenv().ok();
let mtn_url = env::var("MTN_URL").expect("MTN_COLLECTION_URL must be set");
let primary_key =
env::var("MTN_DISBURSEMENT_PRIMARY_KEY").expect("PRIMARY_KEY must be set");
let secondary_key =
env::var("MTN_DISBURSEMENT_SECONDARY_KEY").expect("SECONDARY_KEY must be set");
let api_user = env::var("MTN_API_USER").expect("API_USER must be set");
let api_key = env::var("MTN_API_KEY").expect("API_KEY must be set");
let disbursements = Disbursements::new(
mtn_url.clone(),
Environment::Sandbox,
api_user.clone(),
api_key.clone(),
primary_key,
secondary_key,
);
let refund = RefundRequest::new(
"100".to_string(),
Currency::EUR.to_string(),
"payer_message".to_string(),
"payee_note".to_string(),
uuid::Uuid::new_v4().to_string(),
);
let refund_res = disbursements.refund_v2(refund, None).await;
match refund_res {
Ok(id) => {
assert_ne!(id.as_str().len(), 0);
}
Err(e) => {
println!("Refund failed as expected in sandbox: {:?}", e);
}
}
}
#[tokio::test]
async fn test_get_refund_status() {
dotenv().ok();
let mtn_url = env::var("MTN_URL").expect("MTN_COLLECTION_URL must be set");
let primary_key =
env::var("MTN_DISBURSEMENT_PRIMARY_KEY").expect("PRIMARY_KEY must be set");
let secondary_key =
env::var("MTN_DISBURSEMENT_SECONDARY_KEY").expect("SECONDARY_KEY must be set");
let api_user = env::var("MTN_API_USER").expect("API_USER must be set");
let api_key = env::var("MTN_API_KEY").expect("API_KEY must be set");
let disbursements = Disbursements::new(
mtn_url.clone(),
Environment::Sandbox,
api_user.clone(),
api_key.clone(),
primary_key,
secondary_key,
);
let collection_primary_key =
env::var("MTN_COLLECTION_PRIMARY_KEY").expect("PRIMARY_KEY must be set");
let collection_secondary_key =
env::var("MTN_COLLECTION_SECONDARY_KEY").expect("SECONDARY_KEY must be set");
let collection = MomoCollection::new(
mtn_url,
Environment::Sandbox,
api_user,
api_key,
collection_primary_key,
collection_secondary_key,
);
let payer: Party = Party {
party_id_type: PartyIdType::MSISDN,
party_id: "46733123450".to_string(),
};
let request = RequestToPay::new(
"100".to_string(),
Currency::EUR,
payer,
"test_payer_message".to_string(),
"test_payee_note".to_string(),
);
let res = collection.request_to_pay(request, None).await;
assert!(res.is_ok());
let refund = RefundRequest::new(
"100".to_string(),
Currency::EUR.to_string(),
"payer_message".to_string(),
"payee_note".to_string(),
res.unwrap().as_string(),
);
let refund_res = disbursements.refund_v2(refund, None).await;
match refund_res {
Ok(refund_id) => {
let refund_status_res = disbursements.get_refund_status(refund_id.as_str()).await;
match refund_status_res {
Ok(status) => {
assert_ne!(status.status.len(), 0);
}
Err(e) => {
println!("Refund status check failed as expected in sandbox: {:?}", e);
}
}
}
Err(e) => {
println!("Refund failed as expected in sandbox: {:?}", e);
}
}
}
#[tokio::test]
async fn test_transfer() {
dotenv().ok();
let mtn_url = env::var("MTN_URL").expect("MTN_COLLECTION_URL must be set");
let primary_key =
env::var("MTN_DISBURSEMENT_PRIMARY_KEY").expect("PRIMARY_KEY must be set");
let secondary_key =
env::var("MTN_DISBURSEMENT_SECONDARY_KEY").expect("SECONDARY_KEY must be set");
let api_user = env::var("MTN_API_USER").expect("API_USER must be set");
let api_key = env::var("MTN_API_KEY").expect("API_KEY must be set");
let disbursements = Disbursements::new(
mtn_url,
Environment::Sandbox,
api_user,
api_key,
primary_key,
secondary_key,
);
let transfer = TransferRequest::new(
"100".to_string(),
Currency::EUR,
Party {
party_id_type: PartyIdType::MSISDN,
party_id: "256774290781".to_string(),
},
"payer_message".to_string(),
"payee_note".to_string(),
);
let transfer_result = disbursements.transfer(transfer.clone(), None).await;
assert!(transfer_result.is_ok());
assert_eq!(transfer_result.unwrap().as_string(), transfer.external_id);
}
#[tokio::test]
async fn test_get_transfer_status() {
dotenv().ok();
let mtn_url = env::var("MTN_URL").expect("MTN_COLLECTION_URL must be set");
let primary_key =
env::var("MTN_DISBURSEMENT_PRIMARY_KEY").expect("PRIMARY_KEY must be set");
let secondary_key =
env::var("MTN_DISBURSEMENT_SECONDARY_KEY").expect("SECONDARY_KEY must be set");
let api_user = env::var("MTN_API_USER").expect("API_USER must be set");
let api_key = env::var("MTN_API_KEY").expect("API_KEY must be set");
let disbursements = Disbursements::new(
mtn_url,
Environment::Sandbox,
api_user,
api_key,
primary_key,
secondary_key,
);
let transfer = TransferRequest::new(
"100".to_string(),
Currency::EUR,
Party {
party_id_type: PartyIdType::MSISDN,
party_id: "256774290781".to_string(),
},
"payer_message".to_string(),
"payee_note".to_string(),
);
let transfer_result = disbursements.transfer(transfer.clone(), None).await;
assert!(transfer_result.is_ok());
let status_result = disbursements
.get_transfer_status(transfer_result.unwrap().as_str())
.await;
assert!(status_result.is_ok());
}
}