diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json index cedd4abcca..61ad3bf976 100644 --- a/api-reference-v2/openapi_spec.json +++ b/api-reference-v2/openapi_spec.json @@ -6967,6 +6967,7 @@ "cashtocode", "checkout", "coinbase", + "coingate", "cryptopay", "ctp_mastercard", "cybersource", @@ -19316,6 +19317,7 @@ "cashtocode", "checkout", "coinbase", + "coingate", "cryptopay", "cybersource", "datatrans", diff --git a/api-reference/openapi_spec.json b/api-reference/openapi_spec.json index e9b5039532..1919e9744f 100644 --- a/api-reference/openapi_spec.json +++ b/api-reference/openapi_spec.json @@ -9533,6 +9533,7 @@ "cashtocode", "checkout", "coinbase", + "coingate", "cryptopay", "ctp_mastercard", "cybersource", @@ -24352,6 +24353,7 @@ "cashtocode", "checkout", "coinbase", + "coingate", "cryptopay", "cybersource", "datatrans", diff --git a/config/config.example.toml b/config/config.example.toml index 17b0d5b8c7..3457d330c9 100644 --- a/config/config.example.toml +++ b/config/config.example.toml @@ -196,7 +196,7 @@ cashtocode.base_url = "https://cluster05.api-test.cashtocode.com" chargebee.base_url = "https://$.chargebee.com/api/" checkout.base_url = "https://api.sandbox.checkout.com/" coinbase.base_url = "https://api.commerce.coinbase.com" -coingate.base_url = "https://api-sandbox.coingate.com/v2" +coingate.base_url = "https://api-sandbox.coingate.com" cryptopay.base_url = "https://business-sandbox.cryptopay.me" cybersource.base_url = "https://apitest.cybersource.com/" datatrans.base_url = "https://api.sandbox.datatrans.com/" diff --git a/config/deployments/integration_test.toml b/config/deployments/integration_test.toml index 952cdff80e..079134e6d0 100644 --- a/config/deployments/integration_test.toml +++ b/config/deployments/integration_test.toml @@ -42,7 +42,7 @@ cashtocode.base_url = "https://cluster05.api-test.cashtocode.com" chargebee.base_url = "https://$.chargebee.com/api/" checkout.base_url = "https://api.sandbox.checkout.com/" coinbase.base_url = "https://api.commerce.coinbase.com" -coingate.base_url = "https://api-sandbox.coingate.com/v2" +coingate.base_url = "https://api-sandbox.coingate.com" cryptopay.base_url = "https://business-sandbox.cryptopay.me" cybersource.base_url = "https://apitest.cybersource.com/" datatrans.base_url = "https://api.sandbox.datatrans.com/" diff --git a/config/deployments/production.toml b/config/deployments/production.toml index ac5a48007e..872845ceb0 100644 --- a/config/deployments/production.toml +++ b/config/deployments/production.toml @@ -46,7 +46,7 @@ cashtocode.base_url = "https://cluster14.api.cashtocode.com" chargebee.base_url = "https://$.chargebee.com/api/" checkout.base_url = "https://api.checkout.com/" coinbase.base_url = "https://api.commerce.coinbase.com" -coingate.base_url = "https://api.coingate.com/v2" +coingate.base_url = "https://api.coingate.com" cryptopay.base_url = "https://business.cryptopay.me/" cybersource.base_url = "https://api.cybersource.com/" datatrans.base_url = "https://api.datatrans.com/" diff --git a/config/deployments/sandbox.toml b/config/deployments/sandbox.toml index 42ec46a6ca..a92deafb20 100644 --- a/config/deployments/sandbox.toml +++ b/config/deployments/sandbox.toml @@ -46,7 +46,7 @@ cashtocode.base_url = "https://cluster05.api-test.cashtocode.com" checkout.base_url = "https://api.sandbox.checkout.com/" chargebee.base_url = "https://$.chargebee.com/api/" coinbase.base_url = "https://api.commerce.coinbase.com" -coingate.base_url = "https://api-sandbox.coingate.com/v2" +coingate.base_url = "https://api-sandbox.coingate.com" cryptopay.base_url = "https://business-sandbox.cryptopay.me" cybersource.base_url = "https://apitest.cybersource.com/" datatrans.base_url = "https://api.sandbox.datatrans.com/" diff --git a/config/development.toml b/config/development.toml index 153c8a996d..13ed82c81f 100644 --- a/config/development.toml +++ b/config/development.toml @@ -266,7 +266,7 @@ cashtocode.base_url = "https://cluster05.api-test.cashtocode.com" chargebee.base_url = "https://$.chargebee.com/api/" checkout.base_url = "https://api.sandbox.checkout.com/" coinbase.base_url = "https://api.commerce.coinbase.com" -coingate.base_url = "https://api-sandbox.coingate.com/v2" +coingate.base_url = "https://api-sandbox.coingate.com" cryptopay.base_url = "https://business-sandbox.cryptopay.me" cybersource.base_url = "https://apitest.cybersource.com/" datatrans.base_url = "https://api.sandbox.datatrans.com/" diff --git a/config/docker_compose.toml b/config/docker_compose.toml index 48581fbea0..0031c37f02 100644 --- a/config/docker_compose.toml +++ b/config/docker_compose.toml @@ -128,7 +128,7 @@ cashtocode.base_url = "https://cluster05.api-test.cashtocode.com" chargebee.base_url = "https://$.chargebee.com/api/" checkout.base_url = "https://api.sandbox.checkout.com/" coinbase.base_url = "https://api.commerce.coinbase.com" -coingate.base_url = "https://api-sandbox.coingate.com/v2" +coingate.base_url = "https://api-sandbox.coingate.com" cryptopay.base_url = "https://business-sandbox.cryptopay.me" cybersource.base_url = "https://apitest.cybersource.com/" datatrans.base_url = "https://api.sandbox.datatrans.com/" diff --git a/crates/common_enums/src/connector_enums.rs b/crates/common_enums/src/connector_enums.rs index ce7335ddea..8a42bc274c 100644 --- a/crates/common_enums/src/connector_enums.rs +++ b/crates/common_enums/src/connector_enums.rs @@ -68,7 +68,7 @@ pub enum RoutableConnectors { // Chargebee, Checkout, Coinbase, - // Coingate, + Coingate, Cryptopay, Cybersource, Datatrans, @@ -206,6 +206,7 @@ pub enum Connector { // Chargebee, Checkout, Coinbase, + Coingate, Cryptopay, CtpMastercard, Cybersource, @@ -359,6 +360,7 @@ impl Connector { | Self::Cashtocode // | Self::Chargebee | Self::Coinbase + |Self::Coingate | Self::Cryptopay | Self::Deutschebank | Self::Digitalvirgo @@ -547,6 +549,7 @@ impl From for Connector { RoutableConnectors::Zsl => Self::Zsl, RoutableConnectors::Xendit => Self::Xendit, RoutableConnectors::Inespay => Self::Inespay, + RoutableConnectors::Coingate => Self::Coingate, } } } diff --git a/crates/connector_configs/src/connector.rs b/crates/connector_configs/src/connector.rs index c24beba0a4..f0cea8d149 100644 --- a/crates/connector_configs/src/connector.rs +++ b/crates/connector_configs/src/connector.rs @@ -173,6 +173,7 @@ pub struct ConnectorConfig { pub cashtocode: Option, pub checkout: Option, pub coinbase: Option, + pub coingate: Option, pub cryptopay: Option, pub cybersource: Option, #[cfg(feature = "payouts")] @@ -338,6 +339,7 @@ impl ConnectorConfig { Connector::Cashtocode => Ok(connector_data.cashtocode), Connector::Checkout => Ok(connector_data.checkout), Connector::Coinbase => Ok(connector_data.coinbase), + Connector::Coingate => Ok(connector_data.coingate), Connector::Cryptopay => Ok(connector_data.cryptopay), Connector::Cybersource => Ok(connector_data.cybersource), Connector::Iatapay => Ok(connector_data.iatapay), diff --git a/crates/connector_configs/toml/development.toml b/crates/connector_configs/toml/development.toml index 72272b425d..c4897b2e78 100644 --- a/crates/connector_configs/toml/development.toml +++ b/crates/connector_configs/toml/development.toml @@ -1159,6 +1159,12 @@ api_key="API Key" [coinbase.connector_webhook_details] merchant_secret="Source verification key" +[coingate] +[[coingate.crypto]] + payment_method_type = "crypto_currency" +[coingate.connector_auth.HeaderKey] +api_key="API Key" + [cryptopay] [[cryptopay.crypto]] payment_method_type = "crypto_currency" diff --git a/crates/connector_configs/toml/production.toml b/crates/connector_configs/toml/production.toml index 13f0409ebf..9251edf900 100644 --- a/crates/connector_configs/toml/production.toml +++ b/crates/connector_configs/toml/production.toml @@ -996,6 +996,14 @@ api_key="API Key" [coinbase.connector_webhook_details] merchant_secret="Source verification key" + +[coingate] +[[coingate.crypto]] + payment_method_type = "crypto_currency" +[coingate.connector_auth.HeaderKey] +api_key="API Key" + + [cybersource] [[cybersource.credit]] payment_method_type = "Mastercard" diff --git a/crates/connector_configs/toml/sandbox.toml b/crates/connector_configs/toml/sandbox.toml index 70895d48c8..c13349325d 100644 --- a/crates/connector_configs/toml/sandbox.toml +++ b/crates/connector_configs/toml/sandbox.toml @@ -1157,6 +1157,12 @@ api_key="API Key" [coinbase.connector_webhook_details] merchant_secret="Source verification key" +[coingate] +[[coingate.crypto]] + payment_method_type = "crypto_currency" +[coingate.connector_auth.HeaderKey] +api_key="API Key" + [cryptopay] [[cryptopay.crypto]] payment_method_type = "crypto_currency" diff --git a/crates/hyperswitch_connectors/src/connectors/coingate.rs b/crates/hyperswitch_connectors/src/connectors/coingate.rs index e3bece084b..81bb911695 100644 --- a/crates/hyperswitch_connectors/src/connectors/coingate.rs +++ b/crates/hyperswitch_connectors/src/connectors/coingate.rs @@ -1,10 +1,11 @@ pub mod transformers; +use common_enums::{CaptureMethod, PaymentMethod, PaymentMethodType}; use common_utils::{ errors::CustomResult, ext_traits::BytesExt, request::{Method, Request, RequestBuilder, RequestContent}, - types::{AmountConvertor, StringMinorUnit, StringMinorUnitForConnector}, + types::{AmountConvertor, StringMajorUnit, StringMajorUnitForConnector}, }; use error_stack::{report, ResultExt}; use hyperswitch_domain_models::{ @@ -31,25 +32,26 @@ use hyperswitch_interfaces::{ ConnectorValidation, }, configs::Connectors, + consts::NO_ERROR_CODE, errors, events::connector_api_logs::ConnectorEvent, types::{self, Response}, webhooks, }; -use masking::{ExposeInterface, Mask}; +use masking::{Mask, PeekInterface}; use transformers as coingate; use crate::{constants::headers, types::ResponseRouterData, utils}; #[derive(Clone)] pub struct Coingate { - amount_converter: &'static (dyn AmountConvertor + Sync), + amount_converter: &'static (dyn AmountConvertor + Sync), } impl Coingate { pub fn new() -> &'static Self { &Self { - amount_converter: &StringMinorUnitForConnector, + amount_converter: &StringMajorUnitForConnector, } } } @@ -70,7 +72,6 @@ impl api::PaymentToken for Coingate {} impl ConnectorIntegration for Coingate { - // Not Implemented (R) } impl ConnectorCommonExt for Coingate @@ -99,13 +100,10 @@ impl ConnectorCommon for Coingate { 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" + "application/x-www-form-urlencoded" } fn base_url<'a>(&self, connectors: &'a Connectors) -> &'a str { @@ -120,7 +118,7 @@ impl ConnectorCommon for Coingate { .change_context(errors::ConnectorError::FailedToObtainAuthType)?; Ok(vec![( headers::AUTHORIZATION.to_string(), - auth.api_key.expose().into_masked(), + format!("Bearer {}", auth.api_key.peek()).into_masked(), )]) } @@ -139,19 +137,15 @@ impl ConnectorCommon for Coingate { Ok(ErrorResponse { status_code: res.status_code, - code: response.code, + code: NO_ERROR_CODE.to_string(), message: response.message, - reason: response.reason, + reason: Some(response.reason), attempt_status: None, connector_transaction_id: None, }) } } -impl ConnectorValidation for Coingate { - //TODO: implement functions when support enabled -} - impl ConnectorIntegration for Coingate { //TODO: implement sessions flow } @@ -179,9 +173,9 @@ impl ConnectorIntegration CustomResult { - Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + Ok(format!("{}{}", self.base_url(connectors), "/api/v2/orders")) } fn get_request_body( @@ -197,7 +191,7 @@ impl ConnectorIntegration for Coi fn get_url( &self, - _req: &PaymentsSyncRouterData, - _connectors: &Connectors, + req: &PaymentsSyncRouterData, + connectors: &Connectors, ) -> CustomResult { - Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + let connector_id = req + .request + .connector_transaction_id + .get_connector_transaction_id() + .change_context(errors::ConnectorError::MissingConnectorTransactionID)?; + Ok(format!( + "{}/{}{}", + self.base_url(connectors), + "api/v2/orders/", + connector_id + )) } fn build_request( @@ -315,232 +319,78 @@ impl ConnectorIntegration for Coi } impl ConnectorIntegration for Coingate { - fn get_headers( - &self, - req: &PaymentsCaptureRouterData, - connectors: &Connectors, - ) -> CustomResult)>, 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 { - Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) - } - - fn get_request_body( - &self, - _req: &PaymentsCaptureRouterData, - _connectors: &Connectors, - ) -> CustomResult { - Err(errors::ConnectorError::NotImplemented("get_request_body method".to_string()).into()) - } - fn build_request( &self, - req: &PaymentsCaptureRouterData, - connectors: &Connectors, + _req: &PaymentsCaptureRouterData, + _connectors: &Connectors, ) -> CustomResult, 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 { - let response: coingate::CoingatePaymentsResponse = res - .response - .parse_struct("Coingate 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 { - self.build_error_response(res, event_builder) + Err(errors::ConnectorError::FlowNotSupported { + flow: "Capture".to_string(), + connector: "Coingate".to_string(), + } + .into()) } } -impl ConnectorIntegration for Coingate {} +impl ConnectorIntegration for Coingate { + fn build_request( + &self, + _req: &RouterData, + _connectors: &Connectors, + ) -> CustomResult, errors::ConnectorError> { + Err(errors::ConnectorError::FlowNotSupported { + flow: "Void".to_string(), + connector: "Coingate".to_string(), + } + .into()) + } +} impl ConnectorIntegration for Coingate { - fn get_headers( - &self, - req: &RefundsRouterData, - connectors: &Connectors, - ) -> CustomResult)>, errors::ConnectorError> { - self.build_headers(req, connectors) - } - - fn get_content_type(&self) -> &'static str { - self.common_get_content_type() - } - - fn get_url( + fn build_request( &self, _req: &RefundsRouterData, _connectors: &Connectors, - ) -> CustomResult { - Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) - } - - fn get_request_body( - &self, - req: &RefundsRouterData, - _connectors: &Connectors, - ) -> CustomResult { - let refund_amount = utils::convert_amount( - self.amount_converter, - req.request.minor_refund_amount, - req.request.currency, - )?; - - let connector_router_data = coingate::CoingateRouterData::from((refund_amount, req)); - let connector_req = coingate::CoingateRefundRequest::try_from(&connector_router_data)?; - Ok(RequestContent::Json(Box::new(connector_req))) - } - - fn build_request( - &self, - req: &RefundsRouterData, - connectors: &Connectors, ) -> CustomResult, 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, - event_builder: Option<&mut ConnectorEvent>, - res: Response, - ) -> CustomResult, errors::ConnectorError> { - let response: coingate::RefundResponse = res - .response - .parse_struct("coingate 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 { - self.build_error_response(res, event_builder) + Err(errors::ConnectorError::FlowNotSupported { + flow: "RefundSync".to_string(), + connector: "Coingate".to_string(), + } + .into()) } } impl ConnectorIntegration for Coingate { - fn get_headers( - &self, - req: &RefundSyncRouterData, - connectors: &Connectors, - ) -> CustomResult)>, errors::ConnectorError> { - self.build_headers(req, connectors) - } - - fn get_content_type(&self) -> &'static str { - self.common_get_content_type() - } - - fn get_url( + fn build_request( &self, _req: &RefundSyncRouterData, _connectors: &Connectors, - ) -> CustomResult { - Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) - } - - fn build_request( - &self, - req: &RefundSyncRouterData, - connectors: &Connectors, ) -> CustomResult, 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(), - )) + Err(errors::ConnectorError::FlowNotSupported { + flow: "Refund".to_string(), + connector: "Coingate".to_string(), + } + .into()) } +} - fn handle_response( +impl ConnectorValidation for Coingate { + fn validate_connector_against_payment_request( &self, - data: &RefundSyncRouterData, - event_builder: Option<&mut ConnectorEvent>, - res: Response, - ) -> CustomResult { - let response: coingate::RefundResponse = res - .response - .parse_struct("coingate 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 { - self.build_error_response(res, event_builder) + capture_method: Option, + _payment_method: PaymentMethod, + _pmt: Option, + ) -> CustomResult<(), errors::ConnectorError> { + let capture_method = capture_method.unwrap_or_default(); + match capture_method { + CaptureMethod::Automatic | CaptureMethod::SequentialAutomatic => Ok(()), + CaptureMethod::ManualMultiple | CaptureMethod::Scheduled | CaptureMethod::Manual => { + Err(utils::construct_not_supported_error_report( + capture_method, + self.id(), + )) + } + } } } diff --git a/crates/hyperswitch_connectors/src/connectors/coingate/transformers.rs b/crates/hyperswitch_connectors/src/connectors/coingate/transformers.rs index 831f30453e..77128580c2 100644 --- a/crates/hyperswitch_connectors/src/connectors/coingate/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/coingate/transformers.rs @@ -1,31 +1,27 @@ -use common_enums::enums; -use common_utils::types::StringMinorUnit; +use std::collections::HashMap; + +use common_enums::{enums, Currency}; +use common_utils::{request::Method, types::StringMajorUnit}; 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}, + router_response_types::{PaymentsResponseData, RedirectForm}, + types::PaymentsAuthorizeRouterData, }; use hyperswitch_interfaces::errors; use masking::Secret; use serde::{Deserialize, Serialize}; -use crate::{ - types::{RefundsResponseRouterData, ResponseRouterData}, - utils::PaymentsAuthorizeRequestData, -}; +use crate::{types::ResponseRouterData, utils}; -//TODO: Fill the struct with respective fields pub struct CoingateRouterData { - pub amount: StringMinorUnit, // The type of amount that a connector accepts, for example, String, i64, f64, etc. + pub amount: StringMajorUnit, pub router_data: T, } -impl From<(StringMinorUnit, T)> for CoingateRouterData { - fn from((amount, item): (StringMinorUnit, T)) -> Self { - //Todo : use utils to convert the amount to the type of amount that a connector accepts +impl From<(StringMajorUnit, T)> for CoingateRouterData { + fn from((amount, item): (StringMajorUnit, T)) -> Self { Self { amount, router_data: item, @@ -33,20 +29,15 @@ impl From<(StringMinorUnit, T)> for CoingateRouterData { } } -//TODO: Fill the struct with respective fields #[derive(Default, Debug, Serialize, PartialEq)] pub struct CoingatePaymentsRequest { - amount: StringMinorUnit, - card: CoingateCard, -} - -#[derive(Default, Debug, Serialize, Eq, PartialEq)] -pub struct CoingateCard { - number: cards::CardNumber, - expiry_month: Secret, - expiry_year: Secret, - cvc: Secret, - complete: bool, + price_amount: StringMajorUnit, + price_currency: Currency, + receive_currency: String, + callback_url: Option, + success_url: Option, + cancel_url: Option, + title: String, } impl TryFrom<&CoingateRouterData<&PaymentsAuthorizeRouterData>> for CoingatePaymentsRequest { @@ -54,27 +45,23 @@ impl TryFrom<&CoingateRouterData<&PaymentsAuthorizeRouterData>> for CoingatePaym fn try_from( item: &CoingateRouterData<&PaymentsAuthorizeRouterData>, ) -> Result { - match item.router_data.request.payment_method_data.clone() { - PaymentMethodData::Card(req_card) => { - let card = CoingateCard { - 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 method".to_string()).into()), - } + Ok(match item.router_data.request.payment_method_data { + PaymentMethodData::Crypto(_) => Ok(Self { + price_amount: item.amount.clone(), + price_currency: item.router_data.request.currency, + receive_currency: "DO_NOT_CONVERT".to_string(), + callback_url: item.router_data.request.router_return_url.clone(), + success_url: item.router_data.request.router_return_url.clone(), + cancel_url: item.router_data.request.router_return_url.clone(), + title: item.router_data.connector_request_reference_id.clone(), + }), + _ => Err(errors::ConnectorError::NotImplemented( + utils::get_unimplemented_payment_method_error_message("Coingate"), + )), + }?) } } -//TODO: Fill the struct with respective fields -// Auth Struct pub struct CoingateAuthType { pub(super) api_key: Secret, } @@ -90,32 +77,40 @@ impl TryFrom<&ConnectorAuthType> for CoingateAuthType { } } } -// PaymentsResponse -//TODO: Append the remaining status flags -#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)] + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "lowercase")] pub enum CoingatePaymentStatus { - Succeeded, - Failed, - #[default] - Processing, + New, + Pending, + Confirming, + Paid, + Invalid, + Expired, + Canceled, } impl From for common_enums::AttemptStatus { fn from(item: CoingatePaymentStatus) -> Self { match item { - CoingatePaymentStatus::Succeeded => Self::Charged, - CoingatePaymentStatus::Failed => Self::Failure, - CoingatePaymentStatus::Processing => Self::Authorizing, + CoingatePaymentStatus::Paid => Self::Charged, + CoingatePaymentStatus::Canceled + | CoingatePaymentStatus::Expired + | CoingatePaymentStatus::Invalid => Self::Failure, + CoingatePaymentStatus::Confirming | CoingatePaymentStatus::New => { + Self::AuthenticationPending + } + CoingatePaymentStatus::Pending => Self::Pending, } } } -//TODO: Fill the struct with respective fields -#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct CoingatePaymentsResponse { status: CoingatePaymentStatus, - id: String, + id: i64, + payment_url: String, + order_id: String, } impl TryFrom> @@ -126,14 +121,18 @@ impl TryFrom, ) -> Result { Ok(Self { - status: common_enums::AttemptStatus::from(item.response.status), + status: enums::AttemptStatus::from(item.response.status.clone()), response: Ok(PaymentsResponseData::TransactionResponse { - resource_id: ResponseId::ConnectorTransactionId(item.response.id), - redirection_data: Box::new(None), + resource_id: ResponseId::ConnectorTransactionId(item.response.id.to_string()), + redirection_data: Box::new(Some(RedirectForm::Form { + endpoint: item.response.payment_url.clone(), + method: Method::Get, + form_fields: HashMap::new(), + })), mandate_reference: Box::new(None), connector_metadata: None, network_txn_id: None, - connector_response_reference_id: None, + connector_response_reference_id: Some(item.response.order_id.clone()), incremental_authorization_allowed: None, charges: None, }), @@ -141,88 +140,9 @@ impl TryFrom TryFrom<&CoingateRouterData<&RefundsRouterData>> for CoingateRefundRequest { - type Error = error_stack::Report; - fn try_from(item: &CoingateRouterData<&RefundsRouterData>) -> Result { - 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 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> for RefundsRouterData { - type Error = error_stack::Report; - fn try_from( - item: RefundsResponseRouterData, - ) -> Result { - 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> for RefundsRouterData { - type Error = error_stack::Report; - fn try_from( - item: RefundsResponseRouterData, - ) -> Result { - 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 CoingateErrorResponse { pub status_code: u16, - pub code: String, pub message: String, - pub reason: Option, + pub reason: String, } diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs index 958dbf7438..cdca5883f4 100644 --- a/crates/router/src/core/admin.rs +++ b/crates/router/src/core/admin.rs @@ -1317,6 +1317,10 @@ impl ConnectorAuthTypeAndMetadataValidation<'_> { coinbase::transformers::CoinbaseConnectorMeta::try_from(self.connector_meta_data)?; Ok(()) } + api_enums::Connector::Coingate => { + coingate::transformers::CoingateAuthType::try_from(self.auth_type)?; + Ok(()) + } api_enums::Connector::Cryptopay => { cryptopay::transformers::CryptopayAuthType::try_from(self.auth_type)?; Ok(()) diff --git a/crates/router/src/types/api.rs b/crates/router/src/types/api.rs index 11f2a1902d..1a702cb835 100644 --- a/crates/router/src/types/api.rs +++ b/crates/router/src/types/api.rs @@ -368,7 +368,9 @@ impl ConnectorData { enums::Connector::Coinbase => { Ok(ConnectorEnum::Old(Box::new(&connector::Coinbase))) } - // enums::Connector::Coingate => Ok(ConnectorEnum::Old(Box::new(connector::Coingate))), + enums::Connector::Coingate => { + Ok(ConnectorEnum::Old(Box::new(connector::Coingate::new()))) + } enums::Connector::Cryptopay => { Ok(ConnectorEnum::Old(Box::new(connector::Cryptopay::new()))) } diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs index 99ed67ff83..f8f8830fda 100644 --- a/crates/router/src/types/transformers.rs +++ b/crates/router/src/types/transformers.rs @@ -228,7 +228,7 @@ impl ForeignTryFrom for common_enums::RoutableConnectors { // api_enums::Connector::Chargebee => Self::Chargebee, api_enums::Connector::Checkout => Self::Checkout, api_enums::Connector::Coinbase => Self::Coinbase, - // api_enums::Connector::Coingate => Self::Coingate, + api_enums::Connector::Coingate => Self::Coingate, api_enums::Connector::Cryptopay => Self::Cryptopay, api_enums::Connector::CtpMastercard => { Err(common_utils::errors::ValidationError::InvalidValue { diff --git a/loadtest/config/development.toml b/loadtest/config/development.toml index ed2ea37307..6766d7cb7e 100644 --- a/loadtest/config/development.toml +++ b/loadtest/config/development.toml @@ -94,7 +94,7 @@ cashtocode.base_url = "https://cluster05.api-test.cashtocode.com" chargebee.base_url = "https://$.chargebee.com/api/" checkout.base_url = "https://api.sandbox.checkout.com/" coinbase.base_url = "https://api.commerce.coinbase.com" -coingate.base_url = "https://api-sandbox.coingate.com/v2" +coingate.base_url = "https://api-sandbox.coingate.com" cryptopay.base_url = "https://business-sandbox.cryptopay.me" cybersource.base_url = "https://apitest.cybersource.com/" datatrans.base_url = "https://api.sandbox.datatrans.com/"