use serde::{Deserialize, Serialize};
use crate::client::Mpesa;
use crate::constants::ResponseType;
use crate::environment::ApiEnvironment;
use crate::errors::{MpesaError, MpesaResult};
#[derive(Debug, Serialize)]
struct C2bRegisterPayload<'mpesa> {
#[serde(rename(serialize = "ValidationURL"))]
validation_url: &'mpesa str,
#[serde(rename(serialize = "ConfirmationURL"))]
confirmation_url: &'mpesa str,
#[serde(rename(serialize = "ResponseType"))]
response_type: ResponseType,
#[serde(rename(serialize = "ShortCode"))]
short_code: &'mpesa str,
}
#[derive(Debug, Deserialize, Clone)]
pub struct C2bRegisterResponse {
#[serde(rename(deserialize = "OriginatorConverstionID"))]
pub originator_conversation_id: String,
#[serde(rename(deserialize = "ResponseCode"))]
pub response_code: String,
#[serde(rename(deserialize = "ResponseDescription"))]
pub response_description: String,
}
#[derive(Debug)]
pub struct C2bRegisterBuilder<'mpesa, Env: ApiEnvironment> {
client: &'mpesa Mpesa<Env>,
validation_url: Option<&'mpesa str>,
confirmation_url: Option<&'mpesa str>,
response_type: Option<ResponseType>,
short_code: Option<&'mpesa str>,
}
impl<'mpesa, Env: ApiEnvironment> C2bRegisterBuilder<'mpesa, Env> {
pub fn new(client: &'mpesa Mpesa<Env>) -> C2bRegisterBuilder<'mpesa, Env> {
C2bRegisterBuilder {
client,
validation_url: None,
confirmation_url: None,
response_type: None,
short_code: None,
}
}
pub fn validation_url(
mut self,
validation_url: &'mpesa str,
) -> C2bRegisterBuilder<'mpesa, Env> {
self.validation_url = Some(validation_url);
self
}
pub fn confirmation_url(
mut self,
confirmation_url: &'mpesa str,
) -> C2bRegisterBuilder<'mpesa, Env> {
self.confirmation_url = Some(confirmation_url);
self
}
pub fn response_type(mut self, response_type: ResponseType) -> C2bRegisterBuilder<'mpesa, Env> {
self.response_type = Some(response_type);
self
}
pub fn short_code(mut self, short_code: &'mpesa str) -> C2bRegisterBuilder<'mpesa, Env> {
self.short_code = Some(short_code);
self
}
#[allow(clippy::unnecessary_lazy_evaluations)]
pub async fn send(self) -> MpesaResult<C2bRegisterResponse> {
let url = format!(
"{}/mpesa/c2b/v1/registerurl",
self.client.environment.base_url()
);
let payload = C2bRegisterPayload {
validation_url: self
.validation_url
.ok_or(MpesaError::Message("validation_url is required"))?,
confirmation_url: self
.confirmation_url
.ok_or(MpesaError::Message("confirmation_url is required"))?,
response_type: self
.response_type
.unwrap_or_else(|| ResponseType::Completed),
short_code: self
.short_code
.ok_or(MpesaError::Message("short_code is required"))?,
};
let response = self
.client
.http_client
.post(&url)
.bearer_auth(self.client.auth().await?)
.json(&payload)
.send()
.await?;
if response.status().is_success() {
let value = response.json::<_>().await?;
return Ok(value);
}
let value = response.json().await?;
Err(MpesaError::C2bRegisterError(value))
}
}