mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 09:07:09 +08:00
feat(router): add refunds manual-update api (#5094)
This commit is contained in:
committed by
GitHub
parent
618ec41aff
commit
9bc780151c
@ -1,8 +1,9 @@
|
||||
use common_utils::events::{ApiEventMetric, ApiEventsType};
|
||||
|
||||
use crate::refunds::{
|
||||
RefundListFilters, RefundListMetaData, RefundListRequest, RefundListResponse, RefundRequest,
|
||||
RefundResponse, RefundUpdateRequest, RefundsRetrieveRequest,
|
||||
RefundListFilters, RefundListMetaData, RefundListRequest, RefundListResponse,
|
||||
RefundManualUpdateRequest, RefundRequest, RefundResponse, RefundUpdateRequest,
|
||||
RefundsRetrieveRequest,
|
||||
};
|
||||
|
||||
impl ApiEventMetric for RefundRequest {
|
||||
@ -44,6 +45,15 @@ impl ApiEventMetric for RefundUpdateRequest {
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for RefundManualUpdateRequest {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Refund {
|
||||
payment_id: None,
|
||||
refund_id: self.refund_id.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for RefundListRequest {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::ResourceListAPI)
|
||||
|
||||
@ -97,6 +97,21 @@ pub struct RefundUpdateRequest {
|
||||
pub metadata: Option<pii::SecretSerdeValue>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, ToSchema, Clone, Deserialize, Serialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct RefundManualUpdateRequest {
|
||||
#[serde(skip)]
|
||||
pub refund_id: String,
|
||||
/// Merchant ID
|
||||
pub merchant_id: String,
|
||||
/// The status for refund
|
||||
pub status: Option<RefundStatus>,
|
||||
/// The code for the error
|
||||
pub error_code: Option<String>,
|
||||
/// The error message
|
||||
pub error_message: Option<String>,
|
||||
}
|
||||
|
||||
/// To indicate whether to refund needs to be instant or scheduled
|
||||
#[derive(
|
||||
Default, Debug, Clone, Copy, ToSchema, Deserialize, Serialize, Eq, PartialEq, strum::Display,
|
||||
@ -244,3 +259,14 @@ impl From<enums::RefundStatus> for RefundStatus {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RefundStatus> for enums::RefundStatus {
|
||||
fn from(status: RefundStatus) -> Self {
|
||||
match status {
|
||||
RefundStatus::Failed => Self::Failure,
|
||||
RefundStatus::Review => Self::ManualReview,
|
||||
RefundStatus::Pending => Self::Pending,
|
||||
RefundStatus::Succeeded => Self::Success,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,6 +115,12 @@ pub enum RefundUpdate {
|
||||
refund_error_code: Option<String>,
|
||||
updated_by: String,
|
||||
},
|
||||
ManualUpdate {
|
||||
refund_status: Option<storage_enums::RefundStatus>,
|
||||
refund_error_message: Option<String>,
|
||||
refund_error_code: Option<String>,
|
||||
updated_by: String,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)]
|
||||
@ -201,6 +207,18 @@ impl From<RefundUpdate> for RefundUpdateInternal {
|
||||
updated_by,
|
||||
..Default::default()
|
||||
},
|
||||
RefundUpdate::ManualUpdate {
|
||||
refund_status,
|
||||
refund_error_message,
|
||||
refund_error_code,
|
||||
updated_by,
|
||||
} => Self {
|
||||
refund_status,
|
||||
refund_error_message,
|
||||
refund_error_code,
|
||||
updated_by,
|
||||
..Default::default()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -836,6 +836,60 @@ pub async fn refund_filter_list(
|
||||
Ok(services::ApplicationResponse::Json(filter_list))
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
#[cfg(feature = "olap")]
|
||||
pub async fn refund_manual_update(
|
||||
state: SessionState,
|
||||
req: api_models::refunds::RefundManualUpdateRequest,
|
||||
) -> RouterResponse<serde_json::Value> {
|
||||
let key_store = state
|
||||
.store
|
||||
.get_merchant_key_store_by_merchant_id(
|
||||
&req.merchant_id,
|
||||
&state.store.get_master_key().to_vec().into(),
|
||||
)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)
|
||||
.attach_printable("Error while fetching the key store by merchant_id")?;
|
||||
let merchant_account = state
|
||||
.store
|
||||
.find_merchant_account_by_merchant_id(&req.merchant_id, &key_store)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)
|
||||
.attach_printable("Error while fetching the merchant_account by merchant_id")?;
|
||||
let refund = state
|
||||
.store
|
||||
.find_refund_by_merchant_id_refund_id(
|
||||
&merchant_account.merchant_id,
|
||||
&req.refund_id,
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::RefundNotFound)?;
|
||||
let refund_update = storage::RefundUpdate::ManualUpdate {
|
||||
refund_status: req.status.map(common_enums::RefundStatus::from),
|
||||
refund_error_message: req.error_message,
|
||||
refund_error_code: req.error_code,
|
||||
updated_by: merchant_account.storage_scheme.to_string(),
|
||||
};
|
||||
state
|
||||
.store
|
||||
.update_refund(
|
||||
refund.to_owned(),
|
||||
refund_update,
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable_lazy(|| {
|
||||
format!(
|
||||
"Failed while updating refund: refund_id: {}",
|
||||
refund.refund_id
|
||||
)
|
||||
})?;
|
||||
Ok(services::ApplicationResponse::StatusOk)
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
#[cfg(feature = "olap")]
|
||||
pub async fn get_filters_for_refunds(
|
||||
|
||||
@ -855,7 +855,11 @@ impl Refunds {
|
||||
route = route
|
||||
.service(web::resource("/list").route(web::post().to(refunds_list)))
|
||||
.service(web::resource("/filter").route(web::post().to(refunds_filter_list)))
|
||||
.service(web::resource("/v2/filter").route(web::get().to(get_refunds_filters)));
|
||||
.service(web::resource("/v2/filter").route(web::get().to(get_refunds_filters)))
|
||||
.service(
|
||||
web::resource("/{id}/manual-update")
|
||||
.route(web::put().to(refunds_manual_update)),
|
||||
);
|
||||
}
|
||||
#[cfg(feature = "oltp")]
|
||||
{
|
||||
|
||||
@ -143,7 +143,8 @@ impl From<Flow> for ApiIdentifier {
|
||||
| Flow::RefundsRetrieveForceSync
|
||||
| Flow::RefundsUpdate
|
||||
| Flow::RefundsList
|
||||
| Flow::RefundsFilters => Self::Refunds,
|
||||
| Flow::RefundsFilters
|
||||
| Flow::RefundsManualUpdate => Self::Refunds,
|
||||
|
||||
Flow::FrmFulfillment
|
||||
| Flow::IncomingWebhookReceive
|
||||
|
||||
@ -301,3 +301,26 @@ pub async fn get_refunds_filters(state: web::Data<AppState>, req: HttpRequest) -
|
||||
))
|
||||
.await
|
||||
}
|
||||
|
||||
#[instrument(skip_all, fields(flow = ?Flow::RefundsManualUpdate))]
|
||||
#[cfg(feature = "olap")]
|
||||
pub async fn refunds_manual_update(
|
||||
state: web::Data<AppState>,
|
||||
req: HttpRequest,
|
||||
payload: web::Json<api_models::refunds::RefundManualUpdateRequest>,
|
||||
path: web::Path<String>,
|
||||
) -> HttpResponse {
|
||||
let flow = Flow::RefundsManualUpdate;
|
||||
let mut refund_manual_update_req = payload.into_inner();
|
||||
refund_manual_update_req.refund_id = path.into_inner();
|
||||
Box::pin(api::server_wrap(
|
||||
flow,
|
||||
state,
|
||||
&req,
|
||||
refund_manual_update_req,
|
||||
|state, _auth, req, _| refund_manual_update(state, req),
|
||||
&auth::AdminApiAuth,
|
||||
api_locking::LockAction::NotApplicable,
|
||||
))
|
||||
.await
|
||||
}
|
||||
|
||||
@ -452,6 +452,8 @@ pub enum Flow {
|
||||
ToggleConnectorAgnosticMit,
|
||||
/// Get the extended card info associated to a payment_id
|
||||
GetExtendedCardInfo,
|
||||
/// Manually update the refund details like status, error code, error message etc.
|
||||
RefundsManualUpdate,
|
||||
/// Manually update the payment details like status, error code, error message etc.
|
||||
PaymentsManualUpdate,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user