diff --git a/config/config.example.toml b/config/config.example.toml index 40590128a5d4..02eff1d42979 100644 --- a/config/config.example.toml +++ b/config/config.example.toml @@ -417,6 +417,9 @@ ach = { currency = "USD" } [pm_filters.stripe] cashapp = {country = "US", currency = "USD"} +[pm_filters.prophetpay] +card_redirect = { currency = "USD" } + [connector_customer] connector_list = "gocardless,stax,stripe" payout_connector_list = "wise" diff --git a/config/development.toml b/config/development.toml index d3cad47a23fc..c82607a704c3 100644 --- a/config/development.toml +++ b/config/development.toml @@ -355,6 +355,9 @@ credit = { currency = "USD" } debit = { currency = "USD" } ach = { currency = "USD" } +[pm_filters.prophetpay] +card_redirect = { currency = "USD" } + [pm_filters.trustpay] credit = { not_available_flows = { capture_method = "manual" } } debit = { not_available_flows = { capture_method = "manual" } } diff --git a/config/docker_compose.toml b/config/docker_compose.toml index 39e8fad0fcaa..a5294546de41 100644 --- a/config/docker_compose.toml +++ b/config/docker_compose.toml @@ -285,6 +285,9 @@ red_pagos = { country = "UY", currency = "UYU" } [pm_filters.stripe] cashapp = {country = "US", currency = "USD"} +[pm_filters.prophetpay] +card_redirect = { currency = "USD" } + [pm_filters.stax] credit = { currency = "USD" } debit = { currency = "USD" } diff --git a/crates/api_models/src/enums.rs b/crates/api_models/src/enums.rs index 493a421ece36..c4e4aa90c4b8 100644 --- a/crates/api_models/src/enums.rs +++ b/crates/api_models/src/enums.rs @@ -108,7 +108,7 @@ pub enum Connector { Paypal, Payu, Powertranz, - // Prophetpay, added as a template code for future usage + Prophetpay, Rapyd, Shift4, Square, @@ -229,7 +229,7 @@ pub enum RoutableConnectors { Paypal, Payu, Powertranz, - // Prophetpay, added as a template code for future usage + Prophetpay, Rapyd, Shift4, Square, diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index cf0259f26951..d924fb2e4f62 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -704,6 +704,7 @@ pub enum CardRedirectData { Knet {}, Benefit {}, MomoAtm {}, + CardRedirect {}, } #[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)] @@ -868,6 +869,7 @@ impl GetPaymentMethodType for CardRedirectData { Self::Knet {} => api_enums::PaymentMethodType::Knet, Self::Benefit {} => api_enums::PaymentMethodType::Benefit, Self::MomoAtm {} => api_enums::PaymentMethodType::MomoAtm, + Self::CardRedirect {} => api_enums::PaymentMethodType::CardRedirect, } } } diff --git a/crates/api_models/src/routing.rs b/crates/api_models/src/routing.rs index 650c4517f1b1..47a44ea7443e 100644 --- a/crates/api_models/src/routing.rs +++ b/crates/api_models/src/routing.rs @@ -337,6 +337,7 @@ impl From for ast::ConnectorChoice { RoutableConnectors::Paypal => euclid_enums::Connector::Paypal, RoutableConnectors::Payu => euclid_enums::Connector::Payu, RoutableConnectors::Powertranz => euclid_enums::Connector::Powertranz, + RoutableConnectors::Prophetpay => euclid_enums::Connector::Prophetpay, RoutableConnectors::Rapyd => euclid_enums::Connector::Rapyd, RoutableConnectors::Shift4 => euclid_enums::Connector::Shift4, RoutableConnectors::Square => euclid_enums::Connector::Square, diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs index f0386fc2f42e..48b0664c16d3 100644 --- a/crates/common_enums/src/enums.rs +++ b/crates/common_enums/src/enums.rs @@ -990,6 +990,7 @@ pub enum PaymentMethodType { BcaBankTransfer, BniVa, BriVa, + CardRedirect, CimbVa, #[serde(rename = "classic")] ClassicReward, diff --git a/crates/common_enums/src/transformers.rs b/crates/common_enums/src/transformers.rs index 73f736cdeefa..63abfdb3f73a 100644 --- a/crates/common_enums/src/transformers.rs +++ b/crates/common_enums/src/transformers.rs @@ -1807,6 +1807,7 @@ impl From for PaymentMethod { PaymentMethodType::Bizum => Self::BankRedirect, PaymentMethodType::Blik => Self::BankRedirect, PaymentMethodType::Alfamart => Self::Voucher, + PaymentMethodType::CardRedirect => Self::CardRedirect, PaymentMethodType::CimbVa => Self::BankTransfer, PaymentMethodType::ClassicReward => Self::Reward, PaymentMethodType::Credit => Self::Card, diff --git a/crates/common_utils/src/consts.rs b/crates/common_utils/src/consts.rs index 7bc248bf8d1b..60756192d66e 100644 --- a/crates/common_utils/src/consts.rs +++ b/crates/common_utils/src/consts.rs @@ -41,3 +41,9 @@ pub const DEFAULT_PRODUCT_IMG: &str = "https://i.imgur.com/On3VtKF.png"; /// Default Merchant Logo Link pub const DEFAULT_MERCHANT_LOGO: &str = "https://i.imgur.com/RfxPFQo.png"; + +/// Redirect url for Prophetpay +pub const PROPHETPAY_REDIRECT_URL: &str = "https://ccm-thirdparty.cps.golf/hp/tokenize/"; + +/// Variable which store the card token for Prophetpay +pub const PROPHETPAY_TOKEN: &str = "cctoken"; diff --git a/crates/euclid/src/enums.rs b/crates/euclid/src/enums.rs index da5c99816715..dc6d9f66a58f 100644 --- a/crates/euclid/src/enums.rs +++ b/crates/euclid/src/enums.rs @@ -117,6 +117,7 @@ pub enum Connector { Paypal, Payu, Powertranz, + Prophetpay, Rapyd, Shift4, Square, diff --git a/crates/euclid/src/frontend/dir/enums.rs b/crates/euclid/src/frontend/dir/enums.rs index 17699940363f..f049ad35328e 100644 --- a/crates/euclid/src/frontend/dir/enums.rs +++ b/crates/euclid/src/frontend/dir/enums.rs @@ -225,6 +225,7 @@ pub enum CardRedirectType { Benefit, Knet, MomoAtm, + CardRedirect, } #[derive( diff --git a/crates/euclid/src/frontend/dir/lowering.rs b/crates/euclid/src/frontend/dir/lowering.rs index 516e10e0389e..b1f03e8dd557 100644 --- a/crates/euclid/src/frontend/dir/lowering.rs +++ b/crates/euclid/src/frontend/dir/lowering.rs @@ -134,6 +134,7 @@ impl From for global_enums::PaymentMethodType { enums::CardRedirectType::Benefit => Self::Benefit, enums::CardRedirectType::Knet => Self::Knet, enums::CardRedirectType::MomoAtm => Self::MomoAtm, + enums::CardRedirectType::CardRedirect => Self::CardRedirect, } } } diff --git a/crates/euclid/src/frontend/dir/transformers.rs b/crates/euclid/src/frontend/dir/transformers.rs index da413d380c0f..c99b39e36f46 100644 --- a/crates/euclid/src/frontend/dir/transformers.rs +++ b/crates/euclid/src/frontend/dir/transformers.rs @@ -161,6 +161,9 @@ impl IntoDirValue for (global_enums::PaymentMethodType, global_enums::PaymentMet } global_enums::PaymentMethodType::MomoAtm => Ok(dirval!(CardRedirectType = MomoAtm)), global_enums::PaymentMethodType::Oxxo => Ok(dirval!(VoucherType = Oxxo)), + global_enums::PaymentMethodType::CardRedirect => { + Ok(dirval!(CardRedirectType = CardRedirect)) + } } } } diff --git a/crates/kgraph_utils/src/transformers.rs b/crates/kgraph_utils/src/transformers.rs index 3d32cce38bd8..b1636418aa17 100644 --- a/crates/kgraph_utils/src/transformers.rs +++ b/crates/kgraph_utils/src/transformers.rs @@ -280,6 +280,9 @@ impl IntoDirValue for (api_enums::PaymentMethodType, api_enums::PaymentMethod) { } api_enums::PaymentMethodType::MomoAtm => Ok(dirval!(CardRedirectType = MomoAtm)), api_enums::PaymentMethodType::Oxxo => Ok(dirval!(VoucherType = Oxxo)), + api_enums::PaymentMethodType::CardRedirect => { + Ok(dirval!(CardRedirectType = CardRedirect)) + } } } } diff --git a/crates/router/src/connector/adyen/transformers.rs b/crates/router/src/connector/adyen/transformers.rs index 8bb287812800..ec21c9baa5e9 100644 --- a/crates/router/src/connector/adyen/transformers.rs +++ b/crates/router/src/connector/adyen/transformers.rs @@ -2201,6 +2201,12 @@ impl<'a> TryFrom<&api_models::payments::CardRedirectData> for AdyenPaymentMethod payments::CardRedirectData::Knet {} => Ok(AdyenPaymentMethod::Knet), payments::CardRedirectData::Benefit {} => Ok(AdyenPaymentMethod::Benefit), payments::CardRedirectData::MomoAtm {} => Ok(AdyenPaymentMethod::MomoAtm), + payments::CardRedirectData::CardRedirect {} => { + Err(errors::ConnectorError::NotImplemented( + utils::get_unimplemented_payment_method_error_message("Adyen"), + ) + .into()) + } } } } diff --git a/crates/router/src/connector/klarna.rs b/crates/router/src/connector/klarna.rs index 8737d2b30474..3670f65a2f02 100644 --- a/crates/router/src/connector/klarna.rs +++ b/crates/router/src/connector/klarna.rs @@ -323,6 +323,7 @@ impl | api_models::enums::PaymentMethodType::BcaBankTransfer | api_models::enums::PaymentMethodType::BniVa | api_models::enums::PaymentMethodType::BriVa + | api_models::enums::PaymentMethodType::CardRedirect | api_models::enums::PaymentMethodType::CimbVa | api_models::enums::PaymentMethodType::ClassicReward | api_models::enums::PaymentMethodType::Credit diff --git a/crates/router/src/connector/paypal/transformers.rs b/crates/router/src/connector/paypal/transformers.rs index 0092363523e5..5468c6bb8061 100644 --- a/crates/router/src/connector/paypal/transformers.rs +++ b/crates/router/src/connector/paypal/transformers.rs @@ -439,7 +439,8 @@ impl TryFrom<&api_models::payments::CardRedirectData> for PaypalPaymentsRequest match value { api_models::payments::CardRedirectData::Knet {} | api_models::payments::CardRedirectData::Benefit {} - | api_models::payments::CardRedirectData::MomoAtm {} => { + | api_models::payments::CardRedirectData::MomoAtm {} + | api_models::payments::CardRedirectData::CardRedirect {} => { Err(errors::ConnectorError::NotSupported { message: utils::SELECTED_PAYMENT_METHOD.to_string(), connector: "Paypal", diff --git a/crates/router/src/connector/prophetpay.rs b/crates/router/src/connector/prophetpay.rs index 417c34207e05..6765fad2653d 100644 --- a/crates/router/src/connector/prophetpay.rs +++ b/crates/router/src/connector/prophetpay.rs @@ -2,12 +2,14 @@ pub mod transformers; use std::fmt::Debug; +use base64::Engine; use error_stack::{IntoReport, ResultExt}; -use masking::ExposeInterface; +use masking::PeekInterface; use transformers as prophetpay; use crate::{ configs::settings, + consts, core::errors::{self, CustomResult}, headers, services::{ @@ -37,6 +39,7 @@ impl api::Refund for Prophetpay {} impl api::RefundExecute for Prophetpay {} impl api::RefundSync for Prophetpay {} impl api::PaymentToken for Prophetpay {} +impl api::payments::PaymentsCompleteAuthorize for Prophetpay {} impl ConnectorIntegration< @@ -73,7 +76,7 @@ impl ConnectorCommon for Prophetpay { } fn get_currency_unit(&self) -> api::CurrencyUnit { - api::CurrencyUnit::Minor + api::CurrencyUnit::Base } fn common_get_content_type(&self) -> &'static str { @@ -90,9 +93,13 @@ impl ConnectorCommon for Prophetpay { ) -> CustomResult)>, errors::ConnectorError> { let auth = prophetpay::ProphetpayAuthType::try_from(auth_type) .change_context(errors::ConnectorError::FailedToObtainAuthType)?; + + let auth_val = format!("{}:{}", auth.user_name.peek(), auth.password.peek()); + let basic_token = format!("Basic {}", consts::BASE64_ENGINE.encode(auth_val)); + Ok(vec![( headers::AUTHORIZATION.to_string(), - auth.api_key.expose().into_masked(), + basic_token.into_masked(), )]) } @@ -107,9 +114,9 @@ impl ConnectorCommon for Prophetpay { Ok(ErrorResponse { status_code: res.status_code, - code: response.code, - message: response.message, - reason: response.reason, + code: response.status.to_string(), + message: response.title, + reason: Some(response.errors.to_string()), attempt_status: None, }) } @@ -157,9 +164,12 @@ impl ConnectorIntegration CustomResult { - Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + Ok(format!( + "{}hp/api/HostedTokenize/CreateHostedTokenize", + self.base_url(connectors) + )) } fn get_request_body( @@ -173,10 +183,11 @@ impl ConnectorIntegration::encode_to_string_of_json, + utils::Encode::::encode_to_string_of_json, ) .change_context(errors::ConnectorError::RequestEncodingFailed)?; Ok(Some(prophetpay_req)) @@ -208,10 +219,114 @@ impl ConnectorIntegration CustomResult { - let response: prophetpay::ProphetpayPaymentsResponse = res + ) -> CustomResult + where + types::PaymentsResponseData: Clone, + { + let response: prophetpay::ProphetpayTokenResponse = res .response - .parse_struct("Prophetpay PaymentsAuthorizeResponse") + .parse_struct("prophetpay ProphetpayTokenResponse") + .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; + + types::RouterData::try_from(types::ResponseRouterData { + response, + data: data.clone(), + http_code: res.status_code, + }) + } + + fn get_error_response( + &self, + res: Response, + ) -> CustomResult { + self.build_error_response(res) + } +} + +impl + ConnectorIntegration< + api::CompleteAuthorize, + types::CompleteAuthorizeData, + types::PaymentsResponseData, + > for Prophetpay +{ + fn get_headers( + &self, + req: &types::PaymentsCompleteAuthorizeRouterData, + connectors: &settings::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: &types::PaymentsCompleteAuthorizeRouterData, + connectors: &settings::Connectors, + ) -> CustomResult { + Ok(format!( + "{}hp/api/Transactions/ProcessTransaction", + self.base_url(connectors) + )) + } + + fn get_request_body( + &self, + req: &types::PaymentsCompleteAuthorizeRouterData, + _connectors: &settings::Connectors, + ) -> CustomResult, errors::ConnectorError> { + let connector_router_data = prophetpay::ProphetpayRouterData::try_from(( + &self.get_currency_unit(), + req.request.currency, + req.request.amount, + req, + ))?; + let req_obj = prophetpay::ProphetpayCompleteRequest::try_from(&connector_router_data)?; + + let prophetpay_req = types::RequestBody::log_and_get_request_body( + &req_obj, + utils::Encode::::encode_to_string_of_json, + ) + .change_context(errors::ConnectorError::RequestEncodingFailed)?; + Ok(Some(prophetpay_req)) + } + + fn build_request( + &self, + req: &types::PaymentsCompleteAuthorizeRouterData, + connectors: &settings::Connectors, + ) -> CustomResult, errors::ConnectorError> { + Ok(Some( + services::RequestBuilder::new() + .method(services::Method::Post) + .url(&types::PaymentsCompleteAuthorizeType::get_url( + self, req, connectors, + )?) + .attach_default_headers() + .headers(types::PaymentsCompleteAuthorizeType::get_headers( + self, req, connectors, + )?) + .body(types::PaymentsCompleteAuthorizeType::get_request_body( + self, req, connectors, + )?) + .build(), + )) + } + + fn handle_response( + &self, + data: &types::PaymentsCompleteAuthorizeRouterData, + res: Response, + ) -> CustomResult + where + types::PaymentsResponseData: Clone, + { + let response: prophetpay::ProphetpayResponse = res + .response + .parse_struct("prophetpay ProphetpayResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; types::RouterData::try_from(types::ResponseRouterData { response, @@ -246,9 +361,27 @@ impl ConnectorIntegration CustomResult { - Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + Ok(format!( + "{}hp/api/Transactions/ProcessTransaction", + self.base_url(connectors) + )) + } + + fn get_request_body( + &self, + req: &types::PaymentsSyncRouterData, + _connectors: &settings::Connectors, + ) -> CustomResult, errors::ConnectorError> { + let req_obj = prophetpay::ProphetpaySyncRequest::try_from(req)?; + + let prophetpay_req = types::RequestBody::log_and_get_request_body( + &req_obj, + utils::Encode::::encode_to_string_of_json, + ) + .change_context(errors::ConnectorError::RequestEncodingFailed)?; + Ok(Some(prophetpay_req)) } fn build_request( @@ -258,10 +391,13 @@ impl ConnectorIntegration CustomResult, errors::ConnectorError> { Ok(Some( services::RequestBuilder::new() - .method(services::Method::Get) + .method(services::Method::Post) .url(&types::PaymentsSyncType::get_url(self, req, connectors)?) .attach_default_headers() .headers(types::PaymentsSyncType::get_headers(self, req, connectors)?) + .body(types::PaymentsSyncType::get_request_body( + self, req, connectors, + )?) .build(), )) } @@ -271,9 +407,9 @@ impl ConnectorIntegration CustomResult { - let response: prophetpay::ProphetpayPaymentsResponse = res + let response: prophetpay::ProphetpayResponse = res .response - .parse_struct("prophetpay PaymentsSyncResponse") + .parse_struct("prophetpay ProphetpayResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; types::RouterData::try_from(types::ResponseRouterData { response, @@ -292,10 +428,15 @@ impl ConnectorIntegration for Prophetpay +{ +} + +impl ConnectorIntegration + for Prophetpay { fn get_headers( &self, - req: &types::PaymentsCaptureRouterData, + req: &types::PaymentsCancelRouterData, connectors: &settings::Connectors, ) -> CustomResult)>, errors::ConnectorError> { self.build_headers(req, connectors) @@ -307,34 +448,42 @@ impl ConnectorIntegration CustomResult { - Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + Ok(format!( + "{}hp/api/Transactions/ProcessTransaction", + self.base_url(connectors) + )) } fn get_request_body( &self, - _req: &types::PaymentsCaptureRouterData, + req: &types::PaymentsCancelRouterData, _connectors: &settings::Connectors, ) -> CustomResult, errors::ConnectorError> { - Err(errors::ConnectorError::NotImplemented("get_request_body method".to_string()).into()) + let req_obj = prophetpay::ProphetpayVoidRequest::try_from(req)?; + + let prophetpay_req = types::RequestBody::log_and_get_request_body( + &req_obj, + utils::Encode::::encode_to_string_of_json, + ) + .change_context(errors::ConnectorError::RequestEncodingFailed)?; + Ok(Some(prophetpay_req)) } fn build_request( &self, - req: &types::PaymentsCaptureRouterData, + req: &types::PaymentsCancelRouterData, connectors: &settings::Connectors, ) -> CustomResult, errors::ConnectorError> { Ok(Some( services::RequestBuilder::new() - .method(services::Method::Post) - .url(&types::PaymentsCaptureType::get_url(self, req, connectors)?) + .method(services::Method::Get) + .url(&types::PaymentsVoidType::get_url(self, req, connectors)?) .attach_default_headers() - .headers(types::PaymentsCaptureType::get_headers( - self, req, connectors, - )?) - .body(types::PaymentsCaptureType::get_request_body( + .headers(types::PaymentsVoidType::get_headers(self, req, connectors)?) + .body(types::PaymentsVoidType::get_request_body( self, req, connectors, )?) .build(), @@ -343,12 +492,12 @@ impl ConnectorIntegration CustomResult { - let response: prophetpay::ProphetpayPaymentsResponse = res + ) -> CustomResult { + let response: prophetpay::ProphetpayResponse = res .response - .parse_struct("Prophetpay PaymentsCaptureResponse") + .parse_struct("prophetpay ProphetpayResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; types::RouterData::try_from(types::ResponseRouterData { response, @@ -365,11 +514,6 @@ impl ConnectorIntegration - for Prophetpay -{ -} - impl ConnectorIntegration for Prophetpay { @@ -388,9 +532,12 @@ impl ConnectorIntegration, - _connectors: &settings::Connectors, + connectors: &settings::Connectors, ) -> CustomResult { - Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + Ok(format!( + "{}hp/api/Transactions/ProcessTransaction", + self.base_url(connectors) + )) } fn get_request_body( @@ -437,10 +584,11 @@ impl ConnectorIntegration, res: Response, ) -> CustomResult, errors::ConnectorError> { - let response: prophetpay::RefundResponse = res + let response: prophetpay::ProphetpayRefundResponse = res .response - .parse_struct("prophetpay RefundResponse") + .parse_struct("prophetpay ProphetpayRefundResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; + types::RouterData::try_from(types::ResponseRouterData { response, data: data.clone(), @@ -474,9 +622,27 @@ impl ConnectorIntegration CustomResult { - Err(errors::ConnectorError::NotImplemented("get_url method".to_string()).into()) + Ok(format!( + "{}hp/api/Transactions/ProcessTransaction", + self.base_url(connectors) + )) + } + + fn get_request_body( + &self, + req: &types::RefundSyncRouterData, + _connectors: &settings::Connectors, + ) -> CustomResult, errors::ConnectorError> { + let req_obj = prophetpay::ProphetpayRefundSyncRequest::try_from(req)?; + + let prophetpay_req = types::RequestBody::log_and_get_request_body( + &req_obj, + utils::Encode::::encode_to_string_of_json, + ) + .change_context(errors::ConnectorError::RequestEncodingFailed)?; + Ok(Some(prophetpay_req)) } fn build_request( @@ -502,9 +668,9 @@ impl ConnectorIntegration CustomResult { - let response: prophetpay::RefundResponse = res + let response: prophetpay::ProphetpayRefundResponse = res .response - .parse_struct("prophetpay RefundSyncResponse") + .parse_struct("prophetpay ProphetpayRefundResponse") .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; types::RouterData::try_from(types::ResponseRouterData { response, diff --git a/crates/router/src/connector/prophetpay/transformers.rs b/crates/router/src/connector/prophetpay/transformers.rs index 1066c88df3e1..74071d5b85cb 100644 --- a/crates/router/src/connector/prophetpay/transformers.rs +++ b/crates/router/src/connector/prophetpay/transformers.rs @@ -1,14 +1,20 @@ -use masking::Secret; +use std::collections::HashMap; + +use common_utils::{consts, errors::CustomResult}; +use error_stack::{IntoReport, ResultExt}; +use masking::{PeekInterface, Secret}; use serde::{Deserialize, Serialize}; +use url::Url; use crate::{ - connector::utils::PaymentsAuthorizeRequestData, + connector::utils, core::errors, + services, types::{self, api, storage::enums}, }; pub struct ProphetpayRouterData { - pub amount: i64, // The type of amount that a connector accepts, for example, String, i64, f64, etc. + pub amount: f64, pub router_data: T, } @@ -22,13 +28,14 @@ impl { type Error = error_stack::Report; fn try_from( - (_currency_unit, _currency, amount, item): ( + (currency_unit, currency, amount, item): ( &types::api::CurrencyUnit, types::storage::enums::Currency, i64, T, ), ) -> Result { + let amount = utils::get_amount_as_f64(currency_unit, amount, currency)?; Ok(Self { amount, router_data: item, @@ -36,108 +43,370 @@ impl } } -#[derive(Default, Debug, Serialize, Eq, PartialEq)] -pub struct ProphetpayPaymentsRequest { - amount: i64, - card: ProphetpayCard, +pub struct ProphetpayAuthType { + pub(super) user_name: Secret, + pub(super) password: Secret, + pub(super) profile_id: Secret, +} + +impl TryFrom<&types::ConnectorAuthType> for ProphetpayAuthType { + type Error = error_stack::Report; + fn try_from(auth_type: &types::ConnectorAuthType) -> Result { + match auth_type { + types::ConnectorAuthType::SignatureKey { + api_key, + key1, + api_secret, + } => Ok(Self { + user_name: api_key.to_owned(), + password: key1.to_owned(), + profile_id: api_secret.to_owned(), + }), + _ => Err(errors::ConnectorError::FailedToObtainAuthType.into()), + } + } +} + +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "PascalCase")] +pub struct ProphetpayTokenRequest { + ref_info: String, + profile: Secret, + entry_method: i8, + token_type: i8, + card_entry_context: i8, +} + +#[derive(Debug, Clone)] +pub enum ProphetpayEntryMethod { + ManualEntry, + CardSwipe, +} + +impl ProphetpayEntryMethod { + fn get_entry_method(&self) -> i8 { + match self { + Self::ManualEntry => 1, + Self::CardSwipe => 2, + } + } +} + +#[derive(Debug, Clone)] +#[repr(i8)] +pub enum ProphetpayTokenType { + Normal, + SaleTab, + TemporarySave, } -#[derive(Default, Debug, Serialize, Eq, PartialEq)] -pub struct ProphetpayCard { - name: Secret, - number: cards::CardNumber, - expiry_month: Secret, - expiry_year: Secret, - cvc: Secret, - complete: bool, +impl ProphetpayTokenType { + fn get_token_type(&self) -> i8 { + match self { + Self::Normal => 0, + Self::SaleTab => 1, + Self::TemporarySave => 2, + } + } +} + +#[derive(Debug, Clone)] +#[repr(i8)] +pub enum ProphetpayCardContext { + NotApplicable, + WebConsumerInitiated, +} + +impl ProphetpayCardContext { + fn get_card_context(&self) -> i8 { + match self { + Self::NotApplicable => 0, + Self::WebConsumerInitiated => 5, + } + } } impl TryFrom<&ProphetpayRouterData<&types::PaymentsAuthorizeRouterData>> - for ProphetpayPaymentsRequest + for ProphetpayTokenRequest { type Error = error_stack::Report; fn try_from( item: &ProphetpayRouterData<&types::PaymentsAuthorizeRouterData>, ) -> Result { - match item.router_data.request.payment_method_data.clone() { - api::PaymentMethodData::Card(req_card) => { - let card = ProphetpayCard { - name: req_card.card_holder_name, - 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.to_owned(), - card, - }) + if item.router_data.request.currency == api_models::enums::Currency::USD { + match item.router_data.request.payment_method_data.clone() { + api::PaymentMethodData::CardRedirect( + api_models::payments::CardRedirectData::CardRedirect {}, + ) => { + let auth_data = + ProphetpayAuthType::try_from(&item.router_data.connector_auth_type)?; + Ok(Self { + ref_info: item.router_data.connector_request_reference_id.to_owned(), + profile: auth_data.profile_id, + entry_method: ProphetpayEntryMethod::get_entry_method( + &ProphetpayEntryMethod::ManualEntry, + ), + token_type: ProphetpayTokenType::get_token_type( + &ProphetpayTokenType::SaleTab, + ), + card_entry_context: ProphetpayCardContext::get_card_context( + &ProphetpayCardContext::WebConsumerInitiated, + ), + }) + } + _ => Err( + errors::ConnectorError::NotImplemented("Payment methods".to_string()).into(), + ), } - _ => Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into()), + } else { + Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into()) } } } -pub struct ProphetpayAuthType { - pub(super) api_key: Secret, +#[derive(Debug, Clone, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ProphetpayTokenResponse { + hosted_tokenize_id: String, } -impl TryFrom<&types::ConnectorAuthType> for ProphetpayAuthType { +impl + TryFrom< + types::ResponseRouterData< + F, + ProphetpayTokenResponse, + types::PaymentsAuthorizeData, + types::PaymentsResponseData, + >, + > for types::RouterData +{ type Error = error_stack::Report; - fn try_from(auth_type: &types::ConnectorAuthType) -> Result { - match auth_type { - types::ConnectorAuthType::HeaderKey { api_key } => Ok(Self { - api_key: api_key.to_owned(), + fn try_from( + item: types::ResponseRouterData< + F, + ProphetpayTokenResponse, + types::PaymentsAuthorizeData, + types::PaymentsResponseData, + >, + ) -> Result { + let url_data = format!( + "{}{}", + consts::PROPHETPAY_REDIRECT_URL, + item.response.hosted_tokenize_id + ); + + let redirect_url = Url::parse(url_data.as_str()) + .into_report() + .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; + + let redirection_data = get_redirect_url_form( + redirect_url, + item.data.request.complete_authorize_url.clone(), + ) + .ok(); + + Ok(Self { + status: enums::AttemptStatus::AuthenticationPending, + response: Ok(types::PaymentsResponseData::TransactionResponse { + resource_id: types::ResponseId::NoResponseId, + redirection_data, + mandate_reference: None, + connector_metadata: None, + network_txn_id: None, + connector_response_reference_id: None, }), - _ => Err(errors::ConnectorError::FailedToObtainAuthType.into()), + ..item.data + }) + } +} + +fn get_redirect_url_form( + mut redirect_url: Url, + complete_auth_url: Option, +) -> CustomResult { + let mut form_fields = std::collections::HashMap::::new(); + + form_fields.insert( + String::from("redirectUrl"), + complete_auth_url.ok_or(errors::ConnectorError::MissingRequiredField { + field_name: "complete_auth_url", + })?, + ); + + // Do not include query params in the endpoint + redirect_url.set_query(None); + + Ok(services::RedirectForm::Form { + endpoint: redirect_url.to_string(), + method: services::Method::Get, + form_fields, + }) +} + +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct ProphetpayCompleteRequest { + amount: f64, + ref_info: String, + inquiry_reference: String, + profile: Secret, + action_type: i8, + card_token: String, +} + +impl TryFrom<&ProphetpayRouterData<&types::PaymentsCompleteAuthorizeRouterData>> + for ProphetpayCompleteRequest +{ + type Error = error_stack::Report; + fn try_from( + item: &ProphetpayRouterData<&types::PaymentsCompleteAuthorizeRouterData>, + ) -> Result { + let auth_data = ProphetpayAuthType::try_from(&item.router_data.connector_auth_type)?; + let card_token = get_card_token(item.router_data.request.redirect_response.clone())?; + Ok(Self { + amount: item.amount.to_owned(), + ref_info: item.router_data.connector_request_reference_id.to_owned(), + inquiry_reference: format!( + "inquiry_{}", + item.router_data.connector_request_reference_id + ), + profile: auth_data.profile_id, + action_type: ProphetpayActionType::get_action_type(&ProphetpayActionType::Charge), + card_token, + }) + } +} + +fn get_card_token( + response: Option, +) -> CustomResult { + let res = response.ok_or(errors::ConnectorError::MissingRequiredField { + field_name: "redirect_response", + })?; + let queries_params = res + .params + .map(|param| { + let mut queries = HashMap::::new(); + let values = param.peek().split('&').collect::>(); + for value in values { + let pair = value.split('=').collect::>(); + queries.insert(pair[0].to_string(), pair[1].to_string()); + } + queries + }) + .ok_or(errors::ConnectorError::ResponseDeserializationFailed)?; + + for (key, val) in queries_params { + if key.as_str() == consts::PROPHETPAY_TOKEN { + return Ok(val); + } + } + + Err(errors::ConnectorError::MissingRequiredField { + field_name: "card_token", + }) + .into_report() +} + +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct ProphetpaySyncRequest { + transaction_id: String, + ref_info: String, + inquiry_reference: String, + profile: Secret, + action_type: i8, +} + +#[derive(Debug, Clone)] +pub enum ProphetpayActionType { + Charge, + Refund, + Inquiry, +} + +impl ProphetpayActionType { + fn get_action_type(&self) -> i8 { + match self { + Self::Charge => 1, + Self::Refund => 3, + Self::Inquiry => 7, } } } -#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq)] -#[serde(rename_all = "lowercase")] +impl TryFrom<&types::PaymentsSyncRouterData> for ProphetpaySyncRequest { + type Error = error_stack::Report; + fn try_from(item: &types::PaymentsSyncRouterData) -> Result { + let auth_data = ProphetpayAuthType::try_from(&item.connector_auth_type)?; + let transaction_id = item + .request + .connector_transaction_id + .get_connector_transaction_id() + .change_context(errors::ConnectorError::MissingConnectorTransactionID)?; + Ok(Self { + transaction_id, + ref_info: item.attempt_id.to_owned(), + inquiry_reference: format!("inquiry_{}", item.attempt_id), + profile: auth_data.profile_id, + action_type: ProphetpayActionType::get_action_type(&ProphetpayActionType::Inquiry), + }) + } +} + +#[derive(Debug, Clone, Deserialize)] pub enum ProphetpayPaymentStatus { - Succeeded, - Failed, - #[default] - Processing, + Success, + #[serde(rename = "Transaction Approved")] + Charged, + Failure, + #[serde(rename = "Transaction Voided")] + Voided, + #[serde(rename = "Requires a card on file.")] + CardTokenNotFound, + #[serde(rename = "RefInfo and InquiryReference are duplicated")] + DuplicateValue, + #[serde(rename = "Profile is missing")] + MissingProfile, + #[serde(rename = "RefInfo is empty.")] + EmptyRef, } impl From for enums::AttemptStatus { fn from(item: ProphetpayPaymentStatus) -> Self { match item { - ProphetpayPaymentStatus::Succeeded => Self::Charged, - ProphetpayPaymentStatus::Failed => Self::Failure, - ProphetpayPaymentStatus::Processing => Self::Authorizing, + ProphetpayPaymentStatus::Success | ProphetpayPaymentStatus::Charged => Self::Charged, + ProphetpayPaymentStatus::Failure + | ProphetpayPaymentStatus::CardTokenNotFound + | ProphetpayPaymentStatus::DuplicateValue + | ProphetpayPaymentStatus::MissingProfile + | ProphetpayPaymentStatus::EmptyRef => Self::Failure, + ProphetpayPaymentStatus::Voided => Self::Voided, } } } -#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct ProphetpayPaymentsResponse { - status: ProphetpayPaymentStatus, - id: String, +#[derive(Debug, Clone, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ProphetpayResponse { + pub response_text: ProphetpayPaymentStatus, + #[serde(rename = "transactionID")] + pub transaction_id: String, } -impl - TryFrom< - types::ResponseRouterData, - > for types::RouterData +impl TryFrom> + for types::RouterData { type Error = error_stack::Report; fn try_from( - item: types::ResponseRouterData< - F, - ProphetpayPaymentsResponse, - T, - types::PaymentsResponseData, - >, + item: types::ResponseRouterData, ) -> Result { Ok(Self { - status: enums::AttemptStatus::from(item.response.status), + status: enums::AttemptStatus::from(item.response.response_text), response: Ok(types::PaymentsResponseData::TransactionResponse { - resource_id: types::ResponseId::ConnectorTransactionId(item.response.id), + resource_id: types::ResponseId::ConnectorTransactionId( + item.response.transaction_id, + ), redirection_data: None, mandate_reference: None, connector_metadata: None, @@ -150,8 +419,39 @@ impl } #[derive(Default, Debug, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct ProphetpayVoidRequest { + pub transaction_id: String, + pub profile: Secret, + pub ref_info: String, + pub inquiry_reference: String, + pub action_type: i8, +} + +impl TryFrom<&types::PaymentsCancelRouterData> for ProphetpayVoidRequest { + type Error = error_stack::Report; + fn try_from(item: &types::PaymentsCancelRouterData) -> Result { + let auth_data = ProphetpayAuthType::try_from(&item.connector_auth_type)?; + let transaction_id = item.request.connector_transaction_id.to_owned(); + Ok(Self { + transaction_id, + ref_info: item.attempt_id.to_owned(), + inquiry_reference: format!("inquiry_{}", item.attempt_id), + profile: auth_data.profile_id, + action_type: ProphetpayActionType::get_action_type(&ProphetpayActionType::Inquiry), + }) + } +} + +#[derive(Default, Debug, Serialize)] +#[serde(rename_all = "camelCase")] pub struct ProphetpayRefundRequest { - pub amount: i64, + pub amount: f64, + pub transaction_id: String, + pub profile: Secret, + pub ref_info: String, + pub inquiry_reference: String, + pub action_type: i8, } impl TryFrom<&ProphetpayRouterData<&types::RefundsRouterData>> for ProphetpayRefundRequest { @@ -159,75 +459,118 @@ impl TryFrom<&ProphetpayRouterData<&types::RefundsRouterData>> for Prophet fn try_from( item: &ProphetpayRouterData<&types::RefundsRouterData>, ) -> Result { + let auth_data = ProphetpayAuthType::try_from(&item.router_data.connector_auth_type)?; + let transaction_id = item.router_data.request.connector_transaction_id.to_owned(); Ok(Self { + transaction_id, amount: item.amount.to_owned(), + profile: auth_data.profile_id, + ref_info: item.router_data.request.refund_id.to_owned(), + inquiry_reference: format!("inquiry_{}", item.router_data.request.refund_id), + action_type: ProphetpayActionType::get_action_type(&ProphetpayActionType::Refund), }) } } #[allow(dead_code)] -#[derive(Debug, Serialize, Default, Deserialize, Clone)] +#[derive(Debug, Deserialize, Clone)] pub enum RefundStatus { - Succeeded, - Failed, - #[default] - Processing, + Success, + Failure, + #[serde(rename = "Transaction Voided")] + Voided, + #[serde(rename = "Requires a card on file.")] + CardTokenNotFound, + #[serde(rename = "RefInfo and InquiryReference are duplicated")] + DuplicateValue, + #[serde(rename = "Profile is missing")] + MissingProfile, + #[serde(rename = "RefInfo is empty.")] + EmptyRef, } impl From for enums::RefundStatus { fn from(item: RefundStatus) -> Self { match item { - RefundStatus::Succeeded => Self::Success, - RefundStatus::Failed => Self::Failure, - RefundStatus::Processing => Self::Pending, + RefundStatus::Success + // in retrieving refund, if it is successful, it is shown as voided + | RefundStatus::Voided => Self::Success, + RefundStatus::Failure + | RefundStatus::CardTokenNotFound + | RefundStatus::DuplicateValue + | RefundStatus::MissingProfile + | RefundStatus::EmptyRef => Self::Failure, } } } -#[derive(Default, Debug, Clone, Serialize, Deserialize)] -pub struct RefundResponse { - id: String, - status: RefundStatus, +#[derive(Debug, Clone, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ProphetpayRefundResponse { + pub response_text: RefundStatus, } -impl TryFrom> +impl TryFrom> for types::RefundsRouterData { type Error = error_stack::Report; fn try_from( - item: types::RefundsResponseRouterData, + item: types::RefundsResponseRouterData, ) -> Result { Ok(Self { response: Ok(types::RefundsResponseData { - connector_refund_id: item.response.id.to_string(), - refund_status: enums::RefundStatus::from(item.response.status), + // no refund id is generated, rather transaction id is used for referring to status in refund also + connector_refund_id: item.data.request.connector_transaction_id.clone(), + refund_status: enums::RefundStatus::from(item.response.response_text), }), ..item.data }) } } -impl TryFrom> +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct ProphetpayRefundSyncRequest { + ref_info: String, + profile: Secret, + action_type: i8, +} + +impl TryFrom<&types::RefundSyncRouterData> for ProphetpayRefundSyncRequest { + type Error = error_stack::Report; + fn try_from(item: &types::RefundSyncRouterData) -> Result { + let auth_data = ProphetpayAuthType::try_from(&item.connector_auth_type)?; + Ok(Self { + ref_info: item.attempt_id.to_owned(), + profile: auth_data.profile_id, + action_type: ProphetpayActionType::get_action_type(&ProphetpayActionType::Inquiry), + }) + } +} + +impl TryFrom> for types::RefundsRouterData { type Error = error_stack::Report; fn try_from( - item: types::RefundsResponseRouterData, + item: types::RefundsResponseRouterData, ) -> Result { Ok(Self { response: Ok(types::RefundsResponseData { - connector_refund_id: item.response.id.to_string(), - refund_status: enums::RefundStatus::from(item.response.status), + connector_refund_id: item.data.request.connector_transaction_id.clone(), + refund_status: enums::RefundStatus::from(item.response.response_text), }), ..item.data }) } } +// Error Response body is yet to be confirmed with the connector #[derive(Default, Debug, Serialize, Deserialize, PartialEq)] +#[serde(rename_all = "camelCase")] pub struct ProphetpayErrorResponse { - pub status_code: u16, - pub code: String, - pub message: String, - pub reason: Option, + pub status: u16, + pub title: String, + pub trace_id: String, + pub errors: serde_json::Value, } diff --git a/crates/router/src/connector/stripe/transformers.rs b/crates/router/src/connector/stripe/transformers.rs index a783fd23fe19..3f0d4f543ba4 100644 --- a/crates/router/src/connector/stripe/transformers.rs +++ b/crates/router/src/connector/stripe/transformers.rs @@ -614,6 +614,7 @@ impl TryFrom for StripePaymentMethodType { enums::PaymentMethodType::AliPay => Ok(Self::Alipay), enums::PaymentMethodType::Przelewy24 => Ok(Self::Przelewy24), enums::PaymentMethodType::Boleto + | enums::PaymentMethodType::CardRedirect | enums::PaymentMethodType::CryptoCurrency | enums::PaymentMethodType::GooglePay | enums::PaymentMethodType::Multibanco @@ -1391,11 +1392,14 @@ fn create_stripe_payment_method( payments::PaymentMethodData::CardRedirect(cardredirect_data) => match cardredirect_data { payments::CardRedirectData::Knet {} | payments::CardRedirectData::Benefit {} - | payments::CardRedirectData::MomoAtm {} => Err(errors::ConnectorError::NotSupported { - message: connector_util::SELECTED_PAYMENT_METHOD.to_string(), - connector: "stripe", + | payments::CardRedirectData::MomoAtm {} + | payments::CardRedirectData::CardRedirect {} => { + Err(errors::ConnectorError::NotSupported { + message: connector_util::SELECTED_PAYMENT_METHOD.to_string(), + connector: "stripe", + } + .into()) } - .into()), }, payments::PaymentMethodData::Reward => Err(errors::ConnectorError::NotImplemented( connector_util::get_unimplemented_payment_method_error_message("stripe"), diff --git a/crates/router/src/connector/zen/transformers.rs b/crates/router/src/connector/zen/transformers.rs index 6b0d46dec8d1..689894176b26 100644 --- a/crates/router/src/connector/zen/transformers.rs +++ b/crates/router/src/connector/zen/transformers.rs @@ -790,7 +790,8 @@ impl TryFrom<&api_models::payments::CardRedirectData> for ZenPaymentsRequest { match value { api_models::payments::CardRedirectData::Knet {} | api_models::payments::CardRedirectData::Benefit {} - | api_models::payments::CardRedirectData::MomoAtm {} => { + | api_models::payments::CardRedirectData::MomoAtm {} + | api_models::payments::CardRedirectData::CardRedirect {} => { Err(errors::ConnectorError::NotImplemented( utils::get_unimplemented_payment_method_error_message("Zen"), ) diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs index f5ca2f8b26e9..39b4749535b7 100644 --- a/crates/router/src/core/admin.rs +++ b/crates/router/src/core/admin.rs @@ -1639,6 +1639,10 @@ pub(crate) fn validate_auth_and_metadata_type( powertranz::transformers::PowertranzAuthType::try_from(val)?; Ok(()) } + api_enums::Connector::Prophetpay => { + prophetpay::transformers::ProphetpayAuthType::try_from(val)?; + Ok(()) + } api_enums::Connector::Rapyd => { rapyd::transformers::RapydAuthType::try_from(val)?; Ok(()) diff --git a/crates/router/src/core/payments/flows.rs b/crates/router/src/core/payments/flows.rs index 0b253cdc6079..46eaca26f7cc 100644 --- a/crates/router/src/core/payments/flows.rs +++ b/crates/router/src/core/payments/flows.rs @@ -168,7 +168,6 @@ default_imp_for_complete_authorize!( connector::Opennode, connector::Payeezy, connector::Payu, - connector::Prophetpay, connector::Rapyd, connector::Square, connector::Stax, diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 4ee2fd4b94d3..b9e96ec36e11 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -1817,6 +1817,7 @@ pub fn validate_payment_method_type_against_payment_method( api_enums::PaymentMethodType::Knet | api_enums::PaymentMethodType::Benefit | api_enums::PaymentMethodType::MomoAtm + | api_enums::PaymentMethodType::CardRedirect ), } } diff --git a/crates/router/src/core/payments/routing/transformers.rs b/crates/router/src/core/payments/routing/transformers.rs index d7061a1502de..5704f82f4983 100644 --- a/crates/router/src/core/payments/routing/transformers.rs +++ b/crates/router/src/core/payments/routing/transformers.rs @@ -105,6 +105,7 @@ impl ForeignFrom for dsl_enums::Connector { api_enums::RoutableConnectors::Paypal => Self::Paypal, api_enums::RoutableConnectors::Payu => Self::Payu, api_enums::RoutableConnectors::Powertranz => Self::Powertranz, + api_enums::RoutableConnectors::Prophetpay => Self::Prophetpay, api_enums::RoutableConnectors::Rapyd => Self::Rapyd, api_enums::RoutableConnectors::Shift4 => Self::Shift4, api_enums::RoutableConnectors::Square => Self::Square, diff --git a/crates/router/src/types/api.rs b/crates/router/src/types/api.rs index 2aa8f4a97c76..dc615c4e41fa 100644 --- a/crates/router/src/types/api.rs +++ b/crates/router/src/types/api.rs @@ -371,7 +371,7 @@ impl ConnectorData { enums::Connector::Payme => Ok(Box::new(&connector::Payme)), enums::Connector::Payu => Ok(Box::new(&connector::Payu)), enums::Connector::Powertranz => Ok(Box::new(&connector::Powertranz)), - // enums::Connector::Prophetpay => Ok(Box::new(&connector::Prophetpay)), + enums::Connector::Prophetpay => Ok(Box::new(&connector::Prophetpay)), enums::Connector::Rapyd => Ok(Box::new(&connector::Rapyd)), enums::Connector::Shift4 => Ok(Box::new(&connector::Shift4)), enums::Connector::Square => Ok(Box::new(&connector::Square)), diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs index 2ba4ea483c45..f43abdf73ead 100644 --- a/crates/router/src/types/transformers.rs +++ b/crates/router/src/types/transformers.rs @@ -230,6 +230,7 @@ impl ForeignTryFrom for api_enums::RoutableConnectors { .into_report()? } api_enums::Connector::Powertranz => Self::Powertranz, + api_enums::Connector::Prophetpay => Self::Prophetpay, api_enums::Connector::Rapyd => Self::Rapyd, api_enums::Connector::Shift4 => Self::Shift4, api_enums::Connector::Signifyd => { @@ -304,6 +305,7 @@ impl ForeignFrom for api_enums::RoutableConnectors { dsl_enums::Connector::Paypal => Self::Paypal, dsl_enums::Connector::Payu => Self::Payu, dsl_enums::Connector::Powertranz => Self::Powertranz, + dsl_enums::Connector::Prophetpay => Self::Prophetpay, dsl_enums::Connector::Rapyd => Self::Rapyd, dsl_enums::Connector::Shift4 => Self::Shift4, dsl_enums::Connector::Square => Self::Square, @@ -503,7 +505,8 @@ impl ForeignFrom for api_enums::PaymentMethod { } api_enums::PaymentMethodType::Benefit | api_enums::PaymentMethodType::Knet - | api_enums::PaymentMethodType::MomoAtm => Self::CardRedirect, + | api_enums::PaymentMethodType::MomoAtm + | api_enums::PaymentMethodType::CardRedirect => Self::CardRedirect, } } } diff --git a/crates/router/tests/connectors/prophetpay.rs b/crates/router/tests/connectors/prophetpay.rs index 09e4ea422531..94220c11a6aa 100644 --- a/crates/router/tests/connectors/prophetpay.rs +++ b/crates/router/tests/connectors/prophetpay.rs @@ -12,8 +12,7 @@ impl utils::Connector for ProphetpayTest { use router::connector::Prophetpay; types::api::ConnectorData { connector: Box::new(&Prophetpay), - // Remove `dummy_connector` feature gate from module in `main.rs` when updating this to use actual connector variant - connector_name: types::Connector::DummyConnector1, + connector_name: types::Connector::Prophetpay, get_token: types::api::GetToken::Connector, merchant_connector_id: None, } diff --git a/openapi/openapi_spec.json b/openapi/openapi_spec.json index d154ee5a6407..9fddde01b49a 100644 --- a/openapi/openapi_spec.json +++ b/openapi/openapi_spec.json @@ -4038,6 +4038,17 @@ "type": "object" } } + }, + { + "type": "object", + "required": [ + "card_redirect" + ], + "properties": { + "card_redirect": { + "type": "object" + } + } } ] }, @@ -4089,6 +4100,7 @@ "paypal", "payu", "powertranz", + "prophetpay", "rapyd", "shift4", "square", @@ -8776,6 +8788,7 @@ "bca_bank_transfer", "bni_va", "bri_va", + "card_redirect", "cimb_va", "classic", "credit",