mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-10-31 10:06:32 +08:00 
			
		
		
		
	feat(router): add refunds manual-update api (#5094)
This commit is contained in:
		 Sai Harsha Vardhan
					Sai Harsha Vardhan
				
			
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			 GitHub
						GitHub
					
				
			
						parent
						
							618ec41aff
						
					
				
				
					commit
					9bc780151c
				
			| @ -1,8 +1,9 @@ | |||||||
| use common_utils::events::{ApiEventMetric, ApiEventsType}; | use common_utils::events::{ApiEventMetric, ApiEventsType}; | ||||||
|  |  | ||||||
| use crate::refunds::{ | use crate::refunds::{ | ||||||
|     RefundListFilters, RefundListMetaData, RefundListRequest, RefundListResponse, RefundRequest, |     RefundListFilters, RefundListMetaData, RefundListRequest, RefundListResponse, | ||||||
|     RefundResponse, RefundUpdateRequest, RefundsRetrieveRequest, |     RefundManualUpdateRequest, RefundRequest, RefundResponse, RefundUpdateRequest, | ||||||
|  |     RefundsRetrieveRequest, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| impl ApiEventMetric for RefundRequest { | 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 { | impl ApiEventMetric for RefundListRequest { | ||||||
|     fn get_api_event_type(&self) -> Option<ApiEventsType> { |     fn get_api_event_type(&self) -> Option<ApiEventsType> { | ||||||
|         Some(ApiEventsType::ResourceListAPI) |         Some(ApiEventsType::ResourceListAPI) | ||||||
|  | |||||||
| @ -97,6 +97,21 @@ pub struct RefundUpdateRequest { | |||||||
|     pub metadata: Option<pii::SecretSerdeValue>, |     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 | /// To indicate whether to refund needs to be instant or scheduled | ||||||
| #[derive( | #[derive( | ||||||
|     Default, Debug, Clone, Copy, ToSchema, Deserialize, Serialize, Eq, PartialEq, strum::Display, |     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>, |         refund_error_code: Option<String>, | ||||||
|         updated_by: 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)] | #[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)] | ||||||
| @ -201,6 +207,18 @@ impl From<RefundUpdate> for RefundUpdateInternal { | |||||||
|                 updated_by, |                 updated_by, | ||||||
|                 ..Default::default() |                 ..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)) |     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)] | #[instrument(skip_all)] | ||||||
| #[cfg(feature = "olap")] | #[cfg(feature = "olap")] | ||||||
| pub async fn get_filters_for_refunds( | pub async fn get_filters_for_refunds( | ||||||
|  | |||||||
| @ -855,7 +855,11 @@ impl Refunds { | |||||||
|             route = route |             route = route | ||||||
|                 .service(web::resource("/list").route(web::post().to(refunds_list))) |                 .service(web::resource("/list").route(web::post().to(refunds_list))) | ||||||
|                 .service(web::resource("/filter").route(web::post().to(refunds_filter_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")] |         #[cfg(feature = "oltp")] | ||||||
|         { |         { | ||||||
|  | |||||||
| @ -143,7 +143,8 @@ impl From<Flow> for ApiIdentifier { | |||||||
|             | Flow::RefundsRetrieveForceSync |             | Flow::RefundsRetrieveForceSync | ||||||
|             | Flow::RefundsUpdate |             | Flow::RefundsUpdate | ||||||
|             | Flow::RefundsList |             | Flow::RefundsList | ||||||
|             | Flow::RefundsFilters => Self::Refunds, |             | Flow::RefundsFilters | ||||||
|  |             | Flow::RefundsManualUpdate => Self::Refunds, | ||||||
|  |  | ||||||
|             Flow::FrmFulfillment |             Flow::FrmFulfillment | ||||||
|             | Flow::IncomingWebhookReceive |             | Flow::IncomingWebhookReceive | ||||||
|  | |||||||
| @ -301,3 +301,26 @@ pub async fn get_refunds_filters(state: web::Data<AppState>, req: HttpRequest) - | |||||||
|     )) |     )) | ||||||
|     .await |     .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, |     ToggleConnectorAgnosticMit, | ||||||
|     /// Get the extended card info associated to a payment_id |     /// Get the extended card info associated to a payment_id | ||||||
|     GetExtendedCardInfo, |     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. |     /// Manually update the payment details like status, error code, error message etc. | ||||||
|     PaymentsManualUpdate, |     PaymentsManualUpdate, | ||||||
| } | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user