mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-10-31 01:57:45 +08:00 
			
		
		
		
	feat(router): add retrieve dispute evidence API (#1114)
This commit is contained in:
		 Sai Harsha Vardhan
					Sai Harsha Vardhan
				
			
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			 GitHub
						GitHub
					
				
			
						parent
						
							9f47f20702
						
					
				
				
					commit
					354ee0137a
				
			| @ -378,3 +378,27 @@ pub async fn attach_evidence( | ||||
|         })?; | ||||
|     Ok(create_file_response) | ||||
| } | ||||
|  | ||||
| #[instrument(skip(state))] | ||||
| pub async fn retrieve_dispute_evidence( | ||||
|     state: &AppState, | ||||
|     merchant_account: storage::MerchantAccount, | ||||
|     req: disputes::DisputeId, | ||||
| ) -> RouterResponse<Vec<api_models::disputes::DisputeEvidenceBlock>> { | ||||
|     let dispute = state | ||||
|         .store | ||||
|         .find_dispute_by_merchant_id_dispute_id(&merchant_account.merchant_id, &req.dispute_id) | ||||
|         .await | ||||
|         .to_not_found_response(errors::ApiErrorResponse::DisputeNotFound { | ||||
|             dispute_id: req.dispute_id, | ||||
|         })?; | ||||
|     let dispute_evidence: api::DisputeEvidence = dispute | ||||
|         .evidence | ||||
|         .clone() | ||||
|         .parse_value("DisputeEvidence") | ||||
|         .change_context(errors::ApiErrorResponse::InternalServerError) | ||||
|         .attach_printable("Error while parsing dispute evidence record")?; | ||||
|     let dispute_evidence_vec = | ||||
|         transformers::get_dispute_evidence_vec(state, merchant_account, dispute_evidence).await?; | ||||
|     Ok(services::ApplicationResponse::Json(dispute_evidence_vec)) | ||||
| } | ||||
|  | ||||
| @ -1,10 +1,14 @@ | ||||
| use api_models::disputes::EvidenceType; | ||||
| use common_utils::errors::CustomResult; | ||||
| use error_stack::ResultExt; | ||||
|  | ||||
| use crate::{ | ||||
|     core::{errors, files::helpers::retrieve_file_and_provider_file_id_from_file_id}, | ||||
|     routes::AppState, | ||||
|     types::{ | ||||
|         api::{self, DisputeEvidence}, | ||||
|         storage, | ||||
|         transformers::ForeignFrom, | ||||
|         SubmitEvidenceRequestData, | ||||
|     }, | ||||
| }; | ||||
| @ -186,3 +190,146 @@ pub fn update_dispute_evidence( | ||||
|         }, | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub async fn get_dispute_evidence_block( | ||||
|     state: &AppState, | ||||
|     merchant_account: &storage::MerchantAccount, | ||||
|     evidence_type: EvidenceType, | ||||
|     file_id: String, | ||||
| ) -> CustomResult<api_models::disputes::DisputeEvidenceBlock, errors::ApiErrorResponse> { | ||||
|     let file_metadata = state | ||||
|         .store | ||||
|         .find_file_metadata_by_merchant_id_file_id(&merchant_account.merchant_id, &file_id) | ||||
|         .await | ||||
|         .change_context(errors::ApiErrorResponse::FileNotFound) | ||||
|         .attach_printable("Unable to retrieve file_metadata")?; | ||||
|     let file_metadata_response = | ||||
|         api_models::files::FileMetadataResponse::foreign_from(file_metadata); | ||||
|     Ok(api_models::disputes::DisputeEvidenceBlock { | ||||
|         evidence_type, | ||||
|         file_metadata_response, | ||||
|     }) | ||||
| } | ||||
|  | ||||
| pub async fn get_dispute_evidence_vec( | ||||
|     state: &AppState, | ||||
|     merchant_account: storage::MerchantAccount, | ||||
|     dispute_evidence: DisputeEvidence, | ||||
| ) -> CustomResult<Vec<api_models::disputes::DisputeEvidenceBlock>, errors::ApiErrorResponse> { | ||||
|     let mut dispute_evidence_blocks: Vec<api_models::disputes::DisputeEvidenceBlock> = vec![]; | ||||
|     if let Some(cancellation_policy_block) = dispute_evidence.cancellation_policy { | ||||
|         dispute_evidence_blocks.push( | ||||
|             get_dispute_evidence_block( | ||||
|                 state, | ||||
|                 &merchant_account, | ||||
|                 EvidenceType::CancellationPolicy, | ||||
|                 cancellation_policy_block, | ||||
|             ) | ||||
|             .await?, | ||||
|         ) | ||||
|     } | ||||
|     if let Some(customer_communication_block) = dispute_evidence.customer_communication { | ||||
|         dispute_evidence_blocks.push( | ||||
|             get_dispute_evidence_block( | ||||
|                 state, | ||||
|                 &merchant_account, | ||||
|                 EvidenceType::CustomerCommunication, | ||||
|                 customer_communication_block, | ||||
|             ) | ||||
|             .await?, | ||||
|         ) | ||||
|     } | ||||
|     if let Some(customer_signature_block) = dispute_evidence.customer_signature { | ||||
|         dispute_evidence_blocks.push( | ||||
|             get_dispute_evidence_block( | ||||
|                 state, | ||||
|                 &merchant_account, | ||||
|                 EvidenceType::CustomerSignature, | ||||
|                 customer_signature_block, | ||||
|             ) | ||||
|             .await?, | ||||
|         ) | ||||
|     } | ||||
|     if let Some(receipt_block) = dispute_evidence.receipt { | ||||
|         dispute_evidence_blocks.push( | ||||
|             get_dispute_evidence_block( | ||||
|                 state, | ||||
|                 &merchant_account, | ||||
|                 EvidenceType::Receipt, | ||||
|                 receipt_block, | ||||
|             ) | ||||
|             .await?, | ||||
|         ) | ||||
|     } | ||||
|     if let Some(refund_policy_block) = dispute_evidence.refund_policy { | ||||
|         dispute_evidence_blocks.push( | ||||
|             get_dispute_evidence_block( | ||||
|                 state, | ||||
|                 &merchant_account, | ||||
|                 EvidenceType::RefundPolicy, | ||||
|                 refund_policy_block, | ||||
|             ) | ||||
|             .await?, | ||||
|         ) | ||||
|     } | ||||
|     if let Some(service_documentation_block) = dispute_evidence.service_documentation { | ||||
|         dispute_evidence_blocks.push( | ||||
|             get_dispute_evidence_block( | ||||
|                 state, | ||||
|                 &merchant_account, | ||||
|                 EvidenceType::ServiceDocumentation, | ||||
|                 service_documentation_block, | ||||
|             ) | ||||
|             .await?, | ||||
|         ) | ||||
|     } | ||||
|     if let Some(shipping_documentation_block) = dispute_evidence.shipping_documentation { | ||||
|         dispute_evidence_blocks.push( | ||||
|             get_dispute_evidence_block( | ||||
|                 state, | ||||
|                 &merchant_account, | ||||
|                 EvidenceType::ShippingDocumentation, | ||||
|                 shipping_documentation_block, | ||||
|             ) | ||||
|             .await?, | ||||
|         ) | ||||
|     } | ||||
|     if let Some(invoice_showing_distinct_transactions_block) = | ||||
|         dispute_evidence.invoice_showing_distinct_transactions | ||||
|     { | ||||
|         dispute_evidence_blocks.push( | ||||
|             get_dispute_evidence_block( | ||||
|                 state, | ||||
|                 &merchant_account, | ||||
|                 EvidenceType::InvoiceShowingDistinctTransactions, | ||||
|                 invoice_showing_distinct_transactions_block, | ||||
|             ) | ||||
|             .await?, | ||||
|         ) | ||||
|     } | ||||
|     if let Some(recurring_transaction_agreement_block) = | ||||
|         dispute_evidence.recurring_transaction_agreement | ||||
|     { | ||||
|         dispute_evidence_blocks.push( | ||||
|             get_dispute_evidence_block( | ||||
|                 state, | ||||
|                 &merchant_account, | ||||
|                 EvidenceType::RecurringTransactionAgreement, | ||||
|                 recurring_transaction_agreement_block, | ||||
|             ) | ||||
|             .await?, | ||||
|         ) | ||||
|     } | ||||
|     if let Some(uncategorized_file_block) = dispute_evidence.uncategorized_file { | ||||
|         dispute_evidence_blocks.push( | ||||
|             get_dispute_evidence_block( | ||||
|                 state, | ||||
|                 &merchant_account, | ||||
|                 EvidenceType::UncategorizedFile, | ||||
|                 uncategorized_file_block, | ||||
|             ) | ||||
|             .await?, | ||||
|         ) | ||||
|     } | ||||
|     Ok(dispute_evidence_blocks) | ||||
| } | ||||
|  | ||||
| @ -430,6 +430,10 @@ impl Disputes { | ||||
|                     .route(web::post().to(submit_dispute_evidence)) | ||||
|                     .route(web::put().to(attach_dispute_evidence)), | ||||
|             ) | ||||
|             .service( | ||||
|                 web::resource("/evidence/{dispute_id}") | ||||
|                     .route(web::get().to(retrieve_dispute_evidence)), | ||||
|             ) | ||||
|             .service(web::resource("/{dispute_id}").route(web::get().to(retrieve_dispute))) | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -195,3 +195,39 @@ pub async fn attach_dispute_evidence( | ||||
|     ) | ||||
|     .await | ||||
| } | ||||
|  | ||||
| /// Diputes - Retrieve Dispute | ||||
| #[utoipa::path( | ||||
|     get, | ||||
|     path = "/disputes/evidence/{dispute_id}", | ||||
|     params( | ||||
|         ("dispute_id" = String, Path, description = "The identifier for dispute") | ||||
|     ), | ||||
|     responses( | ||||
|         (status = 200, description = "The dispute evidence was retrieved successfully", body = DisputeResponse), | ||||
|         (status = 404, description = "Dispute does not exist in our records") | ||||
|     ), | ||||
|     tag = "Disputes", | ||||
|     operation_id = "Retrieve a Dispute Evidence", | ||||
|     security(("api_key" = [])) | ||||
| )] | ||||
| #[instrument(skip_all, fields(flow = ?Flow::RetrieveDisputeEvidence))] | ||||
| pub async fn retrieve_dispute_evidence( | ||||
|     state: web::Data<AppState>, | ||||
|     req: HttpRequest, | ||||
|     path: web::Path<String>, | ||||
| ) -> HttpResponse { | ||||
|     let flow = Flow::RetrieveDisputeEvidence; | ||||
|     let dispute_id = dispute_types::DisputeId { | ||||
|         dispute_id: path.into_inner(), | ||||
|     }; | ||||
|     api::server_wrap( | ||||
|         flow, | ||||
|         state.get_ref(), | ||||
|         &req, | ||||
|         dispute_id, | ||||
|         disputes::retrieve_dispute_evidence, | ||||
|         auth::auth_type(&auth::ApiKeyAuth, &auth::JWTAuth, req.headers()), | ||||
|     ) | ||||
|     .await | ||||
| } | ||||
|  | ||||
| @ -526,6 +526,18 @@ impl ForeignFrom<storage::Dispute> for api_models::disputes::DisputeResponsePaym | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl ForeignFrom<storage::FileMetadata> for api_models::files::FileMetadataResponse { | ||||
|     fn foreign_from(file_metadata: storage::FileMetadata) -> Self { | ||||
|         Self { | ||||
|             file_id: file_metadata.file_id, | ||||
|             file_name: file_metadata.file_name, | ||||
|             file_size: file_metadata.file_size, | ||||
|             file_type: file_metadata.file_type, | ||||
|             available: file_metadata.available, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl ForeignFrom<storage_models::cards_info::CardInfo> | ||||
|     for api_models::cards_info::CardInfoResponse | ||||
| { | ||||
|  | ||||
		Reference in New Issue
	
	Block a user