mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-10-31 10:06:32 +08:00 
			
		
		
		
	fix(connector): update amount captured after webhook call and parse error responses from connector properly (#1680)
This commit is contained in:
		| @ -262,8 +262,12 @@ impl ConnectorIntegration<api::PSync, types::PaymentsSyncData, types::PaymentsRe | |||||||
|         data: &types::PaymentsSyncRouterData, |         data: &types::PaymentsSyncRouterData, | ||||||
|         res: Response, |         res: Response, | ||||||
|     ) -> CustomResult<types::PaymentsSyncRouterData, errors::ConnectorError> { |     ) -> CustomResult<types::PaymentsSyncRouterData, errors::ConnectorError> { | ||||||
|  |         let response: transformers::CashtocodePaymentsSyncResponse = res | ||||||
|  |             .response | ||||||
|  |             .parse_struct("CashtocodePaymentsSyncResponse") | ||||||
|  |             .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; | ||||||
|         types::RouterData::try_from(types::ResponseRouterData { |         types::RouterData::try_from(types::ResponseRouterData { | ||||||
|             response: cashtocode::CashtocodePaymentsSyncResponse {}, |             response, | ||||||
|             data: data.clone(), |             data: data.clone(), | ||||||
|             http_code: res.status_code, |             http_code: res.status_code, | ||||||
|         }) |         }) | ||||||
| @ -359,9 +363,9 @@ impl api::IncomingWebhook for Cashtocode { | |||||||
|         &self, |         &self, | ||||||
|         request: &api::IncomingWebhookRequestDetails<'_>, |         request: &api::IncomingWebhookRequestDetails<'_>, | ||||||
|     ) -> CustomResult<api_models::webhooks::ObjectReferenceId, errors::ConnectorError> { |     ) -> CustomResult<api_models::webhooks::ObjectReferenceId, errors::ConnectorError> { | ||||||
|         let webhook: transformers::CashtocodeObjectId = request |         let webhook: transformers::CashtocodePaymentsSyncResponse = request | ||||||
|             .body |             .body | ||||||
|             .parse_struct("CashtocodeObjectId") |             .parse_struct("CashtocodePaymentsSyncResponse") | ||||||
|             .change_context(errors::ConnectorError::WebhookReferenceIdNotFound)?; |             .change_context(errors::ConnectorError::WebhookReferenceIdNotFound)?; | ||||||
|  |  | ||||||
|         Ok(api_models::webhooks::ObjectReferenceId::PaymentId( |         Ok(api_models::webhooks::ObjectReferenceId::PaymentId( | ||||||
| @ -397,9 +401,9 @@ impl api::IncomingWebhook for Cashtocode { | |||||||
|     ) -> CustomResult<services::api::ApplicationResponse<serde_json::Value>, errors::ConnectorError> |     ) -> CustomResult<services::api::ApplicationResponse<serde_json::Value>, errors::ConnectorError> | ||||||
|     { |     { | ||||||
|         let status = "EXECUTED".to_string(); |         let status = "EXECUTED".to_string(); | ||||||
|         let obj: transformers::CashtocodeObjectId = request |         let obj: transformers::CashtocodePaymentsSyncResponse = request | ||||||
|             .body |             .body | ||||||
|             .parse_struct("CashtocodeObjectId") |             .parse_struct("CashtocodePaymentsSyncResponse") | ||||||
|             .change_context(errors::ConnectorError::WebhookReferenceIdNotFound)?; |             .change_context(errors::ConnectorError::WebhookReferenceIdNotFound)?; | ||||||
|         let response: serde_json::Value = |         let response: serde_json::Value = | ||||||
|             serde_json::json!({ "status": status, "transactionId" : obj.transaction_id}); |             serde_json::json!({ "status": status, "transactionId" : obj.transaction_id}); | ||||||
|  | |||||||
| @ -123,13 +123,25 @@ pub struct CashtocodeErrors { | |||||||
|     pub event_type: String, |     pub event_type: String, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Clone, Deserialize)] | #[derive(Debug, Deserialize)] | ||||||
|  | #[serde(untagged)] | ||||||
|  | pub enum CashtocodePaymentsResponse { | ||||||
|  |     CashtoCodeError(CashtocodeErrorResponse), | ||||||
|  |     CashtoCodeData(CashtocodePaymentsResponseData), | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[derive(Debug, Deserialize)] | ||||||
| #[serde(rename_all = "camelCase")] | #[serde(rename_all = "camelCase")] | ||||||
| pub struct CashtocodePaymentsResponse { | pub struct CashtocodePaymentsResponseData { | ||||||
|     pub pay_url: String, |     pub pay_url: String, | ||||||
| } | } | ||||||
|  |  | ||||||
| pub struct CashtocodePaymentsSyncResponse {} | #[derive(Debug, Clone, Deserialize)] | ||||||
|  | #[serde(rename_all = "camelCase")] | ||||||
|  | pub struct CashtocodePaymentsSyncResponse { | ||||||
|  |     pub transaction_id: String, | ||||||
|  |     pub amount: i64, | ||||||
|  | } | ||||||
|  |  | ||||||
| impl<F, T> | impl<F, T> | ||||||
|     TryFrom< |     TryFrom< | ||||||
| @ -145,23 +157,41 @@ impl<F, T> | |||||||
|             types::PaymentsResponseData, |             types::PaymentsResponseData, | ||||||
|         >, |         >, | ||||||
|     ) -> Result<Self, Self::Error> { |     ) -> Result<Self, Self::Error> { | ||||||
|         let redirection_data = services::RedirectForm::Form { |         let (status, response) = match item.response { | ||||||
|             endpoint: item.response.pay_url.clone(), |             CashtocodePaymentsResponse::CashtoCodeError(error_data) => ( | ||||||
|             method: services::Method::Post, |                 enums::AttemptStatus::Failure, | ||||||
|             form_fields: Default::default(), |                 Err(types::ErrorResponse { | ||||||
|  |                     code: error_data.error.to_string(), | ||||||
|  |                     status_code: item.http_code, | ||||||
|  |                     message: error_data.error_description, | ||||||
|  |                     reason: None, | ||||||
|  |                 }), | ||||||
|  |             ), | ||||||
|  |             CashtocodePaymentsResponse::CashtoCodeData(response_data) => { | ||||||
|  |                 let redirection_data = services::RedirectForm::Form { | ||||||
|  |                     endpoint: response_data.pay_url, | ||||||
|  |                     method: services::Method::Post, | ||||||
|  |                     form_fields: Default::default(), | ||||||
|  |                 }; | ||||||
|  |                 ( | ||||||
|  |                     enums::AttemptStatus::AuthenticationPending, | ||||||
|  |                     Ok(types::PaymentsResponseData::TransactionResponse { | ||||||
|  |                         resource_id: types::ResponseId::ConnectorTransactionId( | ||||||
|  |                             item.data.attempt_id.clone(), | ||||||
|  |                         ), | ||||||
|  |                         redirection_data: Some(redirection_data), | ||||||
|  |                         mandate_reference: None, | ||||||
|  |                         connector_metadata: None, | ||||||
|  |                         network_txn_id: None, | ||||||
|  |                         connector_response_reference_id: None, | ||||||
|  |                     }), | ||||||
|  |                 ) | ||||||
|  |             } | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         Ok(Self { |         Ok(Self { | ||||||
|             status: enums::AttemptStatus::AuthenticationPending, |             status, | ||||||
|             response: Ok(types::PaymentsResponseData::TransactionResponse { |             response, | ||||||
|                 resource_id: types::ResponseId::ConnectorTransactionId( |  | ||||||
|                     item.data.attempt_id.clone(), |  | ||||||
|                 ), |  | ||||||
|                 redirection_data: Some(redirection_data), |  | ||||||
|                 mandate_reference: None, |  | ||||||
|                 connector_metadata: None, |  | ||||||
|                 network_txn_id: None, |  | ||||||
|                 connector_response_reference_id: None, |  | ||||||
|             }), |  | ||||||
|             ..item.data |             ..item.data | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| @ -198,6 +228,7 @@ impl<F, T> | |||||||
|                 network_txn_id: None, |                 network_txn_id: None, | ||||||
|                 connector_response_reference_id: None, |                 connector_response_reference_id: None, | ||||||
|             }), |             }), | ||||||
|  |             amount_captured: Some(item.response.amount), | ||||||
|             ..item.data |             ..item.data | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| @ -205,7 +236,7 @@ impl<F, T> | |||||||
|  |  | ||||||
| #[derive(Debug, Deserialize)] | #[derive(Debug, Deserialize)] | ||||||
| pub struct CashtocodeErrorResponse { | pub struct CashtocodeErrorResponse { | ||||||
|     pub error: String, |     pub error: u32, | ||||||
|     pub error_description: String, |     pub error_description: String, | ||||||
|     pub errors: Option<Vec<CashtocodeErrors>>, |     pub errors: Option<Vec<CashtocodeErrors>>, | ||||||
| } | } | ||||||
| @ -220,9 +251,3 @@ pub struct CashtocodeIncomingWebhook { | |||||||
|     pub event_type: String, |     pub event_type: String, | ||||||
|     pub transaction_id: String, |     pub transaction_id: String, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Clone, Deserialize)] |  | ||||||
| #[serde(rename_all = "camelCase")] |  | ||||||
| pub struct CashtocodeObjectId { |  | ||||||
|     pub transaction_id: String, |  | ||||||
| } |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 BallaNitesh
					BallaNitesh