mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-10-31 10:06:32 +08:00 
			
		
		
		
	feat(connector): [FISERVEMEA] Add template code (#5583)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
		| @ -205,6 +205,7 @@ dlocal.base_url = "https://sandbox.dlocal.com/" | |||||||
| dummyconnector.base_url = "http://localhost:8080/dummy-connector" | dummyconnector.base_url = "http://localhost:8080/dummy-connector" | ||||||
| ebanx.base_url = "https://sandbox.ebanxpay.com/" | ebanx.base_url = "https://sandbox.ebanxpay.com/" | ||||||
| fiserv.base_url = "https://cert.api.fiservapps.com/" | fiserv.base_url = "https://cert.api.fiservapps.com/" | ||||||
|  | fiservemea.base_url = "https://prod.emea.api.fiservapps.com/sandbox/ipp/payments-gateway/v2" | ||||||
| forte.base_url = "https://sandbox.forte.net/api/v3" | forte.base_url = "https://sandbox.forte.net/api/v3" | ||||||
| globalpay.base_url = "https://apis.sandbox.globalpay.com/ucp/" | globalpay.base_url = "https://apis.sandbox.globalpay.com/ucp/" | ||||||
| globepay.base_url = "https://pay.globepay.co/" | globepay.base_url = "https://pay.globepay.co/" | ||||||
|  | |||||||
| @ -45,6 +45,7 @@ dlocal.base_url = "https://sandbox.dlocal.com/" | |||||||
| dummyconnector.base_url = "http://localhost:8080/dummy-connector" | dummyconnector.base_url = "http://localhost:8080/dummy-connector" | ||||||
| ebanx.base_url = "https://sandbox.ebanxpay.com/" | ebanx.base_url = "https://sandbox.ebanxpay.com/" | ||||||
| fiserv.base_url = "https://cert.api.fiservapps.com/" | fiserv.base_url = "https://cert.api.fiservapps.com/" | ||||||
|  | fiservemea.base_url = "https://prod.emea.api.fiservapps.com/sandbox/ipp/payments-gateway/v2" | ||||||
| forte.base_url = "https://sandbox.forte.net/api/v3" | forte.base_url = "https://sandbox.forte.net/api/v3" | ||||||
| globalpay.base_url = "https://apis.sandbox.globalpay.com/ucp/" | globalpay.base_url = "https://apis.sandbox.globalpay.com/ucp/" | ||||||
| globepay.base_url = "https://pay.globepay.co/" | globepay.base_url = "https://pay.globepay.co/" | ||||||
|  | |||||||
| @ -49,6 +49,7 @@ dlocal.base_url = "https://sandbox.dlocal.com/" | |||||||
| dummyconnector.base_url = "http://localhost:8080/dummy-connector" | dummyconnector.base_url = "http://localhost:8080/dummy-connector" | ||||||
| ebanx.base_url = "https://sandbox.ebanxpay.com/" | ebanx.base_url = "https://sandbox.ebanxpay.com/" | ||||||
| fiserv.base_url = "https://cert.api.fiservapps.com/" | fiserv.base_url = "https://cert.api.fiservapps.com/" | ||||||
|  | fiservemea.base_url = "https://prod.emea.api.fiservapps.com/ipp/payments-gateway/v2" | ||||||
| forte.base_url = "https://sandbox.forte.net/api/v3" | forte.base_url = "https://sandbox.forte.net/api/v3" | ||||||
| globalpay.base_url = "https://apis.sandbox.globalpay.com/ucp/" | globalpay.base_url = "https://apis.sandbox.globalpay.com/ucp/" | ||||||
| globepay.base_url = "https://pay.globepay.co/" | globepay.base_url = "https://pay.globepay.co/" | ||||||
|  | |||||||
| @ -49,6 +49,7 @@ dlocal.base_url = "https://sandbox.dlocal.com/" | |||||||
| dummyconnector.base_url = "http://localhost:8080/dummy-connector" | dummyconnector.base_url = "http://localhost:8080/dummy-connector" | ||||||
| ebanx.base_url = "https://sandbox.ebanxpay.com/" | ebanx.base_url = "https://sandbox.ebanxpay.com/" | ||||||
| fiserv.base_url = "https://cert.api.fiservapps.com/" | fiserv.base_url = "https://cert.api.fiservapps.com/" | ||||||
|  | fiservemea.base_url = "https://prod.emea.api.fiservapps.com/sandbox/ipp/payments-gateway/v2" | ||||||
| forte.base_url = "https://sandbox.forte.net/api/v3" | forte.base_url = "https://sandbox.forte.net/api/v3" | ||||||
| globalpay.base_url = "https://apis.sandbox.globalpay.com/ucp/" | globalpay.base_url = "https://apis.sandbox.globalpay.com/ucp/" | ||||||
| globepay.base_url = "https://pay.globepay.co/" | globepay.base_url = "https://pay.globepay.co/" | ||||||
|  | |||||||
| @ -118,6 +118,7 @@ cards = [ | |||||||
|     "dummyconnector", |     "dummyconnector", | ||||||
|     "ebanx", |     "ebanx", | ||||||
|     "fiserv", |     "fiserv", | ||||||
|  |     "fiservemea", | ||||||
|     "forte", |     "forte", | ||||||
|     "globalpay", |     "globalpay", | ||||||
|     "globepay", |     "globepay", | ||||||
| @ -207,6 +208,7 @@ dlocal.base_url = "https://sandbox.dlocal.com/" | |||||||
| dummyconnector.base_url = "http://localhost:8080/dummy-connector" | dummyconnector.base_url = "http://localhost:8080/dummy-connector" | ||||||
| ebanx.base_url = "https://sandbox.ebanxpay.com/" | ebanx.base_url = "https://sandbox.ebanxpay.com/" | ||||||
| fiserv.base_url = "https://cert.api.fiservapps.com/" | fiserv.base_url = "https://cert.api.fiservapps.com/" | ||||||
|  | fiservemea.base_url = "https://prod.emea.api.fiservapps.com/sandbox/ipp/payments-gateway/v2" | ||||||
| forte.base_url = "https://sandbox.forte.net/api/v3" | forte.base_url = "https://sandbox.forte.net/api/v3" | ||||||
| globalpay.base_url = "https://apis.sandbox.globalpay.com/ucp/" | globalpay.base_url = "https://apis.sandbox.globalpay.com/ucp/" | ||||||
| globepay.base_url = "https://pay.globepay.co/" | globepay.base_url = "https://pay.globepay.co/" | ||||||
|  | |||||||
| @ -134,6 +134,7 @@ dlocal.base_url = "https://sandbox.dlocal.com/" | |||||||
| dummyconnector.base_url = "http://localhost:8080/dummy-connector" | dummyconnector.base_url = "http://localhost:8080/dummy-connector" | ||||||
| ebanx.base_url = "https://sandbox.ebanxpay.com/" | ebanx.base_url = "https://sandbox.ebanxpay.com/" | ||||||
| fiserv.base_url = "https://cert.api.fiservapps.com/" | fiserv.base_url = "https://cert.api.fiservapps.com/" | ||||||
|  | fiservemea.base_url = "https://prod.emea.api.fiservapps.com/sandbox/ipp/payments-gateway/v2" | ||||||
| forte.base_url = "https://sandbox.forte.net/api/v3" | forte.base_url = "https://sandbox.forte.net/api/v3" | ||||||
| globalpay.base_url = "https://apis.sandbox.globalpay.com/ucp/" | globalpay.base_url = "https://apis.sandbox.globalpay.com/ucp/" | ||||||
| globepay.base_url = "https://pay.globepay.co/" | globepay.base_url = "https://pay.globepay.co/" | ||||||
| @ -219,6 +220,7 @@ cards = [ | |||||||
|     "dummyconnector", |     "dummyconnector", | ||||||
|     "ebanx", |     "ebanx", | ||||||
|     "fiserv", |     "fiserv", | ||||||
|  |     "fiservemea", | ||||||
|     "forte", |     "forte", | ||||||
|     "globalpay", |     "globalpay", | ||||||
|     "globepay", |     "globepay", | ||||||
|  | |||||||
| @ -46,6 +46,7 @@ pub enum RoutingAlgorithm { | |||||||
| #[serde(rename_all = "snake_case")] | #[serde(rename_all = "snake_case")] | ||||||
| #[strum(serialize_all = "snake_case")] | #[strum(serialize_all = "snake_case")] | ||||||
| pub enum Connector { | pub enum Connector { | ||||||
|  |     // Fiservemea, | ||||||
|     Adyenplatform, |     Adyenplatform, | ||||||
|     #[cfg(feature = "dummy_connector")] |     #[cfg(feature = "dummy_connector")] | ||||||
|     #[serde(rename = "phonypay")] |     #[serde(rename = "phonypay")] | ||||||
| @ -207,6 +208,7 @@ impl Connector { | |||||||
|             | Self::DummyConnector7 => false, |             | Self::DummyConnector7 => false, | ||||||
|             Self::Aci |             Self::Aci | ||||||
|             // Add Separate authentication support for connectors |             // Add Separate authentication support for connectors | ||||||
|  | 			// | Self::Fiservemea | ||||||
|             | Self::Adyen |             | Self::Adyen | ||||||
|             | Self::Adyenplatform |             | Self::Adyenplatform | ||||||
|             | Self::Airwallex |             | Self::Airwallex | ||||||
|  | |||||||
| @ -210,6 +210,7 @@ pub enum RoutableConnectors { | |||||||
|     Dlocal, |     Dlocal, | ||||||
|     Ebanx, |     Ebanx, | ||||||
|     Fiserv, |     Fiserv, | ||||||
|  |     // Fiservemea, | ||||||
|     Forte, |     Forte, | ||||||
|     Globalpay, |     Globalpay, | ||||||
|     Globepay, |     Globepay, | ||||||
|  | |||||||
| @ -1,7 +1,11 @@ | |||||||
| pub mod bambora; | pub mod bambora; | ||||||
| pub mod bitpay; | pub mod bitpay; | ||||||
| pub mod fiserv; | pub mod fiserv; | ||||||
|  | pub mod fiservemea; | ||||||
| pub mod helcim; | pub mod helcim; | ||||||
| pub mod stax; | pub mod stax; | ||||||
|  |  | ||||||
| pub use self::{bambora::Bambora, bitpay::Bitpay, fiserv::Fiserv, helcim::Helcim, stax::Stax}; | pub use self::{ | ||||||
|  |     bambora::Bambora, bitpay::Bitpay, fiserv::Fiserv, fiservemea::Fiservemea, helcim::Helcim, | ||||||
|  |     stax::Stax, | ||||||
|  | }; | ||||||
|  | |||||||
							
								
								
									
										567
									
								
								crates/hyperswitch_connectors/src/connectors/fiservemea.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										567
									
								
								crates/hyperswitch_connectors/src/connectors/fiservemea.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,567 @@ | |||||||
|  | pub mod transformers; | ||||||
|  |  | ||||||
|  | use common_utils::{ | ||||||
|  |     errors::CustomResult, | ||||||
|  |     ext_traits::BytesExt, | ||||||
|  |     request::{Method, Request, RequestBuilder, RequestContent}, | ||||||
|  |     types::{AmountConvertor, StringMinorUnit, StringMinorUnitForConnector}, | ||||||
|  | }; | ||||||
|  | use error_stack::{report, ResultExt}; | ||||||
|  | use hyperswitch_domain_models::{ | ||||||
|  |     router_data::{AccessToken, ConnectorAuthType, ErrorResponse, RouterData}, | ||||||
|  |     router_flow_types::{ | ||||||
|  |         access_token_auth::AccessTokenAuth, | ||||||
|  |         payments::{Authorize, Capture, PSync, PaymentMethodToken, Session, SetupMandate, Void}, | ||||||
|  |         refunds::{Execute, RSync}, | ||||||
|  |     }, | ||||||
|  |     router_request_types::{ | ||||||
|  |         AccessTokenRequestData, PaymentMethodTokenizationData, PaymentsAuthorizeData, | ||||||
|  |         PaymentsCancelData, PaymentsCaptureData, PaymentsSessionData, PaymentsSyncData, | ||||||
|  |         RefundsData, SetupMandateRequestData, | ||||||
|  |     }, | ||||||
|  |     router_response_types::{PaymentsResponseData, RefundsResponseData}, | ||||||
|  |     types::{ | ||||||
|  |         PaymentsAuthorizeRouterData, PaymentsCaptureRouterData, PaymentsSyncRouterData, | ||||||
|  |         RefundSyncRouterData, RefundsRouterData, | ||||||
|  |     }, | ||||||
|  | }; | ||||||
|  | use hyperswitch_interfaces::{ | ||||||
|  |     api::{self, ConnectorCommon, ConnectorCommonExt, ConnectorIntegration, ConnectorValidation}, | ||||||
|  |     configs::Connectors, | ||||||
|  |     errors, | ||||||
|  |     events::connector_api_logs::ConnectorEvent, | ||||||
|  |     types::{self, Response}, | ||||||
|  |     webhooks, | ||||||
|  | }; | ||||||
|  | use masking::{ExposeInterface, Mask}; | ||||||
|  | use transformers as fiservemea; | ||||||
|  |  | ||||||
|  | use crate::{constants::headers, types::ResponseRouterData, utils}; | ||||||
|  |  | ||||||
|  | #[derive(Clone)] | ||||||
|  | pub struct Fiservemea { | ||||||
|  |     amount_converter: &'static (dyn AmountConvertor<Output = StringMinorUnit> + Sync), | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl Fiservemea { | ||||||
|  |     pub fn new() -> &'static Self { | ||||||
|  |         &Self { | ||||||
|  |             amount_converter: &StringMinorUnitForConnector, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl api::Payment for Fiservemea {} | ||||||
|  | impl api::PaymentSession for Fiservemea {} | ||||||
|  | impl api::ConnectorAccessToken for Fiservemea {} | ||||||
|  | impl api::MandateSetup for Fiservemea {} | ||||||
|  | impl api::PaymentAuthorize for Fiservemea {} | ||||||
|  | impl api::PaymentSync for Fiservemea {} | ||||||
|  | impl api::PaymentCapture for Fiservemea {} | ||||||
|  | impl api::PaymentVoid for Fiservemea {} | ||||||
|  | impl api::Refund for Fiservemea {} | ||||||
|  | impl api::RefundExecute for Fiservemea {} | ||||||
|  | impl api::RefundSync for Fiservemea {} | ||||||
|  | impl api::PaymentToken for Fiservemea {} | ||||||
|  |  | ||||||
|  | impl ConnectorIntegration<PaymentMethodToken, PaymentMethodTokenizationData, PaymentsResponseData> | ||||||
|  |     for Fiservemea | ||||||
|  | { | ||||||
|  |     // Not Implemented (R) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl<Flow, Request, Response> ConnectorCommonExt<Flow, Request, Response> for Fiservemea | ||||||
|  | where | ||||||
|  |     Self: ConnectorIntegration<Flow, Request, Response>, | ||||||
|  | { | ||||||
|  |     fn build_headers( | ||||||
|  |         &self, | ||||||
|  |         req: &RouterData<Flow, Request, Response>, | ||||||
|  |         _connectors: &Connectors, | ||||||
|  |     ) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> { | ||||||
|  |         let mut header = vec![( | ||||||
|  |             headers::CONTENT_TYPE.to_string(), | ||||||
|  |             self.get_content_type().to_string().into(), | ||||||
|  |         )]; | ||||||
|  |         let mut api_key = self.get_auth_header(&req.connector_auth_type)?; | ||||||
|  |         header.append(&mut api_key); | ||||||
|  |         Ok(header) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl ConnectorCommon for Fiservemea { | ||||||
|  |     fn id(&self) -> &'static str { | ||||||
|  |         "fiservemea" | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn get_currency_unit(&self) -> api::CurrencyUnit { | ||||||
|  |         api::CurrencyUnit::Base | ||||||
|  |         //    TODO! Check connector documentation, on which unit they are processing the currency. | ||||||
|  |         //    If the connector accepts amount in lower unit ( i.e cents for USD) then return api::CurrencyUnit::Minor, | ||||||
|  |         //    if connector accepts amount in base unit (i.e dollars for USD) then return api::CurrencyUnit::Base | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn common_get_content_type(&self) -> &'static str { | ||||||
|  |         "application/json" | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn base_url<'a>(&self, connectors: &'a Connectors) -> &'a str { | ||||||
|  |         connectors.fiservemea.base_url.as_ref() | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn get_auth_header( | ||||||
|  |         &self, | ||||||
|  |         auth_type: &ConnectorAuthType, | ||||||
|  |     ) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> { | ||||||
|  |         let auth = fiservemea::FiservemeaAuthType::try_from(auth_type) | ||||||
|  |             .change_context(errors::ConnectorError::FailedToObtainAuthType)?; | ||||||
|  |         Ok(vec![( | ||||||
|  |             headers::AUTHORIZATION.to_string(), | ||||||
|  |             auth.api_key.expose().into_masked(), | ||||||
|  |         )]) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn build_error_response( | ||||||
|  |         &self, | ||||||
|  |         res: Response, | ||||||
|  |         event_builder: Option<&mut ConnectorEvent>, | ||||||
|  |     ) -> CustomResult<ErrorResponse, errors::ConnectorError> { | ||||||
|  |         let response: fiservemea::FiservemeaErrorResponse = res | ||||||
|  |             .response | ||||||
|  |             .parse_struct("FiservemeaErrorResponse") | ||||||
|  |             .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; | ||||||
|  |  | ||||||
|  |         event_builder.map(|i| i.set_response_body(&response)); | ||||||
|  |         router_env::logger::info!(connector_response=?response); | ||||||
|  |  | ||||||
|  |         Ok(ErrorResponse { | ||||||
|  |             status_code: res.status_code, | ||||||
|  |             code: response.code, | ||||||
|  |             message: response.message, | ||||||
|  |             reason: response.reason, | ||||||
|  |             attempt_status: None, | ||||||
|  |             connector_transaction_id: None, | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl ConnectorValidation for Fiservemea { | ||||||
|  |     //TODO: implement functions when support enabled | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl ConnectorIntegration<Session, PaymentsSessionData, PaymentsResponseData> for Fiservemea { | ||||||
|  |     //TODO: implement sessions flow | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl ConnectorIntegration<AccessTokenAuth, AccessTokenRequestData, AccessToken> for Fiservemea {} | ||||||
|  |  | ||||||
|  | impl ConnectorIntegration<SetupMandate, SetupMandateRequestData, PaymentsResponseData> | ||||||
|  |     for Fiservemea | ||||||
|  | { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl ConnectorIntegration<Authorize, PaymentsAuthorizeData, PaymentsResponseData> for Fiservemea { | ||||||
|  |     fn get_headers( | ||||||
|  |         &self, | ||||||
|  |         req: &PaymentsAuthorizeRouterData, | ||||||
|  |         connectors: &Connectors, | ||||||
|  |     ) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> { | ||||||
|  |         self.build_headers(req, connectors) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn get_content_type(&self) -> &'static str { | ||||||
|  |         self.common_get_content_type() | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn get_url( | ||||||
|  |         &self, | ||||||
|  |         _req: &PaymentsAuthorizeRouterData, | ||||||
|  |         _connectors: &Connectors, | ||||||
|  |     ) -> CustomResult<String, errors::ConnectorError> { | ||||||
|  |         Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn get_request_body( | ||||||
|  |         &self, | ||||||
|  |         req: &PaymentsAuthorizeRouterData, | ||||||
|  |         _connectors: &Connectors, | ||||||
|  |     ) -> CustomResult<RequestContent, errors::ConnectorError> { | ||||||
|  |         let amount = utils::convert_amount( | ||||||
|  |             self.amount_converter, | ||||||
|  |             req.request.minor_amount, | ||||||
|  |             req.request.currency, | ||||||
|  |         )?; | ||||||
|  |  | ||||||
|  |         let connector_router_data = fiservemea::FiservemeaRouterData::from((amount, req)); | ||||||
|  |         let connector_req = | ||||||
|  |             fiservemea::FiservemeaPaymentsRequest::try_from(&connector_router_data)?; | ||||||
|  |         Ok(RequestContent::Json(Box::new(connector_req))) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn build_request( | ||||||
|  |         &self, | ||||||
|  |         req: &PaymentsAuthorizeRouterData, | ||||||
|  |         connectors: &Connectors, | ||||||
|  |     ) -> CustomResult<Option<Request>, errors::ConnectorError> { | ||||||
|  |         Ok(Some( | ||||||
|  |             RequestBuilder::new() | ||||||
|  |                 .method(Method::Post) | ||||||
|  |                 .url(&types::PaymentsAuthorizeType::get_url( | ||||||
|  |                     self, req, connectors, | ||||||
|  |                 )?) | ||||||
|  |                 .attach_default_headers() | ||||||
|  |                 .headers(types::PaymentsAuthorizeType::get_headers( | ||||||
|  |                     self, req, connectors, | ||||||
|  |                 )?) | ||||||
|  |                 .set_body(types::PaymentsAuthorizeType::get_request_body( | ||||||
|  |                     self, req, connectors, | ||||||
|  |                 )?) | ||||||
|  |                 .build(), | ||||||
|  |         )) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn handle_response( | ||||||
|  |         &self, | ||||||
|  |         data: &PaymentsAuthorizeRouterData, | ||||||
|  |         event_builder: Option<&mut ConnectorEvent>, | ||||||
|  |         res: Response, | ||||||
|  |     ) -> CustomResult<PaymentsAuthorizeRouterData, errors::ConnectorError> { | ||||||
|  |         let response: fiservemea::FiservemeaPaymentsResponse = res | ||||||
|  |             .response | ||||||
|  |             .parse_struct("Fiservemea PaymentsAuthorizeResponse") | ||||||
|  |             .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; | ||||||
|  |         event_builder.map(|i| i.set_response_body(&response)); | ||||||
|  |         router_env::logger::info!(connector_response=?response); | ||||||
|  |         RouterData::try_from(ResponseRouterData { | ||||||
|  |             response, | ||||||
|  |             data: data.clone(), | ||||||
|  |             http_code: res.status_code, | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn get_error_response( | ||||||
|  |         &self, | ||||||
|  |         res: Response, | ||||||
|  |         event_builder: Option<&mut ConnectorEvent>, | ||||||
|  |     ) -> CustomResult<ErrorResponse, errors::ConnectorError> { | ||||||
|  |         self.build_error_response(res, event_builder) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl ConnectorIntegration<PSync, PaymentsSyncData, PaymentsResponseData> for Fiservemea { | ||||||
|  |     fn get_headers( | ||||||
|  |         &self, | ||||||
|  |         req: &PaymentsSyncRouterData, | ||||||
|  |         connectors: &Connectors, | ||||||
|  |     ) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> { | ||||||
|  |         self.build_headers(req, connectors) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn get_content_type(&self) -> &'static str { | ||||||
|  |         self.common_get_content_type() | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn get_url( | ||||||
|  |         &self, | ||||||
|  |         _req: &PaymentsSyncRouterData, | ||||||
|  |         _connectors: &Connectors, | ||||||
|  |     ) -> CustomResult<String, errors::ConnectorError> { | ||||||
|  |         Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn build_request( | ||||||
|  |         &self, | ||||||
|  |         req: &PaymentsSyncRouterData, | ||||||
|  |         connectors: &Connectors, | ||||||
|  |     ) -> CustomResult<Option<Request>, errors::ConnectorError> { | ||||||
|  |         Ok(Some( | ||||||
|  |             RequestBuilder::new() | ||||||
|  |                 .method(Method::Get) | ||||||
|  |                 .url(&types::PaymentsSyncType::get_url(self, req, connectors)?) | ||||||
|  |                 .attach_default_headers() | ||||||
|  |                 .headers(types::PaymentsSyncType::get_headers(self, req, connectors)?) | ||||||
|  |                 .build(), | ||||||
|  |         )) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn handle_response( | ||||||
|  |         &self, | ||||||
|  |         data: &PaymentsSyncRouterData, | ||||||
|  |         event_builder: Option<&mut ConnectorEvent>, | ||||||
|  |         res: Response, | ||||||
|  |     ) -> CustomResult<PaymentsSyncRouterData, errors::ConnectorError> { | ||||||
|  |         let response: fiservemea::FiservemeaPaymentsResponse = res | ||||||
|  |             .response | ||||||
|  |             .parse_struct("fiservemea PaymentsSyncResponse") | ||||||
|  |             .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; | ||||||
|  |         event_builder.map(|i| i.set_response_body(&response)); | ||||||
|  |         router_env::logger::info!(connector_response=?response); | ||||||
|  |         RouterData::try_from(ResponseRouterData { | ||||||
|  |             response, | ||||||
|  |             data: data.clone(), | ||||||
|  |             http_code: res.status_code, | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn get_error_response( | ||||||
|  |         &self, | ||||||
|  |         res: Response, | ||||||
|  |         event_builder: Option<&mut ConnectorEvent>, | ||||||
|  |     ) -> CustomResult<ErrorResponse, errors::ConnectorError> { | ||||||
|  |         self.build_error_response(res, event_builder) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl ConnectorIntegration<Capture, PaymentsCaptureData, PaymentsResponseData> for Fiservemea { | ||||||
|  |     fn get_headers( | ||||||
|  |         &self, | ||||||
|  |         req: &PaymentsCaptureRouterData, | ||||||
|  |         connectors: &Connectors, | ||||||
|  |     ) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> { | ||||||
|  |         self.build_headers(req, connectors) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn get_content_type(&self) -> &'static str { | ||||||
|  |         self.common_get_content_type() | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn get_url( | ||||||
|  |         &self, | ||||||
|  |         _req: &PaymentsCaptureRouterData, | ||||||
|  |         _connectors: &Connectors, | ||||||
|  |     ) -> CustomResult<String, errors::ConnectorError> { | ||||||
|  |         Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn get_request_body( | ||||||
|  |         &self, | ||||||
|  |         _req: &PaymentsCaptureRouterData, | ||||||
|  |         _connectors: &Connectors, | ||||||
|  |     ) -> CustomResult<RequestContent, errors::ConnectorError> { | ||||||
|  |         Err(errors::ConnectorError::NotImplemented("get_request_body method".to_string()).into()) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn build_request( | ||||||
|  |         &self, | ||||||
|  |         req: &PaymentsCaptureRouterData, | ||||||
|  |         connectors: &Connectors, | ||||||
|  |     ) -> CustomResult<Option<Request>, errors::ConnectorError> { | ||||||
|  |         Ok(Some( | ||||||
|  |             RequestBuilder::new() | ||||||
|  |                 .method(Method::Post) | ||||||
|  |                 .url(&types::PaymentsCaptureType::get_url(self, req, connectors)?) | ||||||
|  |                 .attach_default_headers() | ||||||
|  |                 .headers(types::PaymentsCaptureType::get_headers( | ||||||
|  |                     self, req, connectors, | ||||||
|  |                 )?) | ||||||
|  |                 .set_body(types::PaymentsCaptureType::get_request_body( | ||||||
|  |                     self, req, connectors, | ||||||
|  |                 )?) | ||||||
|  |                 .build(), | ||||||
|  |         )) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn handle_response( | ||||||
|  |         &self, | ||||||
|  |         data: &PaymentsCaptureRouterData, | ||||||
|  |         event_builder: Option<&mut ConnectorEvent>, | ||||||
|  |         res: Response, | ||||||
|  |     ) -> CustomResult<PaymentsCaptureRouterData, errors::ConnectorError> { | ||||||
|  |         let response: fiservemea::FiservemeaPaymentsResponse = res | ||||||
|  |             .response | ||||||
|  |             .parse_struct("Fiservemea PaymentsCaptureResponse") | ||||||
|  |             .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; | ||||||
|  |         event_builder.map(|i| i.set_response_body(&response)); | ||||||
|  |         router_env::logger::info!(connector_response=?response); | ||||||
|  |         RouterData::try_from(ResponseRouterData { | ||||||
|  |             response, | ||||||
|  |             data: data.clone(), | ||||||
|  |             http_code: res.status_code, | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn get_error_response( | ||||||
|  |         &self, | ||||||
|  |         res: Response, | ||||||
|  |         event_builder: Option<&mut ConnectorEvent>, | ||||||
|  |     ) -> CustomResult<ErrorResponse, errors::ConnectorError> { | ||||||
|  |         self.build_error_response(res, event_builder) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl ConnectorIntegration<Void, PaymentsCancelData, PaymentsResponseData> for Fiservemea {} | ||||||
|  |  | ||||||
|  | impl ConnectorIntegration<Execute, RefundsData, RefundsResponseData> for Fiservemea { | ||||||
|  |     fn get_headers( | ||||||
|  |         &self, | ||||||
|  |         req: &RefundsRouterData<Execute>, | ||||||
|  |         connectors: &Connectors, | ||||||
|  |     ) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> { | ||||||
|  |         self.build_headers(req, connectors) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn get_content_type(&self) -> &'static str { | ||||||
|  |         self.common_get_content_type() | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn get_url( | ||||||
|  |         &self, | ||||||
|  |         _req: &RefundsRouterData<Execute>, | ||||||
|  |         _connectors: &Connectors, | ||||||
|  |     ) -> CustomResult<String, errors::ConnectorError> { | ||||||
|  |         Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn get_request_body( | ||||||
|  |         &self, | ||||||
|  |         req: &RefundsRouterData<Execute>, | ||||||
|  |         _connectors: &Connectors, | ||||||
|  |     ) -> CustomResult<RequestContent, errors::ConnectorError> { | ||||||
|  |         let refund_amount = utils::convert_amount( | ||||||
|  |             self.amount_converter, | ||||||
|  |             req.request.minor_refund_amount, | ||||||
|  |             req.request.currency, | ||||||
|  |         )?; | ||||||
|  |  | ||||||
|  |         let connector_router_data = fiservemea::FiservemeaRouterData::from((refund_amount, req)); | ||||||
|  |         let connector_req = fiservemea::FiservemeaRefundRequest::try_from(&connector_router_data)?; | ||||||
|  |         Ok(RequestContent::Json(Box::new(connector_req))) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn build_request( | ||||||
|  |         &self, | ||||||
|  |         req: &RefundsRouterData<Execute>, | ||||||
|  |         connectors: &Connectors, | ||||||
|  |     ) -> CustomResult<Option<Request>, errors::ConnectorError> { | ||||||
|  |         let request = RequestBuilder::new() | ||||||
|  |             .method(Method::Post) | ||||||
|  |             .url(&types::RefundExecuteType::get_url(self, req, connectors)?) | ||||||
|  |             .attach_default_headers() | ||||||
|  |             .headers(types::RefundExecuteType::get_headers( | ||||||
|  |                 self, req, connectors, | ||||||
|  |             )?) | ||||||
|  |             .set_body(types::RefundExecuteType::get_request_body( | ||||||
|  |                 self, req, connectors, | ||||||
|  |             )?) | ||||||
|  |             .build(); | ||||||
|  |         Ok(Some(request)) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn handle_response( | ||||||
|  |         &self, | ||||||
|  |         data: &RefundsRouterData<Execute>, | ||||||
|  |         event_builder: Option<&mut ConnectorEvent>, | ||||||
|  |         res: Response, | ||||||
|  |     ) -> CustomResult<RefundsRouterData<Execute>, errors::ConnectorError> { | ||||||
|  |         let response: fiservemea::RefundResponse = res | ||||||
|  |             .response | ||||||
|  |             .parse_struct("fiservemea RefundResponse") | ||||||
|  |             .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; | ||||||
|  |         event_builder.map(|i| i.set_response_body(&response)); | ||||||
|  |         router_env::logger::info!(connector_response=?response); | ||||||
|  |         RouterData::try_from(ResponseRouterData { | ||||||
|  |             response, | ||||||
|  |             data: data.clone(), | ||||||
|  |             http_code: res.status_code, | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn get_error_response( | ||||||
|  |         &self, | ||||||
|  |         res: Response, | ||||||
|  |         event_builder: Option<&mut ConnectorEvent>, | ||||||
|  |     ) -> CustomResult<ErrorResponse, errors::ConnectorError> { | ||||||
|  |         self.build_error_response(res, event_builder) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl ConnectorIntegration<RSync, RefundsData, RefundsResponseData> for Fiservemea { | ||||||
|  |     fn get_headers( | ||||||
|  |         &self, | ||||||
|  |         req: &RefundSyncRouterData, | ||||||
|  |         connectors: &Connectors, | ||||||
|  |     ) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> { | ||||||
|  |         self.build_headers(req, connectors) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn get_content_type(&self) -> &'static str { | ||||||
|  |         self.common_get_content_type() | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn get_url( | ||||||
|  |         &self, | ||||||
|  |         _req: &RefundSyncRouterData, | ||||||
|  |         _connectors: &Connectors, | ||||||
|  |     ) -> CustomResult<String, errors::ConnectorError> { | ||||||
|  |         Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn build_request( | ||||||
|  |         &self, | ||||||
|  |         req: &RefundSyncRouterData, | ||||||
|  |         connectors: &Connectors, | ||||||
|  |     ) -> CustomResult<Option<Request>, errors::ConnectorError> { | ||||||
|  |         Ok(Some( | ||||||
|  |             RequestBuilder::new() | ||||||
|  |                 .method(Method::Get) | ||||||
|  |                 .url(&types::RefundSyncType::get_url(self, req, connectors)?) | ||||||
|  |                 .attach_default_headers() | ||||||
|  |                 .headers(types::RefundSyncType::get_headers(self, req, connectors)?) | ||||||
|  |                 .set_body(types::RefundSyncType::get_request_body( | ||||||
|  |                     self, req, connectors, | ||||||
|  |                 )?) | ||||||
|  |                 .build(), | ||||||
|  |         )) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn handle_response( | ||||||
|  |         &self, | ||||||
|  |         data: &RefundSyncRouterData, | ||||||
|  |         event_builder: Option<&mut ConnectorEvent>, | ||||||
|  |         res: Response, | ||||||
|  |     ) -> CustomResult<RefundSyncRouterData, errors::ConnectorError> { | ||||||
|  |         let response: fiservemea::RefundResponse = res | ||||||
|  |             .response | ||||||
|  |             .parse_struct("fiservemea RefundSyncResponse") | ||||||
|  |             .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; | ||||||
|  |         event_builder.map(|i| i.set_response_body(&response)); | ||||||
|  |         router_env::logger::info!(connector_response=?response); | ||||||
|  |         RouterData::try_from(ResponseRouterData { | ||||||
|  |             response, | ||||||
|  |             data: data.clone(), | ||||||
|  |             http_code: res.status_code, | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn get_error_response( | ||||||
|  |         &self, | ||||||
|  |         res: Response, | ||||||
|  |         event_builder: Option<&mut ConnectorEvent>, | ||||||
|  |     ) -> CustomResult<ErrorResponse, errors::ConnectorError> { | ||||||
|  |         self.build_error_response(res, event_builder) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[async_trait::async_trait] | ||||||
|  | impl webhooks::IncomingWebhook for Fiservemea { | ||||||
|  |     fn get_webhook_object_reference_id( | ||||||
|  |         &self, | ||||||
|  |         _request: &webhooks::IncomingWebhookRequestDetails<'_>, | ||||||
|  |     ) -> CustomResult<api_models::webhooks::ObjectReferenceId, errors::ConnectorError> { | ||||||
|  |         Err(report!(errors::ConnectorError::WebhooksNotImplemented)) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn get_webhook_event_type( | ||||||
|  |         &self, | ||||||
|  |         _request: &webhooks::IncomingWebhookRequestDetails<'_>, | ||||||
|  |     ) -> CustomResult<api_models::webhooks::IncomingWebhookEvent, errors::ConnectorError> { | ||||||
|  |         Err(report!(errors::ConnectorError::WebhooksNotImplemented)) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn get_webhook_resource_object( | ||||||
|  |         &self, | ||||||
|  |         _request: &webhooks::IncomingWebhookRequestDetails<'_>, | ||||||
|  |     ) -> CustomResult<Box<dyn masking::ErasedMaskSerialize>, errors::ConnectorError> { | ||||||
|  |         Err(report!(errors::ConnectorError::WebhooksNotImplemented)) | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,228 @@ | |||||||
|  | use common_enums::enums; | ||||||
|  | use common_utils::types::StringMinorUnit; | ||||||
|  | use hyperswitch_domain_models::{ | ||||||
|  |     payment_method_data::PaymentMethodData, | ||||||
|  |     router_data::{ConnectorAuthType, RouterData}, | ||||||
|  |     router_flow_types::refunds::{Execute, RSync}, | ||||||
|  |     router_request_types::ResponseId, | ||||||
|  |     router_response_types::{PaymentsResponseData, RefundsResponseData}, | ||||||
|  |     types::{PaymentsAuthorizeRouterData, RefundsRouterData}, | ||||||
|  | }; | ||||||
|  | use hyperswitch_interfaces::errors; | ||||||
|  | use masking::Secret; | ||||||
|  | use serde::{Deserialize, Serialize}; | ||||||
|  |  | ||||||
|  | use crate::{ | ||||||
|  |     types::{RefundsResponseRouterData, ResponseRouterData}, | ||||||
|  |     utils::PaymentsAuthorizeRequestData, | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | //TODO: Fill the struct with respective fields | ||||||
|  | pub struct FiservemeaRouterData<T> { | ||||||
|  |     pub amount: StringMinorUnit, // The type of amount that a connector accepts, for example, String, i64, f64, etc. | ||||||
|  |     pub router_data: T, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl<T> From<(StringMinorUnit, T)> for FiservemeaRouterData<T> { | ||||||
|  |     fn from((amount, item): (StringMinorUnit, T)) -> Self { | ||||||
|  |         //Todo :  use utils to convert the amount to the type of amount that a connector accepts | ||||||
|  |         Self { | ||||||
|  |             amount, | ||||||
|  |             router_data: item, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //TODO: Fill the struct with respective fields | ||||||
|  | #[derive(Default, Debug, Serialize, PartialEq)] | ||||||
|  | pub struct FiservemeaPaymentsRequest { | ||||||
|  |     amount: StringMinorUnit, | ||||||
|  |     card: FiservemeaCard, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[derive(Default, Debug, Serialize, Eq, PartialEq)] | ||||||
|  | pub struct FiservemeaCard { | ||||||
|  |     number: cards::CardNumber, | ||||||
|  |     expiry_month: Secret<String>, | ||||||
|  |     expiry_year: Secret<String>, | ||||||
|  |     cvc: Secret<String>, | ||||||
|  |     complete: bool, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl TryFrom<&FiservemeaRouterData<&PaymentsAuthorizeRouterData>> for FiservemeaPaymentsRequest { | ||||||
|  |     type Error = error_stack::Report<errors::ConnectorError>; | ||||||
|  |     fn try_from( | ||||||
|  |         item: &FiservemeaRouterData<&PaymentsAuthorizeRouterData>, | ||||||
|  |     ) -> Result<Self, Self::Error> { | ||||||
|  |         match item.router_data.request.payment_method_data.clone() { | ||||||
|  |             PaymentMethodData::Card(req_card) => { | ||||||
|  |                 let card = FiservemeaCard { | ||||||
|  |                     number: req_card.card_number, | ||||||
|  |                     expiry_month: req_card.card_exp_month, | ||||||
|  |                     expiry_year: req_card.card_exp_year, | ||||||
|  |                     cvc: req_card.card_cvc, | ||||||
|  |                     complete: item.router_data.request.is_auto_capture()?, | ||||||
|  |                 }; | ||||||
|  |                 Ok(Self { | ||||||
|  |                     amount: item.amount.clone(), | ||||||
|  |                     card, | ||||||
|  |                 }) | ||||||
|  |             } | ||||||
|  |             _ => Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into()), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //TODO: Fill the struct with respective fields | ||||||
|  | // Auth Struct | ||||||
|  | pub struct FiservemeaAuthType { | ||||||
|  |     pub(super) api_key: Secret<String>, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl TryFrom<&ConnectorAuthType> for FiservemeaAuthType { | ||||||
|  |     type Error = error_stack::Report<errors::ConnectorError>; | ||||||
|  |     fn try_from(auth_type: &ConnectorAuthType) -> Result<Self, Self::Error> { | ||||||
|  |         match auth_type { | ||||||
|  |             ConnectorAuthType::HeaderKey { api_key } => Ok(Self { | ||||||
|  |                 api_key: api_key.to_owned(), | ||||||
|  |             }), | ||||||
|  |             _ => Err(errors::ConnectorError::FailedToObtainAuthType.into()), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | // PaymentsResponse | ||||||
|  | //TODO: Append the remaining status flags | ||||||
|  | #[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)] | ||||||
|  | #[serde(rename_all = "lowercase")] | ||||||
|  | pub enum FiservemeaPaymentStatus { | ||||||
|  |     Succeeded, | ||||||
|  |     Failed, | ||||||
|  |     #[default] | ||||||
|  |     Processing, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl From<FiservemeaPaymentStatus> for common_enums::AttemptStatus { | ||||||
|  |     fn from(item: FiservemeaPaymentStatus) -> Self { | ||||||
|  |         match item { | ||||||
|  |             FiservemeaPaymentStatus::Succeeded => Self::Charged, | ||||||
|  |             FiservemeaPaymentStatus::Failed => Self::Failure, | ||||||
|  |             FiservemeaPaymentStatus::Processing => Self::Authorizing, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //TODO: Fill the struct with respective fields | ||||||
|  | #[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq)] | ||||||
|  | pub struct FiservemeaPaymentsResponse { | ||||||
|  |     status: FiservemeaPaymentStatus, | ||||||
|  |     id: String, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl<F, T> TryFrom<ResponseRouterData<F, FiservemeaPaymentsResponse, T, PaymentsResponseData>> | ||||||
|  |     for RouterData<F, T, PaymentsResponseData> | ||||||
|  | { | ||||||
|  |     type Error = error_stack::Report<errors::ConnectorError>; | ||||||
|  |     fn try_from( | ||||||
|  |         item: ResponseRouterData<F, FiservemeaPaymentsResponse, T, PaymentsResponseData>, | ||||||
|  |     ) -> Result<Self, Self::Error> { | ||||||
|  |         Ok(Self { | ||||||
|  |             status: common_enums::AttemptStatus::from(item.response.status), | ||||||
|  |             response: Ok(PaymentsResponseData::TransactionResponse { | ||||||
|  |                 resource_id: ResponseId::ConnectorTransactionId(item.response.id), | ||||||
|  |                 redirection_data: None, | ||||||
|  |                 mandate_reference: None, | ||||||
|  |                 connector_metadata: None, | ||||||
|  |                 network_txn_id: None, | ||||||
|  |                 connector_response_reference_id: None, | ||||||
|  |                 incremental_authorization_allowed: None, | ||||||
|  |                 charge_id: None, | ||||||
|  |             }), | ||||||
|  |             ..item.data | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //TODO: Fill the struct with respective fields | ||||||
|  | // REFUND : | ||||||
|  | // Type definition for RefundRequest | ||||||
|  | #[derive(Default, Debug, Serialize)] | ||||||
|  | pub struct FiservemeaRefundRequest { | ||||||
|  |     pub amount: StringMinorUnit, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl<F> TryFrom<&FiservemeaRouterData<&RefundsRouterData<F>>> for FiservemeaRefundRequest { | ||||||
|  |     type Error = error_stack::Report<errors::ConnectorError>; | ||||||
|  |     fn try_from(item: &FiservemeaRouterData<&RefundsRouterData<F>>) -> Result<Self, Self::Error> { | ||||||
|  |         Ok(Self { | ||||||
|  |             amount: item.amount.to_owned(), | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Type definition for Refund Response | ||||||
|  |  | ||||||
|  | #[allow(dead_code)] | ||||||
|  | #[derive(Debug, Serialize, Default, Deserialize, Clone)] | ||||||
|  | pub enum RefundStatus { | ||||||
|  |     Succeeded, | ||||||
|  |     Failed, | ||||||
|  |     #[default] | ||||||
|  |     Processing, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl From<RefundStatus> for enums::RefundStatus { | ||||||
|  |     fn from(item: RefundStatus) -> Self { | ||||||
|  |         match item { | ||||||
|  |             RefundStatus::Succeeded => Self::Success, | ||||||
|  |             RefundStatus::Failed => Self::Failure, | ||||||
|  |             RefundStatus::Processing => Self::Pending, | ||||||
|  |             //TODO: Review mapping | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //TODO: Fill the struct with respective fields | ||||||
|  | #[derive(Default, Debug, Clone, Serialize, Deserialize)] | ||||||
|  | pub struct RefundResponse { | ||||||
|  |     id: String, | ||||||
|  |     status: RefundStatus, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl TryFrom<RefundsResponseRouterData<Execute, RefundResponse>> for RefundsRouterData<Execute> { | ||||||
|  |     type Error = error_stack::Report<errors::ConnectorError>; | ||||||
|  |     fn try_from( | ||||||
|  |         item: RefundsResponseRouterData<Execute, RefundResponse>, | ||||||
|  |     ) -> Result<Self, Self::Error> { | ||||||
|  |         Ok(Self { | ||||||
|  |             response: Ok(RefundsResponseData { | ||||||
|  |                 connector_refund_id: item.response.id.to_string(), | ||||||
|  |                 refund_status: enums::RefundStatus::from(item.response.status), | ||||||
|  |             }), | ||||||
|  |             ..item.data | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | impl TryFrom<RefundsResponseRouterData<RSync, RefundResponse>> for RefundsRouterData<RSync> { | ||||||
|  |     type Error = error_stack::Report<errors::ConnectorError>; | ||||||
|  |     fn try_from( | ||||||
|  |         item: RefundsResponseRouterData<RSync, RefundResponse>, | ||||||
|  |     ) -> Result<Self, Self::Error> { | ||||||
|  |         Ok(Self { | ||||||
|  |             response: Ok(RefundsResponseData { | ||||||
|  |                 connector_refund_id: item.response.id.to_string(), | ||||||
|  |                 refund_status: enums::RefundStatus::from(item.response.status), | ||||||
|  |             }), | ||||||
|  |             ..item.data | ||||||
|  |         }) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //TODO: Fill the struct with respective fields | ||||||
|  | #[derive(Default, Debug, Serialize, Deserialize, PartialEq)] | ||||||
|  | pub struct FiservemeaErrorResponse { | ||||||
|  |     pub status_code: u16, | ||||||
|  |     pub code: String, | ||||||
|  |     pub message: String, | ||||||
|  |     pub reason: Option<String>, | ||||||
|  | } | ||||||
| @ -89,6 +89,7 @@ default_imp_for_authorize_session_token!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -112,6 +113,7 @@ macro_rules! default_imp_for_complete_authorize { | |||||||
| default_imp_for_complete_authorize!( | default_imp_for_complete_authorize!( | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -135,6 +137,7 @@ default_imp_for_incremental_authorization!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -158,6 +161,7 @@ default_imp_for_create_customer!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim |     connectors::Helcim | ||||||
| ); | ); | ||||||
|  |  | ||||||
| @ -181,6 +185,7 @@ macro_rules! default_imp_for_connector_redirect_response { | |||||||
| default_imp_for_connector_redirect_response!( | default_imp_for_connector_redirect_response!( | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -204,6 +209,7 @@ default_imp_for_pre_processing_steps!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -227,6 +233,7 @@ default_imp_for_post_processing_steps!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -250,6 +257,7 @@ default_imp_for_approve!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -273,6 +281,7 @@ default_imp_for_reject!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -296,6 +305,7 @@ default_imp_for_webhook_source_verification!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -320,6 +330,7 @@ default_imp_for_accept_dispute!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -343,6 +354,7 @@ default_imp_for_submit_evidence!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -366,6 +378,7 @@ default_imp_for_defend_dispute!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -398,6 +411,7 @@ default_imp_for_file_upload!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -423,6 +437,7 @@ default_imp_for_payouts_create!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -448,6 +463,7 @@ default_imp_for_payouts_retrieve!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -473,6 +489,7 @@ default_imp_for_payouts_eligibility!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -498,6 +515,7 @@ default_imp_for_payouts_fulfill!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -523,6 +541,7 @@ default_imp_for_payouts_cancel!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -548,6 +567,7 @@ default_imp_for_payouts_quote!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -573,6 +593,7 @@ default_imp_for_payouts_recipient!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -598,6 +619,7 @@ default_imp_for_payouts_recipient_account!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -623,6 +645,7 @@ default_imp_for_frm_sale!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -648,6 +671,7 @@ default_imp_for_frm_checkout!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -673,6 +697,7 @@ default_imp_for_frm_transaction!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -698,6 +723,7 @@ default_imp_for_frm_fulfillment!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -723,6 +749,7 @@ default_imp_for_frm_record_return!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -745,6 +772,7 @@ default_imp_for_revoking_mandates!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
|  | |||||||
| @ -184,6 +184,7 @@ default_imp_for_new_connector_integration_payment!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -208,6 +209,7 @@ default_imp_for_new_connector_integration_refund!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -227,6 +229,7 @@ default_imp_for_new_connector_integration_connector_access_token!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -252,6 +255,7 @@ default_imp_for_new_connector_integration_accept_dispute!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -276,6 +280,7 @@ default_imp_for_new_connector_integration_submit_evidence!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -300,6 +305,7 @@ default_imp_for_new_connector_integration_defend_dispute!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -334,6 +340,7 @@ default_imp_for_new_connector_integration_file_upload!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -360,6 +367,7 @@ default_imp_for_new_connector_integration_payouts_create!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -386,6 +394,7 @@ default_imp_for_new_connector_integration_payouts_eligibility!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -412,6 +421,7 @@ default_imp_for_new_connector_integration_payouts_fulfill!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -438,6 +448,7 @@ default_imp_for_new_connector_integration_payouts_cancel!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -464,6 +475,7 @@ default_imp_for_new_connector_integration_payouts_quote!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -490,6 +502,7 @@ default_imp_for_new_connector_integration_payouts_recipient!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -516,6 +529,7 @@ default_imp_for_new_connector_integration_payouts_sync!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -542,6 +556,7 @@ default_imp_for_new_connector_integration_payouts_recipient_account!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -566,6 +581,7 @@ default_imp_for_new_connector_integration_webhook_source_verification!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -592,6 +608,7 @@ default_imp_for_new_connector_integration_frm_sale!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -618,6 +635,7 @@ default_imp_for_new_connector_integration_frm_checkout!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -644,6 +662,7 @@ default_imp_for_new_connector_integration_frm_transaction!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -670,6 +689,7 @@ default_imp_for_new_connector_integration_frm_fulfillment!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -696,6 +716,7 @@ default_imp_for_new_connector_integration_frm_record_return!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
| @ -719,6 +740,7 @@ default_imp_for_new_connector_integration_revoking_mandates!( | |||||||
|     connectors::Bambora, |     connectors::Bambora, | ||||||
|     connectors::Bitpay, |     connectors::Bitpay, | ||||||
|     connectors::Fiserv, |     connectors::Fiserv, | ||||||
|  |     connectors::Fiservemea, | ||||||
|     connectors::Helcim, |     connectors::Helcim, | ||||||
|     connectors::Stax |     connectors::Stax | ||||||
| ); | ); | ||||||
|  | |||||||
| @ -37,6 +37,7 @@ pub struct Connectors { | |||||||
|     pub dummyconnector: ConnectorParams, |     pub dummyconnector: ConnectorParams, | ||||||
|     pub ebanx: ConnectorParams, |     pub ebanx: ConnectorParams, | ||||||
|     pub fiserv: ConnectorParams, |     pub fiserv: ConnectorParams, | ||||||
|  |     pub fiservemea: ConnectorParams, | ||||||
|     pub forte: ConnectorParams, |     pub forte: ConnectorParams, | ||||||
|     pub globalpay: ConnectorParams, |     pub globalpay: ConnectorParams, | ||||||
|     pub globepay: ConnectorParams, |     pub globepay: ConnectorParams, | ||||||
|  | |||||||
| @ -68,8 +68,8 @@ pub mod zen; | |||||||
| pub mod zsl; | pub mod zsl; | ||||||
|  |  | ||||||
| pub use hyperswitch_connectors::connectors::{ | pub use hyperswitch_connectors::connectors::{ | ||||||
|     bambora, bambora::Bambora, bitpay, bitpay::Bitpay, fiserv, fiserv::Fiserv, helcim, |     bambora, bambora::Bambora, bitpay, bitpay::Bitpay, fiserv, fiserv::Fiserv, fiservemea, | ||||||
|     helcim::Helcim, stax, stax::Stax, |     fiservemea::Fiservemea, helcim, helcim::Helcim, stax, stax::Stax, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #[cfg(feature = "dummy_connector")] | #[cfg(feature = "dummy_connector")] | ||||||
|  | |||||||
| @ -1234,6 +1234,7 @@ default_imp_for_new_connector_integration_payouts!( | |||||||
|     connector::Dlocal, |     connector::Dlocal, | ||||||
|     connector::Ebanx, |     connector::Ebanx, | ||||||
|     connector::Fiserv, |     connector::Fiserv, | ||||||
|  |     connector::Fiservemea, | ||||||
|     connector::Forte, |     connector::Forte, | ||||||
|     connector::Globalpay, |     connector::Globalpay, | ||||||
|     connector::Globepay, |     connector::Globepay, | ||||||
| @ -2077,6 +2078,7 @@ default_imp_for_new_connector_integration_frm!( | |||||||
|     connector::Dlocal, |     connector::Dlocal, | ||||||
|     connector::Ebanx, |     connector::Ebanx, | ||||||
|     connector::Fiserv, |     connector::Fiserv, | ||||||
|  |     connector::Fiservemea, | ||||||
|     connector::Forte, |     connector::Forte, | ||||||
|     connector::Globalpay, |     connector::Globalpay, | ||||||
|     connector::Globepay, |     connector::Globepay, | ||||||
| @ -2699,6 +2701,7 @@ default_imp_for_new_connector_integration_connector_authentication!( | |||||||
|     connector::Dlocal, |     connector::Dlocal, | ||||||
|     connector::Ebanx, |     connector::Ebanx, | ||||||
|     connector::Fiserv, |     connector::Fiserv, | ||||||
|  |     connector::Fiservemea, | ||||||
|     connector::Forte, |     connector::Forte, | ||||||
|     connector::Globalpay, |     connector::Globalpay, | ||||||
|     connector::Globepay, |     connector::Globepay, | ||||||
|  | |||||||
| @ -541,6 +541,7 @@ default_imp_for_connector_request_id!( | |||||||
|     connector::Dlocal, |     connector::Dlocal, | ||||||
|     connector::Ebanx, |     connector::Ebanx, | ||||||
|     connector::Fiserv, |     connector::Fiserv, | ||||||
|  |     connector::Fiservemea, | ||||||
|     connector::Forte, |     connector::Forte, | ||||||
|     connector::Globalpay, |     connector::Globalpay, | ||||||
|     connector::Globepay, |     connector::Globepay, | ||||||
| @ -1195,6 +1196,7 @@ default_imp_for_payouts!( | |||||||
|     connector::Datatrans, |     connector::Datatrans, | ||||||
|     connector::Dlocal, |     connector::Dlocal, | ||||||
|     connector::Fiserv, |     connector::Fiserv, | ||||||
|  |     connector::Fiservemea, | ||||||
|     connector::Forte, |     connector::Forte, | ||||||
|     connector::Globalpay, |     connector::Globalpay, | ||||||
|     connector::Globepay, |     connector::Globepay, | ||||||
| @ -2212,6 +2214,7 @@ default_imp_for_fraud_check!( | |||||||
|     connector::Dlocal, |     connector::Dlocal, | ||||||
|     connector::Ebanx, |     connector::Ebanx, | ||||||
|     connector::Fiserv, |     connector::Fiserv, | ||||||
|  |     connector::Fiservemea, | ||||||
|     connector::Forte, |     connector::Forte, | ||||||
|     connector::Globalpay, |     connector::Globalpay, | ||||||
|     connector::Globepay, |     connector::Globepay, | ||||||
| @ -3026,6 +3029,7 @@ default_imp_for_connector_authentication!( | |||||||
|     connector::Dlocal, |     connector::Dlocal, | ||||||
|     connector::Ebanx, |     connector::Ebanx, | ||||||
|     connector::Fiserv, |     connector::Fiserv, | ||||||
|  |     connector::Fiservemea, | ||||||
|     connector::Forte, |     connector::Forte, | ||||||
|     connector::Globalpay, |     connector::Globalpay, | ||||||
|     connector::Globepay, |     connector::Globepay, | ||||||
|  | |||||||
| @ -388,6 +388,9 @@ impl ConnectorData { | |||||||
|                 ))), |                 ))), | ||||||
|                 enums::Connector::Ebanx => Ok(ConnectorEnum::Old(Box::new(&connector::Ebanx))), |                 enums::Connector::Ebanx => Ok(ConnectorEnum::Old(Box::new(&connector::Ebanx))), | ||||||
|                 enums::Connector::Fiserv => Ok(ConnectorEnum::Old(Box::new(&connector::Fiserv))), |                 enums::Connector::Fiserv => Ok(ConnectorEnum::Old(Box::new(&connector::Fiserv))), | ||||||
|  |                 // enums::Connector::Fiservemea => { | ||||||
|  |                 //     Ok(ConnectorEnum::Old(Box::new(connector::Fiservemea))) | ||||||
|  |                 // } | ||||||
|                 enums::Connector::Forte => Ok(ConnectorEnum::Old(Box::new(&connector::Forte))), |                 enums::Connector::Forte => Ok(ConnectorEnum::Old(Box::new(&connector::Forte))), | ||||||
|                 enums::Connector::Globalpay => { |                 enums::Connector::Globalpay => { | ||||||
|                     Ok(ConnectorEnum::Old(Box::new(connector::Globalpay::new()))) |                     Ok(ConnectorEnum::Old(Box::new(connector::Globalpay::new()))) | ||||||
|  | |||||||
| @ -244,6 +244,7 @@ impl ForeignTryFrom<api_enums::Connector> for common_enums::RoutableConnectors { | |||||||
|             api_enums::Connector::Dlocal => Self::Dlocal, |             api_enums::Connector::Dlocal => Self::Dlocal, | ||||||
|             api_enums::Connector::Ebanx => Self::Ebanx, |             api_enums::Connector::Ebanx => Self::Ebanx, | ||||||
|             api_enums::Connector::Fiserv => Self::Fiserv, |             api_enums::Connector::Fiserv => Self::Fiserv, | ||||||
|  |             // api_enums::Connector::Fiservemea => Self::Fiservemea, | ||||||
|             api_enums::Connector::Forte => Self::Forte, |             api_enums::Connector::Forte => Self::Forte, | ||||||
|             api_enums::Connector::Globalpay => Self::Globalpay, |             api_enums::Connector::Globalpay => Self::Globalpay, | ||||||
|             api_enums::Connector::Globepay => Self::Globepay, |             api_enums::Connector::Globepay => Self::Globepay, | ||||||
|  | |||||||
							
								
								
									
										421
									
								
								crates/router/tests/connectors/fiservemea.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										421
									
								
								crates/router/tests/connectors/fiservemea.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,421 @@ | |||||||
|  | use hyperswitch_domain_models::payment_method_data::{Card, PaymentMethodData}; | ||||||
|  | use masking::Secret; | ||||||
|  | use router::types::{self, api, storage::enums}; | ||||||
|  | use test_utils::connector_auth; | ||||||
|  |  | ||||||
|  | use crate::utils::{self, ConnectorActions}; | ||||||
|  |  | ||||||
|  | #[derive(Clone, Copy)] | ||||||
|  | struct FiservemeaTest; | ||||||
|  | impl ConnectorActions for FiservemeaTest {} | ||||||
|  | impl utils::Connector for FiservemeaTest { | ||||||
|  |     fn get_data(&self) -> api::ConnectorData { | ||||||
|  |         use router::connector::Fiservemea; | ||||||
|  |         utils::construct_connector_data_old( | ||||||
|  |             Box::new(Fiservemea::new()), | ||||||
|  |             types::Connector::Plaid, | ||||||
|  |             api::GetToken::Connector, | ||||||
|  |             None, | ||||||
|  |         ) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn get_auth_token(&self) -> types::ConnectorAuthType { | ||||||
|  |         utils::to_connector_auth_type( | ||||||
|  |             connector_auth::ConnectorAuthentication::new() | ||||||
|  |                 .fiservemea | ||||||
|  |                 .expect("Missing connector authentication configuration") | ||||||
|  |                 .into(), | ||||||
|  |         ) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     fn get_name(&self) -> String { | ||||||
|  |         "fiservemea".to_string() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static CONNECTOR: FiservemeaTest = FiservemeaTest {}; | ||||||
|  |  | ||||||
|  | fn get_default_payment_info() -> Option<utils::PaymentInfo> { | ||||||
|  |     None | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fn payment_method_details() -> Option<types::PaymentsAuthorizeData> { | ||||||
|  |     None | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Cards Positive Tests | ||||||
|  | // Creates a payment using the manual capture flow (Non 3DS). | ||||||
|  | #[actix_web::test] | ||||||
|  | async fn should_only_authorize_payment() { | ||||||
|  |     let response = CONNECTOR | ||||||
|  |         .authorize_payment(payment_method_details(), get_default_payment_info()) | ||||||
|  |         .await | ||||||
|  |         .expect("Authorize payment response"); | ||||||
|  |     assert_eq!(response.status, enums::AttemptStatus::Authorized); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Captures a payment using the manual capture flow (Non 3DS). | ||||||
|  | #[actix_web::test] | ||||||
|  | async fn should_capture_authorized_payment() { | ||||||
|  |     let response = CONNECTOR | ||||||
|  |         .authorize_and_capture_payment(payment_method_details(), None, get_default_payment_info()) | ||||||
|  |         .await | ||||||
|  |         .expect("Capture payment response"); | ||||||
|  |     assert_eq!(response.status, enums::AttemptStatus::Charged); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Partially captures a payment using the manual capture flow (Non 3DS). | ||||||
|  | #[actix_web::test] | ||||||
|  | async fn should_partially_capture_authorized_payment() { | ||||||
|  |     let response = CONNECTOR | ||||||
|  |         .authorize_and_capture_payment( | ||||||
|  |             payment_method_details(), | ||||||
|  |             Some(types::PaymentsCaptureData { | ||||||
|  |                 amount_to_capture: 50, | ||||||
|  |                 ..utils::PaymentCaptureType::default().0 | ||||||
|  |             }), | ||||||
|  |             get_default_payment_info(), | ||||||
|  |         ) | ||||||
|  |         .await | ||||||
|  |         .expect("Capture payment response"); | ||||||
|  |     assert_eq!(response.status, enums::AttemptStatus::Charged); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Synchronizes a payment using the manual capture flow (Non 3DS). | ||||||
|  | #[actix_web::test] | ||||||
|  | async fn should_sync_authorized_payment() { | ||||||
|  |     let authorize_response = CONNECTOR | ||||||
|  |         .authorize_payment(payment_method_details(), get_default_payment_info()) | ||||||
|  |         .await | ||||||
|  |         .expect("Authorize payment response"); | ||||||
|  |     let txn_id = utils::get_connector_transaction_id(authorize_response.response); | ||||||
|  |     let response = CONNECTOR | ||||||
|  |         .psync_retry_till_status_matches( | ||||||
|  |             enums::AttemptStatus::Authorized, | ||||||
|  |             Some(types::PaymentsSyncData { | ||||||
|  |                 connector_transaction_id: types::ResponseId::ConnectorTransactionId( | ||||||
|  |                     txn_id.unwrap(), | ||||||
|  |                 ), | ||||||
|  |                 ..Default::default() | ||||||
|  |             }), | ||||||
|  |             get_default_payment_info(), | ||||||
|  |         ) | ||||||
|  |         .await | ||||||
|  |         .expect("PSync response"); | ||||||
|  |     assert_eq!(response.status, enums::AttemptStatus::Authorized,); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Voids a payment using the manual capture flow (Non 3DS). | ||||||
|  | #[actix_web::test] | ||||||
|  | async fn should_void_authorized_payment() { | ||||||
|  |     let response = CONNECTOR | ||||||
|  |         .authorize_and_void_payment( | ||||||
|  |             payment_method_details(), | ||||||
|  |             Some(types::PaymentsCancelData { | ||||||
|  |                 connector_transaction_id: String::from(""), | ||||||
|  |                 cancellation_reason: Some("requested_by_customer".to_string()), | ||||||
|  |                 ..Default::default() | ||||||
|  |             }), | ||||||
|  |             get_default_payment_info(), | ||||||
|  |         ) | ||||||
|  |         .await | ||||||
|  |         .expect("Void payment response"); | ||||||
|  |     assert_eq!(response.status, enums::AttemptStatus::Voided); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Refunds a payment using the manual capture flow (Non 3DS). | ||||||
|  | #[actix_web::test] | ||||||
|  | async fn should_refund_manually_captured_payment() { | ||||||
|  |     let response = CONNECTOR | ||||||
|  |         .capture_payment_and_refund( | ||||||
|  |             payment_method_details(), | ||||||
|  |             None, | ||||||
|  |             None, | ||||||
|  |             get_default_payment_info(), | ||||||
|  |         ) | ||||||
|  |         .await | ||||||
|  |         .unwrap(); | ||||||
|  |     assert_eq!( | ||||||
|  |         response.response.unwrap().refund_status, | ||||||
|  |         enums::RefundStatus::Success, | ||||||
|  |     ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Partially refunds a payment using the manual capture flow (Non 3DS). | ||||||
|  | #[actix_web::test] | ||||||
|  | async fn should_partially_refund_manually_captured_payment() { | ||||||
|  |     let response = CONNECTOR | ||||||
|  |         .capture_payment_and_refund( | ||||||
|  |             payment_method_details(), | ||||||
|  |             None, | ||||||
|  |             Some(types::RefundsData { | ||||||
|  |                 refund_amount: 50, | ||||||
|  |                 ..utils::PaymentRefundType::default().0 | ||||||
|  |             }), | ||||||
|  |             get_default_payment_info(), | ||||||
|  |         ) | ||||||
|  |         .await | ||||||
|  |         .unwrap(); | ||||||
|  |     assert_eq!( | ||||||
|  |         response.response.unwrap().refund_status, | ||||||
|  |         enums::RefundStatus::Success, | ||||||
|  |     ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Synchronizes a refund using the manual capture flow (Non 3DS). | ||||||
|  | #[actix_web::test] | ||||||
|  | async fn should_sync_manually_captured_refund() { | ||||||
|  |     let refund_response = CONNECTOR | ||||||
|  |         .capture_payment_and_refund( | ||||||
|  |             payment_method_details(), | ||||||
|  |             None, | ||||||
|  |             None, | ||||||
|  |             get_default_payment_info(), | ||||||
|  |         ) | ||||||
|  |         .await | ||||||
|  |         .unwrap(); | ||||||
|  |     let response = CONNECTOR | ||||||
|  |         .rsync_retry_till_status_matches( | ||||||
|  |             enums::RefundStatus::Success, | ||||||
|  |             refund_response.response.unwrap().connector_refund_id, | ||||||
|  |             None, | ||||||
|  |             get_default_payment_info(), | ||||||
|  |         ) | ||||||
|  |         .await | ||||||
|  |         .unwrap(); | ||||||
|  |     assert_eq!( | ||||||
|  |         response.response.unwrap().refund_status, | ||||||
|  |         enums::RefundStatus::Success, | ||||||
|  |     ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Creates a payment using the automatic capture flow (Non 3DS). | ||||||
|  | #[actix_web::test] | ||||||
|  | async fn should_make_payment() { | ||||||
|  |     let authorize_response = CONNECTOR | ||||||
|  |         .make_payment(payment_method_details(), get_default_payment_info()) | ||||||
|  |         .await | ||||||
|  |         .unwrap(); | ||||||
|  |     assert_eq!(authorize_response.status, enums::AttemptStatus::Charged); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Synchronizes a payment using the automatic capture flow (Non 3DS). | ||||||
|  | #[actix_web::test] | ||||||
|  | async fn should_sync_auto_captured_payment() { | ||||||
|  |     let authorize_response = CONNECTOR | ||||||
|  |         .make_payment(payment_method_details(), get_default_payment_info()) | ||||||
|  |         .await | ||||||
|  |         .unwrap(); | ||||||
|  |     assert_eq!(authorize_response.status, enums::AttemptStatus::Charged); | ||||||
|  |     let txn_id = utils::get_connector_transaction_id(authorize_response.response); | ||||||
|  |     assert_ne!(txn_id, None, "Empty connector transaction id"); | ||||||
|  |     let response = CONNECTOR | ||||||
|  |         .psync_retry_till_status_matches( | ||||||
|  |             enums::AttemptStatus::Charged, | ||||||
|  |             Some(types::PaymentsSyncData { | ||||||
|  |                 connector_transaction_id: types::ResponseId::ConnectorTransactionId( | ||||||
|  |                     txn_id.unwrap(), | ||||||
|  |                 ), | ||||||
|  |                 capture_method: Some(enums::CaptureMethod::Automatic), | ||||||
|  |                 ..Default::default() | ||||||
|  |             }), | ||||||
|  |             get_default_payment_info(), | ||||||
|  |         ) | ||||||
|  |         .await | ||||||
|  |         .unwrap(); | ||||||
|  |     assert_eq!(response.status, enums::AttemptStatus::Charged,); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Refunds a payment using the automatic capture flow (Non 3DS). | ||||||
|  | #[actix_web::test] | ||||||
|  | async fn should_refund_auto_captured_payment() { | ||||||
|  |     let response = CONNECTOR | ||||||
|  |         .make_payment_and_refund(payment_method_details(), None, get_default_payment_info()) | ||||||
|  |         .await | ||||||
|  |         .unwrap(); | ||||||
|  |     assert_eq!( | ||||||
|  |         response.response.unwrap().refund_status, | ||||||
|  |         enums::RefundStatus::Success, | ||||||
|  |     ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Partially refunds a payment using the automatic capture flow (Non 3DS). | ||||||
|  | #[actix_web::test] | ||||||
|  | async fn should_partially_refund_succeeded_payment() { | ||||||
|  |     let refund_response = CONNECTOR | ||||||
|  |         .make_payment_and_refund( | ||||||
|  |             payment_method_details(), | ||||||
|  |             Some(types::RefundsData { | ||||||
|  |                 refund_amount: 50, | ||||||
|  |                 ..utils::PaymentRefundType::default().0 | ||||||
|  |             }), | ||||||
|  |             get_default_payment_info(), | ||||||
|  |         ) | ||||||
|  |         .await | ||||||
|  |         .unwrap(); | ||||||
|  |     assert_eq!( | ||||||
|  |         refund_response.response.unwrap().refund_status, | ||||||
|  |         enums::RefundStatus::Success, | ||||||
|  |     ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Creates multiple refunds against a payment using the automatic capture flow (Non 3DS). | ||||||
|  | #[actix_web::test] | ||||||
|  | async fn should_refund_succeeded_payment_multiple_times() { | ||||||
|  |     CONNECTOR | ||||||
|  |         .make_payment_and_multiple_refund( | ||||||
|  |             payment_method_details(), | ||||||
|  |             Some(types::RefundsData { | ||||||
|  |                 refund_amount: 50, | ||||||
|  |                 ..utils::PaymentRefundType::default().0 | ||||||
|  |             }), | ||||||
|  |             get_default_payment_info(), | ||||||
|  |         ) | ||||||
|  |         .await; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Synchronizes a refund using the automatic capture flow (Non 3DS). | ||||||
|  | #[actix_web::test] | ||||||
|  | async fn should_sync_refund() { | ||||||
|  |     let refund_response = CONNECTOR | ||||||
|  |         .make_payment_and_refund(payment_method_details(), None, get_default_payment_info()) | ||||||
|  |         .await | ||||||
|  |         .unwrap(); | ||||||
|  |     let response = CONNECTOR | ||||||
|  |         .rsync_retry_till_status_matches( | ||||||
|  |             enums::RefundStatus::Success, | ||||||
|  |             refund_response.response.unwrap().connector_refund_id, | ||||||
|  |             None, | ||||||
|  |             get_default_payment_info(), | ||||||
|  |         ) | ||||||
|  |         .await | ||||||
|  |         .unwrap(); | ||||||
|  |     assert_eq!( | ||||||
|  |         response.response.unwrap().refund_status, | ||||||
|  |         enums::RefundStatus::Success, | ||||||
|  |     ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Cards Negative scenarios | ||||||
|  | // Creates a payment with incorrect CVC. | ||||||
|  | #[actix_web::test] | ||||||
|  | async fn should_fail_payment_for_incorrect_cvc() { | ||||||
|  |     let response = CONNECTOR | ||||||
|  |         .make_payment( | ||||||
|  |             Some(types::PaymentsAuthorizeData { | ||||||
|  |                 payment_method_data: PaymentMethodData::Card(Card { | ||||||
|  |                     card_cvc: Secret::new("12345".to_string()), | ||||||
|  |                     ..utils::CCardType::default().0 | ||||||
|  |                 }), | ||||||
|  |                 ..utils::PaymentAuthorizeType::default().0 | ||||||
|  |             }), | ||||||
|  |             get_default_payment_info(), | ||||||
|  |         ) | ||||||
|  |         .await | ||||||
|  |         .unwrap(); | ||||||
|  |     assert_eq!( | ||||||
|  |         response.response.unwrap_err().message, | ||||||
|  |         "Your card's security code is invalid.".to_string(), | ||||||
|  |     ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Creates a payment with incorrect expiry month. | ||||||
|  | #[actix_web::test] | ||||||
|  | async fn should_fail_payment_for_invalid_exp_month() { | ||||||
|  |     let response = CONNECTOR | ||||||
|  |         .make_payment( | ||||||
|  |             Some(types::PaymentsAuthorizeData { | ||||||
|  |                 payment_method_data: PaymentMethodData::Card(Card { | ||||||
|  |                     card_exp_month: Secret::new("20".to_string()), | ||||||
|  |                     ..utils::CCardType::default().0 | ||||||
|  |                 }), | ||||||
|  |                 ..utils::PaymentAuthorizeType::default().0 | ||||||
|  |             }), | ||||||
|  |             get_default_payment_info(), | ||||||
|  |         ) | ||||||
|  |         .await | ||||||
|  |         .unwrap(); | ||||||
|  |     assert_eq!( | ||||||
|  |         response.response.unwrap_err().message, | ||||||
|  |         "Your card's expiration month is invalid.".to_string(), | ||||||
|  |     ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Creates a payment with incorrect expiry year. | ||||||
|  | #[actix_web::test] | ||||||
|  | async fn should_fail_payment_for_incorrect_expiry_year() { | ||||||
|  |     let response = CONNECTOR | ||||||
|  |         .make_payment( | ||||||
|  |             Some(types::PaymentsAuthorizeData { | ||||||
|  |                 payment_method_data: PaymentMethodData::Card(Card { | ||||||
|  |                     card_exp_year: Secret::new("2000".to_string()), | ||||||
|  |                     ..utils::CCardType::default().0 | ||||||
|  |                 }), | ||||||
|  |                 ..utils::PaymentAuthorizeType::default().0 | ||||||
|  |             }), | ||||||
|  |             get_default_payment_info(), | ||||||
|  |         ) | ||||||
|  |         .await | ||||||
|  |         .unwrap(); | ||||||
|  |     assert_eq!( | ||||||
|  |         response.response.unwrap_err().message, | ||||||
|  |         "Your card's expiration year is invalid.".to_string(), | ||||||
|  |     ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Voids a payment using automatic capture flow (Non 3DS). | ||||||
|  | #[actix_web::test] | ||||||
|  | async fn should_fail_void_payment_for_auto_capture() { | ||||||
|  |     let authorize_response = CONNECTOR | ||||||
|  |         .make_payment(payment_method_details(), get_default_payment_info()) | ||||||
|  |         .await | ||||||
|  |         .unwrap(); | ||||||
|  |     assert_eq!(authorize_response.status, enums::AttemptStatus::Charged); | ||||||
|  |     let txn_id = utils::get_connector_transaction_id(authorize_response.response); | ||||||
|  |     assert_ne!(txn_id, None, "Empty connector transaction id"); | ||||||
|  |     let void_response = CONNECTOR | ||||||
|  |         .void_payment(txn_id.unwrap(), None, get_default_payment_info()) | ||||||
|  |         .await | ||||||
|  |         .unwrap(); | ||||||
|  |     assert_eq!( | ||||||
|  |         void_response.response.unwrap_err().message, | ||||||
|  |         "You cannot cancel this PaymentIntent because it has a status of succeeded." | ||||||
|  |     ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Captures a payment using invalid connector payment id. | ||||||
|  | #[actix_web::test] | ||||||
|  | async fn should_fail_capture_for_invalid_payment() { | ||||||
|  |     let capture_response = CONNECTOR | ||||||
|  |         .capture_payment("123456789".to_string(), None, get_default_payment_info()) | ||||||
|  |         .await | ||||||
|  |         .unwrap(); | ||||||
|  |     assert_eq!( | ||||||
|  |         capture_response.response.unwrap_err().message, | ||||||
|  |         String::from("No such payment_intent: '123456789'") | ||||||
|  |     ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Refunds a payment with refund amount higher than payment amount. | ||||||
|  | #[actix_web::test] | ||||||
|  | async fn should_fail_for_refund_amount_higher_than_payment_amount() { | ||||||
|  |     let response = CONNECTOR | ||||||
|  |         .make_payment_and_refund( | ||||||
|  |             payment_method_details(), | ||||||
|  |             Some(types::RefundsData { | ||||||
|  |                 refund_amount: 150, | ||||||
|  |                 ..utils::PaymentRefundType::default().0 | ||||||
|  |             }), | ||||||
|  |             get_default_payment_info(), | ||||||
|  |         ) | ||||||
|  |         .await | ||||||
|  |         .unwrap(); | ||||||
|  |     assert_eq!( | ||||||
|  |         response.response.unwrap_err().message, | ||||||
|  |         "Refund amount (₹1.50) is greater than charge amount (₹1.00)", | ||||||
|  |     ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Connector dependent test cases goes here | ||||||
|  |  | ||||||
|  | // [#478]: add unit tests for non 3DS, wallets & webhooks in connector tests | ||||||
| @ -31,6 +31,7 @@ mod dlocal; | |||||||
| mod dummyconnector; | mod dummyconnector; | ||||||
| mod ebanx; | mod ebanx; | ||||||
| mod fiserv; | mod fiserv; | ||||||
|  | mod fiservemea; | ||||||
| mod forte; | mod forte; | ||||||
| mod globalpay; | mod globalpay; | ||||||
| mod globepay; | mod globepay; | ||||||
|  | |||||||
| @ -258,6 +258,9 @@ api_secret = "Secret key" | |||||||
| [paybox] | [paybox] | ||||||
| api_key="API Key" | api_key="API Key" | ||||||
|  |  | ||||||
|  | [fiservemea] | ||||||
|  | api_key="API Key" | ||||||
|  |  | ||||||
| [wellsfargopayout] | [wellsfargopayout] | ||||||
| api_key = "Consumer Key" | api_key = "Consumer Key" | ||||||
| key1 = "Gateway Entity Id" | key1 = "Gateway Entity Id" | ||||||
|  | |||||||
| @ -36,6 +36,7 @@ pub struct ConnectorAuthentication { | |||||||
|     pub dummyconnector: Option<HeaderKey>, |     pub dummyconnector: Option<HeaderKey>, | ||||||
|     pub ebanx: Option<HeaderKey>, |     pub ebanx: Option<HeaderKey>, | ||||||
|     pub fiserv: Option<SignatureKey>, |     pub fiserv: Option<SignatureKey>, | ||||||
|  |     pub fiservemea: Option<HeaderKey>, | ||||||
|     pub forte: Option<MultiAuthKey>, |     pub forte: Option<MultiAuthKey>, | ||||||
|     pub globalpay: Option<BodyKey>, |     pub globalpay: Option<BodyKey>, | ||||||
|     pub globepay: Option<BodyKey>, |     pub globepay: Option<BodyKey>, | ||||||
|  | |||||||
| @ -99,6 +99,7 @@ dlocal.base_url = "https://sandbox.dlocal.com/" | |||||||
| dummyconnector.base_url = "http://localhost:8080/dummy-connector" | dummyconnector.base_url = "http://localhost:8080/dummy-connector" | ||||||
| ebanx.base_url = "https://sandbox.ebanxpay.com/" | ebanx.base_url = "https://sandbox.ebanxpay.com/" | ||||||
| fiserv.base_url = "https://cert.api.fiservapps.com/" | fiserv.base_url = "https://cert.api.fiservapps.com/" | ||||||
|  | fiservemea.base_url = "https://prod.emea.api.fiservapps.com/sandbox/ipp/payments-gateway/v2" | ||||||
| forte.base_url = "https://sandbox.forte.net/api/v3" | forte.base_url = "https://sandbox.forte.net/api/v3" | ||||||
| globalpay.base_url = "https://apis.sandbox.globalpay.com/ucp/" | globalpay.base_url = "https://apis.sandbox.globalpay.com/ucp/" | ||||||
| globepay.base_url = "https://pay.globepay.co/" | globepay.base_url = "https://pay.globepay.co/" | ||||||
| @ -184,6 +185,7 @@ cards = [ | |||||||
|     "dummyconnector", |     "dummyconnector", | ||||||
|     "ebanx", |     "ebanx", | ||||||
|     "fiserv", |     "fiserv", | ||||||
|  |     "fiservemea", | ||||||
|     "forte", |     "forte", | ||||||
|     "globalpay", |     "globalpay", | ||||||
|     "globepay", |     "globepay", | ||||||
|  | |||||||
| @ -6,7 +6,7 @@ function find_prev_connector() { | |||||||
|     git checkout $self |     git checkout $self | ||||||
|     cp $self $self.tmp |     cp $self $self.tmp | ||||||
|     # Add new connector to existing list and sort it |     # Add new connector to existing list and sort it | ||||||
|     connectors=(aci adyen adyenplatform airwallex applepay authorizedotnet bambora bamboraapac bankofamerica billwerk bitpay bluesnap boku braintree cashtocode checkout coinbase cryptopay cybersource datatrans dlocal dummyconnector ebanx fiserv forte globalpay globepay gocardless gpayments helcim iatapay itaubank klarna mifinity mollie multisafepay netcetera nexinets noon nuvei opayo opennode paybox payeezy payme payone paypal payu placetopay plaid powertranz prophetpay rapyd razorpay shift4 square stax stripe threedsecureio trustpay tsys volt wellsfargo wellsfargopayout wise worldline worldpay zsl "$1") |     connectors=(aci adyen adyenplatform airwallex applepay authorizedotnet bambora bamboraapac bankofamerica billwerk bitpay bluesnap boku braintree cashtocode checkout coinbase cryptopay cybersource datatrans dlocal dummyconnector ebanx fiserv fiservemea forte globalpay globepay gocardless gpayments helcim iatapay itaubank klarna mifinity mollie multisafepay netcetera nexinets noon nuvei opayo opennode paybox payeezy payme payone paypal payu placetopay plaid powertranz prophetpay rapyd razorpay shift4 square stax stripe threedsecureio trustpay tsys volt wellsfargo wellsfargopayout wise worldline worldpay zsl "$1") | ||||||
|     IFS=$'\n' sorted=($(sort <<<"${connectors[*]}")); unset IFS |     IFS=$'\n' sorted=($(sort <<<"${connectors[*]}")); unset IFS | ||||||
|     res=`echo ${sorted[@]}` |     res=`echo ${sorted[@]}` | ||||||
|     sed -i'' -e "s/^    connectors=.*/    connectors=($res \"\$1\")/" $self.tmp |     sed -i'' -e "s/^    connectors=.*/    connectors=($res \"\$1\")/" $self.tmp | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 DEEPANSHU BANSAL
					DEEPANSHU BANSAL