mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 09:07:09 +08:00
feat: add routing support for v2 sdk session flow (#6763)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@ -1,5 +1,9 @@
|
||||
//! API interface
|
||||
|
||||
/// authentication module
|
||||
pub mod authentication;
|
||||
/// authentication_v2 module
|
||||
pub mod authentication_v2;
|
||||
pub mod disputes;
|
||||
pub mod disputes_v2;
|
||||
pub mod files;
|
||||
@ -19,6 +23,8 @@ pub mod refunds_v2;
|
||||
pub mod revenue_recovery;
|
||||
pub mod revenue_recovery_v2;
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
use common_enums::{
|
||||
enums::{CallConnectorAction, CaptureMethod, EventClass, PaymentAction, PaymentMethodType},
|
||||
PaymentMethod,
|
||||
@ -29,6 +35,8 @@ use common_utils::{
|
||||
};
|
||||
use error_stack::ResultExt;
|
||||
use hyperswitch_domain_models::{
|
||||
configs::Connectors,
|
||||
errors::api_error_response::ApiErrorResponse,
|
||||
payment_method_data::PaymentMethodData,
|
||||
router_data::{AccessToken, ConnectorAuthType, ErrorResponse, RouterData},
|
||||
router_data_v2::{
|
||||
@ -55,14 +63,67 @@ use hyperswitch_domain_models::{
|
||||
use masking::Maskable;
|
||||
use serde_json::json;
|
||||
|
||||
#[cfg(feature = "frm")]
|
||||
pub use self::fraud_check::*;
|
||||
#[cfg(feature = "frm")]
|
||||
pub use self::fraud_check_v2::*;
|
||||
#[cfg(feature = "payouts")]
|
||||
pub use self::payouts::*;
|
||||
#[cfg(feature = "payouts")]
|
||||
pub use self::payouts_v2::*;
|
||||
pub use self::{payments::*, refunds::*};
|
||||
use crate::{
|
||||
configs::Connectors, connector_integration_v2::ConnectorIntegrationV2, consts, errors,
|
||||
events::connector_api_logs::ConnectorEvent, metrics, types,
|
||||
api::revenue_recovery::RevenueRecovery, connector_integration_v2::ConnectorIntegrationV2,
|
||||
consts, errors, events::connector_api_logs::ConnectorEvent, metrics, types, webhooks,
|
||||
};
|
||||
|
||||
/// Connector trait
|
||||
pub trait Connector:
|
||||
Send
|
||||
+ Refund
|
||||
+ Payment
|
||||
+ ConnectorRedirectResponse
|
||||
+ webhooks::IncomingWebhook
|
||||
+ ConnectorAccessToken
|
||||
+ disputes::Dispute
|
||||
+ files::FileUpload
|
||||
+ ConnectorTransactionId
|
||||
+ Payouts
|
||||
+ ConnectorVerifyWebhookSource
|
||||
+ FraudCheck
|
||||
+ ConnectorMandateRevoke
|
||||
+ authentication::ExternalAuthentication
|
||||
+ TaxCalculation
|
||||
+ UnifiedAuthenticationService
|
||||
+ RevenueRecovery
|
||||
{
|
||||
}
|
||||
|
||||
impl<
|
||||
T: Refund
|
||||
+ Payment
|
||||
+ ConnectorRedirectResponse
|
||||
+ Send
|
||||
+ webhooks::IncomingWebhook
|
||||
+ ConnectorAccessToken
|
||||
+ disputes::Dispute
|
||||
+ files::FileUpload
|
||||
+ ConnectorTransactionId
|
||||
+ Payouts
|
||||
+ ConnectorVerifyWebhookSource
|
||||
+ FraudCheck
|
||||
+ ConnectorMandateRevoke
|
||||
+ authentication::ExternalAuthentication
|
||||
+ TaxCalculation
|
||||
+ UnifiedAuthenticationService
|
||||
+ RevenueRecovery,
|
||||
> Connector for T
|
||||
{
|
||||
}
|
||||
|
||||
/// Alias for Box<&'static (dyn Connector + Sync)>
|
||||
pub type BoxedConnector = Box<&'static (dyn Connector + Sync)>;
|
||||
|
||||
/// type BoxedConnectorIntegration
|
||||
pub type BoxedConnectorIntegration<'a, T, Req, Resp> =
|
||||
Box<&'a (dyn ConnectorIntegration<T, Req, Resp> + Send + Sync)>;
|
||||
@ -582,6 +643,16 @@ pub trait ConnectorRedirectResponse {
|
||||
/// Empty trait for when payouts feature is disabled
|
||||
#[cfg(not(feature = "payouts"))]
|
||||
pub trait Payouts {}
|
||||
/// Empty trait for when payouts feature is disabled
|
||||
#[cfg(not(feature = "payouts"))]
|
||||
pub trait PayoutsV2 {}
|
||||
|
||||
/// Empty trait for when frm feature is disabled
|
||||
#[cfg(not(feature = "frm"))]
|
||||
pub trait FraudCheck {}
|
||||
/// Empty trait for when frm feature is disabled
|
||||
#[cfg(not(feature = "frm"))]
|
||||
pub trait FraudCheckV2 {}
|
||||
|
||||
fn get_connector_payment_method_type_info(
|
||||
supported_payment_method: &SupportedPaymentMethods,
|
||||
@ -609,3 +680,16 @@ fn get_connector_payment_method_type_info(
|
||||
})
|
||||
.transpose()
|
||||
}
|
||||
|
||||
/// ConnectorTransactionId trait
|
||||
pub trait ConnectorTransactionId: ConnectorCommon + Sync {
|
||||
/// fn connector_transaction_id
|
||||
fn connector_transaction_id(
|
||||
&self,
|
||||
payment_attempt: hyperswitch_domain_models::payments::payment_attempt::PaymentAttempt,
|
||||
) -> Result<Option<String>, ApiErrorResponse> {
|
||||
Ok(payment_attempt
|
||||
.get_connector_payment_id()
|
||||
.map(ToString::to_string))
|
||||
}
|
||||
}
|
||||
|
||||
50
crates/hyperswitch_interfaces/src/api/authentication.rs
Normal file
50
crates/hyperswitch_interfaces/src/api/authentication.rs
Normal file
@ -0,0 +1,50 @@
|
||||
use hyperswitch_domain_models::{
|
||||
router_flow_types::authentication::{
|
||||
Authentication, PostAuthentication, PreAuthentication, PreAuthenticationVersionCall,
|
||||
},
|
||||
router_request_types::authentication::{
|
||||
ConnectorAuthenticationRequestData, ConnectorPostAuthenticationRequestData,
|
||||
PreAuthNRequestData,
|
||||
},
|
||||
router_response_types::AuthenticationResponseData,
|
||||
};
|
||||
|
||||
use crate::api::ConnectorIntegration;
|
||||
|
||||
/// trait ConnectorAuthentication
|
||||
pub trait ConnectorAuthentication:
|
||||
ConnectorIntegration<Authentication, ConnectorAuthenticationRequestData, AuthenticationResponseData>
|
||||
{
|
||||
}
|
||||
|
||||
/// trait ConnectorPreAuthentication
|
||||
pub trait ConnectorPreAuthentication:
|
||||
ConnectorIntegration<PreAuthentication, PreAuthNRequestData, AuthenticationResponseData>
|
||||
{
|
||||
}
|
||||
|
||||
/// trait ConnectorPreAuthenticationVersionCall
|
||||
pub trait ConnectorPreAuthenticationVersionCall:
|
||||
ConnectorIntegration<PreAuthenticationVersionCall, PreAuthNRequestData, AuthenticationResponseData>
|
||||
{
|
||||
}
|
||||
|
||||
/// trait ConnectorPostAuthentication
|
||||
pub trait ConnectorPostAuthentication:
|
||||
ConnectorIntegration<
|
||||
PostAuthentication,
|
||||
ConnectorPostAuthenticationRequestData,
|
||||
AuthenticationResponseData,
|
||||
>
|
||||
{
|
||||
}
|
||||
|
||||
/// trait ExternalAuthentication
|
||||
pub trait ExternalAuthentication:
|
||||
super::ConnectorCommon
|
||||
+ ConnectorAuthentication
|
||||
+ ConnectorPreAuthentication
|
||||
+ ConnectorPreAuthenticationVersionCall
|
||||
+ ConnectorPostAuthentication
|
||||
{
|
||||
}
|
||||
67
crates/hyperswitch_interfaces/src/api/authentication_v2.rs
Normal file
67
crates/hyperswitch_interfaces/src/api/authentication_v2.rs
Normal file
@ -0,0 +1,67 @@
|
||||
use hyperswitch_domain_models::{
|
||||
router_data_v2::ExternalAuthenticationFlowData,
|
||||
router_flow_types::authentication::{
|
||||
Authentication, PostAuthentication, PreAuthentication, PreAuthenticationVersionCall,
|
||||
},
|
||||
router_request_types::authentication::{
|
||||
ConnectorAuthenticationRequestData, ConnectorPostAuthenticationRequestData,
|
||||
PreAuthNRequestData,
|
||||
},
|
||||
router_response_types::AuthenticationResponseData,
|
||||
};
|
||||
|
||||
use crate::api::ConnectorIntegrationV2;
|
||||
|
||||
/// trait ConnectorAuthenticationV2
|
||||
pub trait ConnectorAuthenticationV2:
|
||||
ConnectorIntegrationV2<
|
||||
Authentication,
|
||||
ExternalAuthenticationFlowData,
|
||||
ConnectorAuthenticationRequestData,
|
||||
AuthenticationResponseData,
|
||||
>
|
||||
{
|
||||
}
|
||||
|
||||
/// trait ConnectorPreAuthenticationV2
|
||||
pub trait ConnectorPreAuthenticationV2:
|
||||
ConnectorIntegrationV2<
|
||||
PreAuthentication,
|
||||
ExternalAuthenticationFlowData,
|
||||
PreAuthNRequestData,
|
||||
AuthenticationResponseData,
|
||||
>
|
||||
{
|
||||
}
|
||||
|
||||
/// trait ConnectorPreAuthenticationVersionCallV2
|
||||
pub trait ConnectorPreAuthenticationVersionCallV2:
|
||||
ConnectorIntegrationV2<
|
||||
PreAuthenticationVersionCall,
|
||||
ExternalAuthenticationFlowData,
|
||||
PreAuthNRequestData,
|
||||
AuthenticationResponseData,
|
||||
>
|
||||
{
|
||||
}
|
||||
|
||||
/// trait ConnectorPostAuthenticationV2
|
||||
pub trait ConnectorPostAuthenticationV2:
|
||||
ConnectorIntegrationV2<
|
||||
PostAuthentication,
|
||||
ExternalAuthenticationFlowData,
|
||||
ConnectorPostAuthenticationRequestData,
|
||||
AuthenticationResponseData,
|
||||
>
|
||||
{
|
||||
}
|
||||
|
||||
/// trait ExternalAuthenticationV2
|
||||
pub trait ExternalAuthenticationV2:
|
||||
super::ConnectorCommon
|
||||
+ ConnectorAuthenticationV2
|
||||
+ ConnectorPreAuthenticationV2
|
||||
+ ConnectorPreAuthenticationVersionCallV2
|
||||
+ ConnectorPostAuthenticationV2
|
||||
{
|
||||
}
|
||||
@ -39,3 +39,14 @@ pub trait FraudCheckRecordReturn:
|
||||
ConnectorIntegration<RecordReturn, FraudCheckRecordReturnData, FraudCheckResponseData>
|
||||
{
|
||||
}
|
||||
|
||||
/// trait FraudCheck
|
||||
pub trait FraudCheck:
|
||||
super::ConnectorCommon
|
||||
+ FraudCheckSale
|
||||
+ FraudCheckTransaction
|
||||
+ FraudCheckCheckout
|
||||
+ FraudCheckFulfillment
|
||||
+ FraudCheckRecordReturn
|
||||
{
|
||||
}
|
||||
|
||||
@ -45,3 +45,14 @@ pub trait FraudCheckRecordReturnV2:
|
||||
>
|
||||
{
|
||||
}
|
||||
|
||||
/// trait FraudCheckV2
|
||||
pub trait FraudCheckV2:
|
||||
super::ConnectorCommon
|
||||
+ FraudCheckSaleV2
|
||||
+ FraudCheckTransactionV2
|
||||
+ FraudCheckCheckoutV2
|
||||
+ FraudCheckFulfillmentV2
|
||||
+ FraudCheckRecordReturnV2
|
||||
{
|
||||
}
|
||||
|
||||
@ -1,208 +1 @@
|
||||
//! Configs interface
|
||||
use common_enums::ApplicationError;
|
||||
use masking::Secret;
|
||||
use router_derive;
|
||||
use serde::Deserialize;
|
||||
// struct Connectors
|
||||
#[allow(missing_docs, missing_debug_implementations)]
|
||||
#[derive(Debug, Deserialize, Clone, Default, router_derive::ConfigValidate)]
|
||||
#[serde(default)]
|
||||
pub struct Connectors {
|
||||
pub aci: ConnectorParams,
|
||||
pub adyen: AdyenParamsWithThreeBaseUrls,
|
||||
pub adyenplatform: ConnectorParams,
|
||||
pub airwallex: ConnectorParams,
|
||||
pub amazonpay: ConnectorParams,
|
||||
pub applepay: ConnectorParams,
|
||||
pub authorizedotnet: ConnectorParams,
|
||||
pub bambora: ConnectorParams,
|
||||
pub bamboraapac: ConnectorParams,
|
||||
pub bankofamerica: ConnectorParams,
|
||||
pub billwerk: ConnectorParams,
|
||||
pub bitpay: ConnectorParams,
|
||||
pub bluesnap: ConnectorParamsWithSecondaryBaseUrl,
|
||||
pub boku: ConnectorParams,
|
||||
pub braintree: ConnectorParams,
|
||||
pub cashtocode: ConnectorParams,
|
||||
pub chargebee: ConnectorParams,
|
||||
pub checkout: ConnectorParams,
|
||||
pub coinbase: ConnectorParams,
|
||||
pub coingate: ConnectorParams,
|
||||
pub cryptopay: ConnectorParams,
|
||||
pub ctp_mastercard: NoParams,
|
||||
pub cybersource: ConnectorParams,
|
||||
pub datatrans: ConnectorParamsWithSecondaryBaseUrl,
|
||||
pub deutschebank: ConnectorParams,
|
||||
pub digitalvirgo: ConnectorParams,
|
||||
pub dlocal: ConnectorParams,
|
||||
#[cfg(feature = "dummy_connector")]
|
||||
pub dummyconnector: ConnectorParams,
|
||||
pub ebanx: ConnectorParams,
|
||||
pub elavon: ConnectorParams,
|
||||
pub fiserv: ConnectorParams,
|
||||
pub fiservemea: ConnectorParams,
|
||||
pub fiuu: ConnectorParamsWithThreeUrls,
|
||||
pub forte: ConnectorParams,
|
||||
pub getnet: ConnectorParams,
|
||||
pub globalpay: ConnectorParams,
|
||||
pub globepay: ConnectorParams,
|
||||
pub gocardless: ConnectorParams,
|
||||
pub gpayments: ConnectorParams,
|
||||
pub helcim: ConnectorParams,
|
||||
pub hipay: ConnectorParamsWithThreeUrls,
|
||||
pub iatapay: ConnectorParams,
|
||||
pub inespay: ConnectorParams,
|
||||
pub itaubank: ConnectorParams,
|
||||
pub jpmorgan: ConnectorParams,
|
||||
pub juspaythreedsserver: ConnectorParams,
|
||||
pub klarna: ConnectorParams,
|
||||
pub mifinity: ConnectorParams,
|
||||
pub mollie: ConnectorParams,
|
||||
pub moneris: ConnectorParams,
|
||||
pub multisafepay: ConnectorParams,
|
||||
pub netcetera: ConnectorParams,
|
||||
pub nexinets: ConnectorParams,
|
||||
pub nexixpay: ConnectorParams,
|
||||
pub nmi: ConnectorParams,
|
||||
pub nomupay: ConnectorParams,
|
||||
pub noon: ConnectorParamsWithModeType,
|
||||
pub novalnet: ConnectorParams,
|
||||
pub nuvei: ConnectorParams,
|
||||
pub opayo: ConnectorParams,
|
||||
pub opennode: ConnectorParams,
|
||||
pub paybox: ConnectorParamsWithSecondaryBaseUrl,
|
||||
pub payeezy: ConnectorParams,
|
||||
pub payme: ConnectorParams,
|
||||
pub payone: ConnectorParams,
|
||||
pub paypal: ConnectorParams,
|
||||
pub paystack: ConnectorParams,
|
||||
pub payu: ConnectorParams,
|
||||
pub placetopay: ConnectorParams,
|
||||
pub plaid: ConnectorParams,
|
||||
pub powertranz: ConnectorParams,
|
||||
pub prophetpay: ConnectorParams,
|
||||
pub rapyd: ConnectorParams,
|
||||
pub razorpay: ConnectorParamsWithKeys,
|
||||
pub recurly: ConnectorParams,
|
||||
pub redsys: ConnectorParams,
|
||||
pub riskified: ConnectorParams,
|
||||
pub shift4: ConnectorParams,
|
||||
pub signifyd: ConnectorParams,
|
||||
pub square: ConnectorParams,
|
||||
pub stax: ConnectorParams,
|
||||
pub stripe: ConnectorParamsWithFileUploadUrl,
|
||||
pub stripebilling: ConnectorParams,
|
||||
pub taxjar: ConnectorParams,
|
||||
pub threedsecureio: ConnectorParams,
|
||||
pub thunes: ConnectorParams,
|
||||
pub trustpay: ConnectorParamsWithMoreUrls,
|
||||
pub tsys: ConnectorParams,
|
||||
pub unified_authentication_service: ConnectorParams,
|
||||
pub volt: ConnectorParams,
|
||||
pub wellsfargo: ConnectorParams,
|
||||
pub wellsfargopayout: ConnectorParams,
|
||||
pub wise: ConnectorParams,
|
||||
pub worldline: ConnectorParams,
|
||||
pub worldpay: ConnectorParams,
|
||||
pub xendit: ConnectorParams,
|
||||
pub zen: ConnectorParams,
|
||||
pub zsl: ConnectorParams,
|
||||
}
|
||||
|
||||
/// struct ConnectorParams
|
||||
#[derive(Debug, Deserialize, Clone, Default, router_derive::ConfigValidate)]
|
||||
#[serde(default)]
|
||||
pub struct ConnectorParams {
|
||||
/// base url
|
||||
pub base_url: String,
|
||||
/// secondary base url
|
||||
pub secondary_base_url: Option<String>,
|
||||
}
|
||||
|
||||
///struct No Param for connectors with no params
|
||||
#[derive(Debug, Deserialize, Clone, Default)]
|
||||
pub struct NoParams;
|
||||
|
||||
impl NoParams {
|
||||
/// function to satisfy connector param validation macro
|
||||
pub fn validate(&self, _parent_field: &str) -> Result<(), ApplicationError> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// struct ConnectorParamsWithKeys
|
||||
#[derive(Debug, Deserialize, Clone, Default, router_derive::ConfigValidate)]
|
||||
#[serde(default)]
|
||||
pub struct ConnectorParamsWithKeys {
|
||||
/// base url
|
||||
pub base_url: String,
|
||||
/// api key
|
||||
pub api_key: Secret<String>,
|
||||
/// merchant ID
|
||||
pub merchant_id: Secret<String>,
|
||||
}
|
||||
|
||||
/// struct ConnectorParamsWithModeType
|
||||
#[derive(Debug, Deserialize, Clone, Default, router_derive::ConfigValidate)]
|
||||
#[serde(default)]
|
||||
pub struct ConnectorParamsWithModeType {
|
||||
/// base url
|
||||
pub base_url: String,
|
||||
/// secondary base url
|
||||
pub secondary_base_url: Option<String>,
|
||||
/// Can take values like Test or Live for Noon
|
||||
pub key_mode: String,
|
||||
}
|
||||
|
||||
/// struct ConnectorParamsWithMoreUrls
|
||||
#[derive(Debug, Deserialize, Clone, Default, router_derive::ConfigValidate)]
|
||||
#[serde(default)]
|
||||
pub struct ConnectorParamsWithMoreUrls {
|
||||
/// base url
|
||||
pub base_url: String,
|
||||
/// base url for bank redirects
|
||||
pub base_url_bank_redirects: String,
|
||||
}
|
||||
|
||||
/// struct ConnectorParamsWithFileUploadUrl
|
||||
#[derive(Debug, Deserialize, Clone, Default, router_derive::ConfigValidate)]
|
||||
#[serde(default)]
|
||||
pub struct ConnectorParamsWithFileUploadUrl {
|
||||
/// base url
|
||||
pub base_url: String,
|
||||
/// base url for file upload
|
||||
pub base_url_file_upload: String,
|
||||
}
|
||||
|
||||
/// struct ConnectorParamsWithThreeBaseUrls
|
||||
#[derive(Debug, Deserialize, Clone, Default, router_derive::ConfigValidate)]
|
||||
#[serde(default)]
|
||||
pub struct AdyenParamsWithThreeBaseUrls {
|
||||
/// base url
|
||||
pub base_url: String,
|
||||
/// secondary base url
|
||||
#[cfg(feature = "payouts")]
|
||||
pub payout_base_url: String,
|
||||
/// third base url
|
||||
pub dispute_base_url: String,
|
||||
}
|
||||
/// struct ConnectorParamsWithSecondaryBaseUrl
|
||||
#[derive(Debug, Deserialize, Clone, Default, router_derive::ConfigValidate)]
|
||||
#[serde(default)]
|
||||
pub struct ConnectorParamsWithSecondaryBaseUrl {
|
||||
/// base url
|
||||
pub base_url: String,
|
||||
/// secondary base url
|
||||
pub secondary_base_url: String,
|
||||
}
|
||||
/// struct ConnectorParamsWithThreeUrls
|
||||
#[derive(Debug, Deserialize, Clone, Default, router_derive::ConfigValidate)]
|
||||
#[serde(default)]
|
||||
pub struct ConnectorParamsWithThreeUrls {
|
||||
/// base url
|
||||
pub base_url: String,
|
||||
/// secondary base url
|
||||
pub secondary_base_url: String,
|
||||
/// third base url
|
||||
pub third_base_url: String,
|
||||
}
|
||||
pub use hyperswitch_domain_models::configs::Connectors;
|
||||
|
||||
@ -0,0 +1,737 @@
|
||||
use api_models::webhooks::{IncomingWebhookEvent, ObjectReferenceId};
|
||||
use common_enums::PaymentAction;
|
||||
use common_utils::{crypto, errors::CustomResult, request::Request};
|
||||
use hyperswitch_domain_models::{
|
||||
api::ApplicationResponse,
|
||||
configs::Connectors,
|
||||
errors::api_error_response::ApiErrorResponse,
|
||||
payment_method_data::PaymentMethodData,
|
||||
router_data::{ConnectorAuthType, ErrorResponse, RouterData},
|
||||
router_data_v2::RouterDataV2,
|
||||
router_response_types::{ConnectorInfo, SupportedPaymentMethods},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
api,
|
||||
api::{
|
||||
BoxedConnectorIntegration, CaptureSyncMethod, Connector, ConnectorCommon,
|
||||
ConnectorIntegration, ConnectorRedirectResponse, ConnectorSpecifications,
|
||||
ConnectorValidation, CurrencyUnit,
|
||||
},
|
||||
authentication::ExternalAuthenticationPayload,
|
||||
connector_integration_v2::{BoxedConnectorIntegrationV2, ConnectorIntegrationV2, ConnectorV2},
|
||||
disputes, errors,
|
||||
events::connector_api_logs::ConnectorEvent,
|
||||
types,
|
||||
webhooks::{IncomingWebhook, IncomingWebhookFlowError, IncomingWebhookRequestDetails},
|
||||
};
|
||||
|
||||
/// RouterDataConversion trait
|
||||
///
|
||||
/// This trait must be implemented for conversion between Router data and RouterDataV2
|
||||
pub trait RouterDataConversion<T, Req: Clone, Resp: Clone> {
|
||||
/// Convert RouterData to RouterDataV2
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `old_router_data` - A reference to the old RouterData
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A `CustomResult` containing the new RouterDataV2 or a ConnectorError
|
||||
fn from_old_router_data(
|
||||
old_router_data: &RouterData<T, Req, Resp>,
|
||||
) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, errors::ConnectorError>
|
||||
where
|
||||
Self: Sized;
|
||||
/// Convert RouterDataV2 back to RouterData
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `new_router_data` - The new RouterDataV2
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A `CustomResult` containing the old RouterData or a ConnectorError
|
||||
fn to_old_router_data(
|
||||
new_router_data: RouterDataV2<T, Self, Req, Resp>,
|
||||
) -> CustomResult<RouterData<T, Req, Resp>, errors::ConnectorError>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
/// Alias for Box<&'static (dyn Connector + Sync)>
|
||||
pub type BoxedConnector = Box<&'static (dyn Connector + Sync)>;
|
||||
/// Alias for Box<&'static (dyn ConnectorV2 + Sync)>
|
||||
pub type BoxedConnectorV2 = Box<&'static (dyn ConnectorV2 + Sync)>;
|
||||
|
||||
/// Enum representing the Connector
|
||||
#[derive(Clone)]
|
||||
pub enum ConnectorEnum {
|
||||
/// Old connector type
|
||||
Old(BoxedConnector),
|
||||
/// New connector type
|
||||
New(BoxedConnectorV2),
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for ConnectorEnum {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Old(_) => f
|
||||
.debug_tuple("Old")
|
||||
.field(&std::any::type_name::<BoxedConnector>().to_string())
|
||||
.finish(),
|
||||
Self::New(_) => f
|
||||
.debug_tuple("New")
|
||||
.field(&std::any::type_name::<BoxedConnectorV2>().to_string())
|
||||
.finish(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(missing_debug_implementations)]
|
||||
/// Enum representing the Connector Integration
|
||||
#[derive(Clone)]
|
||||
pub enum ConnectorIntegrationEnum<'a, F, ResourceCommonData, Req, Resp> {
|
||||
/// Old connector integration type
|
||||
Old(BoxedConnectorIntegration<'a, F, Req, Resp>),
|
||||
/// New connector integration type
|
||||
New(BoxedConnectorIntegrationV2<'a, F, ResourceCommonData, Req, Resp>),
|
||||
}
|
||||
|
||||
/// Alias for Box<dyn ConnectorIntegrationInterface>
|
||||
pub type BoxedConnectorIntegrationInterface<F, ResourceCommonData, Req, Resp> =
|
||||
Box<dyn ConnectorIntegrationInterface<F, ResourceCommonData, Req, Resp> + Send + Sync>;
|
||||
|
||||
impl ConnectorEnum {
|
||||
/// Get the connector integration
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A `BoxedConnectorIntegrationInterface` containing the connector integration
|
||||
pub fn get_connector_integration<F, ResourceCommonData, Req, Resp>(
|
||||
&self,
|
||||
) -> BoxedConnectorIntegrationInterface<F, ResourceCommonData, Req, Resp>
|
||||
where
|
||||
dyn Connector + Sync: ConnectorIntegration<F, Req, Resp>,
|
||||
dyn ConnectorV2 + Sync: ConnectorIntegrationV2<F, ResourceCommonData, Req, Resp>,
|
||||
ResourceCommonData: RouterDataConversion<F, Req, Resp> + Clone + 'static,
|
||||
F: Clone + 'static,
|
||||
Req: Clone + 'static,
|
||||
Resp: Clone + 'static,
|
||||
{
|
||||
match self {
|
||||
Self::Old(old_integration) => Box::new(ConnectorIntegrationEnum::Old(
|
||||
old_integration.get_connector_integration(),
|
||||
)),
|
||||
Self::New(new_integration) => Box::new(ConnectorIntegrationEnum::New(
|
||||
new_integration.get_connector_integration_v2(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
/// validates the file upload
|
||||
pub fn validate_file_upload(
|
||||
&self,
|
||||
purpose: api::files::FilePurpose,
|
||||
file_size: i32,
|
||||
file_type: mime::Mime,
|
||||
) -> CustomResult<(), errors::ConnectorError> {
|
||||
match self {
|
||||
Self::Old(connector) => connector.validate_file_upload(purpose, file_size, file_type),
|
||||
Self::New(connector) => {
|
||||
connector.validate_file_upload_v2(purpose, file_size, file_type)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl IncomingWebhook for ConnectorEnum {
|
||||
fn get_webhook_body_decoding_algorithm(
|
||||
&self,
|
||||
request: &IncomingWebhookRequestDetails<'_>,
|
||||
) -> CustomResult<Box<dyn crypto::DecodeMessage + Send>, errors::ConnectorError> {
|
||||
match self {
|
||||
Self::Old(connector) => connector.get_webhook_body_decoding_algorithm(request),
|
||||
Self::New(connector) => connector.get_webhook_body_decoding_algorithm(request),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_webhook_body_decoding_message(
|
||||
&self,
|
||||
request: &IncomingWebhookRequestDetails<'_>,
|
||||
) -> CustomResult<Vec<u8>, errors::ConnectorError> {
|
||||
match self {
|
||||
Self::Old(connector) => connector.get_webhook_body_decoding_message(request),
|
||||
Self::New(connector) => connector.get_webhook_body_decoding_message(request),
|
||||
}
|
||||
}
|
||||
|
||||
async fn decode_webhook_body(
|
||||
&self,
|
||||
request: &IncomingWebhookRequestDetails<'_>,
|
||||
merchant_id: &common_utils::id_type::MerchantId,
|
||||
connector_webhook_details: Option<common_utils::pii::SecretSerdeValue>,
|
||||
connector_name: &str,
|
||||
) -> CustomResult<Vec<u8>, errors::ConnectorError> {
|
||||
match self {
|
||||
Self::Old(connector) => {
|
||||
connector
|
||||
.decode_webhook_body(
|
||||
request,
|
||||
merchant_id,
|
||||
connector_webhook_details,
|
||||
connector_name,
|
||||
)
|
||||
.await
|
||||
}
|
||||
Self::New(connector) => {
|
||||
connector
|
||||
.decode_webhook_body(
|
||||
request,
|
||||
merchant_id,
|
||||
connector_webhook_details,
|
||||
connector_name,
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_webhook_source_verification_algorithm(
|
||||
&self,
|
||||
request: &IncomingWebhookRequestDetails<'_>,
|
||||
) -> CustomResult<Box<dyn crypto::VerifySignature + Send>, errors::ConnectorError> {
|
||||
match self {
|
||||
Self::Old(connector) => connector.get_webhook_source_verification_algorithm(request),
|
||||
Self::New(connector) => connector.get_webhook_source_verification_algorithm(request),
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_webhook_source_verification_merchant_secret(
|
||||
&self,
|
||||
merchant_id: &common_utils::id_type::MerchantId,
|
||||
connector_name: &str,
|
||||
connector_webhook_details: Option<common_utils::pii::SecretSerdeValue>,
|
||||
) -> CustomResult<api_models::webhooks::ConnectorWebhookSecrets, errors::ConnectorError> {
|
||||
match self {
|
||||
Self::Old(connector) => {
|
||||
connector
|
||||
.get_webhook_source_verification_merchant_secret(
|
||||
merchant_id,
|
||||
connector_name,
|
||||
connector_webhook_details,
|
||||
)
|
||||
.await
|
||||
}
|
||||
Self::New(connector) => {
|
||||
connector
|
||||
.get_webhook_source_verification_merchant_secret(
|
||||
merchant_id,
|
||||
connector_name,
|
||||
connector_webhook_details,
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_webhook_source_verification_signature(
|
||||
&self,
|
||||
request: &IncomingWebhookRequestDetails<'_>,
|
||||
connector_webhook_secrets: &api_models::webhooks::ConnectorWebhookSecrets,
|
||||
) -> CustomResult<Vec<u8>, errors::ConnectorError> {
|
||||
match self {
|
||||
Self::Old(connector) => connector
|
||||
.get_webhook_source_verification_signature(request, connector_webhook_secrets),
|
||||
Self::New(connector) => connector
|
||||
.get_webhook_source_verification_signature(request, connector_webhook_secrets),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_webhook_source_verification_message(
|
||||
&self,
|
||||
request: &IncomingWebhookRequestDetails<'_>,
|
||||
merchant_id: &common_utils::id_type::MerchantId,
|
||||
connector_webhook_secrets: &api_models::webhooks::ConnectorWebhookSecrets,
|
||||
) -> CustomResult<Vec<u8>, errors::ConnectorError> {
|
||||
match self {
|
||||
Self::Old(connector) => connector.get_webhook_source_verification_message(
|
||||
request,
|
||||
merchant_id,
|
||||
connector_webhook_secrets,
|
||||
),
|
||||
Self::New(connector) => connector.get_webhook_source_verification_message(
|
||||
request,
|
||||
merchant_id,
|
||||
connector_webhook_secrets,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
async fn verify_webhook_source(
|
||||
&self,
|
||||
request: &IncomingWebhookRequestDetails<'_>,
|
||||
merchant_id: &common_utils::id_type::MerchantId,
|
||||
connector_webhook_details: Option<common_utils::pii::SecretSerdeValue>,
|
||||
connector_account_details: crypto::Encryptable<masking::Secret<serde_json::Value>>,
|
||||
connector_name: &str,
|
||||
) -> CustomResult<bool, errors::ConnectorError> {
|
||||
match self {
|
||||
Self::Old(connector) => {
|
||||
connector
|
||||
.verify_webhook_source(
|
||||
request,
|
||||
merchant_id,
|
||||
connector_webhook_details,
|
||||
connector_account_details,
|
||||
connector_name,
|
||||
)
|
||||
.await
|
||||
}
|
||||
Self::New(connector) => {
|
||||
connector
|
||||
.verify_webhook_source(
|
||||
request,
|
||||
merchant_id,
|
||||
connector_webhook_details,
|
||||
connector_account_details,
|
||||
connector_name,
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_webhook_object_reference_id(
|
||||
&self,
|
||||
request: &IncomingWebhookRequestDetails<'_>,
|
||||
) -> CustomResult<ObjectReferenceId, errors::ConnectorError> {
|
||||
match self {
|
||||
Self::Old(connector) => connector.get_webhook_object_reference_id(request),
|
||||
Self::New(connector) => connector.get_webhook_object_reference_id(request),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_webhook_event_type(
|
||||
&self,
|
||||
request: &IncomingWebhookRequestDetails<'_>,
|
||||
) -> CustomResult<IncomingWebhookEvent, errors::ConnectorError> {
|
||||
match self {
|
||||
Self::Old(connector) => connector.get_webhook_event_type(request),
|
||||
Self::New(connector) => connector.get_webhook_event_type(request),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_webhook_resource_object(
|
||||
&self,
|
||||
request: &IncomingWebhookRequestDetails<'_>,
|
||||
) -> CustomResult<Box<dyn masking::ErasedMaskSerialize>, errors::ConnectorError> {
|
||||
match self {
|
||||
Self::Old(connector) => connector.get_webhook_resource_object(request),
|
||||
Self::New(connector) => connector.get_webhook_resource_object(request),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_webhook_api_response(
|
||||
&self,
|
||||
request: &IncomingWebhookRequestDetails<'_>,
|
||||
error_kind: Option<IncomingWebhookFlowError>,
|
||||
) -> CustomResult<ApplicationResponse<serde_json::Value>, errors::ConnectorError> {
|
||||
match self {
|
||||
Self::Old(connector) => connector.get_webhook_api_response(request, error_kind),
|
||||
Self::New(connector) => connector.get_webhook_api_response(request, error_kind),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_dispute_details(
|
||||
&self,
|
||||
request: &IncomingWebhookRequestDetails<'_>,
|
||||
) -> CustomResult<disputes::DisputePayload, errors::ConnectorError> {
|
||||
match self {
|
||||
Self::Old(connector) => connector.get_dispute_details(request),
|
||||
Self::New(connector) => connector.get_dispute_details(request),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_external_authentication_details(
|
||||
&self,
|
||||
request: &IncomingWebhookRequestDetails<'_>,
|
||||
) -> CustomResult<ExternalAuthenticationPayload, errors::ConnectorError> {
|
||||
match self {
|
||||
Self::Old(connector) => connector.get_external_authentication_details(request),
|
||||
Self::New(connector) => connector.get_external_authentication_details(request),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_mandate_details(
|
||||
&self,
|
||||
request: &IncomingWebhookRequestDetails<'_>,
|
||||
) -> CustomResult<
|
||||
Option<hyperswitch_domain_models::router_flow_types::ConnectorMandateDetails>,
|
||||
errors::ConnectorError,
|
||||
> {
|
||||
match self {
|
||||
Self::Old(connector) => connector.get_mandate_details(request),
|
||||
Self::New(connector) => connector.get_mandate_details(request),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_network_txn_id(
|
||||
&self,
|
||||
request: &IncomingWebhookRequestDetails<'_>,
|
||||
) -> CustomResult<
|
||||
Option<hyperswitch_domain_models::router_flow_types::ConnectorNetworkTxnId>,
|
||||
errors::ConnectorError,
|
||||
> {
|
||||
match self {
|
||||
Self::Old(connector) => connector.get_network_txn_id(request),
|
||||
Self::New(connector) => connector.get_network_txn_id(request),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ConnectorRedirectResponse for ConnectorEnum {
|
||||
fn get_flow_type(
|
||||
&self,
|
||||
query_params: &str,
|
||||
json_payload: Option<serde_json::Value>,
|
||||
action: PaymentAction,
|
||||
) -> CustomResult<common_enums::CallConnectorAction, errors::ConnectorError> {
|
||||
match self {
|
||||
Self::Old(connector) => connector.get_flow_type(query_params, json_payload, action),
|
||||
Self::New(connector) => connector.get_flow_type(query_params, json_payload, action),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ConnectorValidation for ConnectorEnum {
|
||||
fn validate_connector_against_payment_request(
|
||||
&self,
|
||||
capture_method: Option<common_enums::CaptureMethod>,
|
||||
payment_method: common_enums::PaymentMethod,
|
||||
pmt: Option<common_enums::PaymentMethodType>,
|
||||
) -> CustomResult<(), errors::ConnectorError> {
|
||||
match self {
|
||||
Self::Old(connector) => connector.validate_connector_against_payment_request(
|
||||
capture_method,
|
||||
payment_method,
|
||||
pmt,
|
||||
),
|
||||
Self::New(connector) => connector.validate_connector_against_payment_request(
|
||||
capture_method,
|
||||
payment_method,
|
||||
pmt,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn validate_mandate_payment(
|
||||
&self,
|
||||
pm_type: Option<common_enums::PaymentMethodType>,
|
||||
pm_data: PaymentMethodData,
|
||||
) -> CustomResult<(), errors::ConnectorError> {
|
||||
match self {
|
||||
Self::Old(connector) => connector.validate_mandate_payment(pm_type, pm_data),
|
||||
Self::New(connector) => connector.validate_mandate_payment(pm_type, pm_data),
|
||||
}
|
||||
}
|
||||
|
||||
fn validate_psync_reference_id(
|
||||
&self,
|
||||
data: &hyperswitch_domain_models::router_request_types::PaymentsSyncData,
|
||||
is_three_ds: bool,
|
||||
status: common_enums::enums::AttemptStatus,
|
||||
connector_meta_data: Option<common_utils::pii::SecretSerdeValue>,
|
||||
) -> CustomResult<(), errors::ConnectorError> {
|
||||
match self {
|
||||
Self::Old(connector) => connector.validate_psync_reference_id(
|
||||
data,
|
||||
is_three_ds,
|
||||
status,
|
||||
connector_meta_data,
|
||||
),
|
||||
Self::New(connector) => connector.validate_psync_reference_id(
|
||||
data,
|
||||
is_three_ds,
|
||||
status,
|
||||
connector_meta_data,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_webhook_source_verification_mandatory(&self) -> bool {
|
||||
match self {
|
||||
Self::Old(connector) => connector.is_webhook_source_verification_mandatory(),
|
||||
Self::New(connector) => connector.is_webhook_source_verification_mandatory(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ConnectorSpecifications for ConnectorEnum {
|
||||
fn get_supported_payment_methods(&self) -> Option<&'static SupportedPaymentMethods> {
|
||||
match self {
|
||||
Self::Old(connector) => connector.get_supported_payment_methods(),
|
||||
Self::New(connector) => connector.get_supported_payment_methods(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Supported webhooks flows
|
||||
fn get_supported_webhook_flows(&self) -> Option<&'static [common_enums::EventClass]> {
|
||||
match self {
|
||||
Self::Old(connector) => connector.get_supported_webhook_flows(),
|
||||
Self::New(connector) => connector.get_supported_webhook_flows(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Details related to connector
|
||||
fn get_connector_about(&self) -> Option<&'static ConnectorInfo> {
|
||||
match self {
|
||||
Self::Old(connector) => connector.get_connector_about(),
|
||||
Self::New(connector) => connector.get_connector_about(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ConnectorCommon for ConnectorEnum {
|
||||
fn id(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Old(connector) => connector.id(),
|
||||
Self::New(connector) => connector.id(),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_currency_unit(&self) -> CurrencyUnit {
|
||||
match self {
|
||||
Self::Old(connector) => connector.get_currency_unit(),
|
||||
Self::New(connector) => connector.get_currency_unit(),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_auth_header(
|
||||
&self,
|
||||
auth_type: &ConnectorAuthType,
|
||||
) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> {
|
||||
match self {
|
||||
Self::Old(connector) => connector.get_auth_header(auth_type),
|
||||
Self::New(connector) => connector.get_auth_header(auth_type),
|
||||
}
|
||||
}
|
||||
|
||||
fn common_get_content_type(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Old(connector) => connector.common_get_content_type(),
|
||||
Self::New(connector) => connector.common_get_content_type(),
|
||||
}
|
||||
}
|
||||
|
||||
fn base_url<'a>(&self, connectors: &'a Connectors) -> &'a str {
|
||||
match self {
|
||||
Self::Old(connector) => connector.base_url(connectors),
|
||||
Self::New(connector) => connector.base_url(connectors),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_error_response(
|
||||
&self,
|
||||
res: types::Response,
|
||||
event_builder: Option<&mut ConnectorEvent>,
|
||||
) -> CustomResult<ErrorResponse, errors::ConnectorError> {
|
||||
match self {
|
||||
Self::Old(connector) => connector.build_error_response(res, event_builder),
|
||||
Self::New(connector) => connector.build_error_response(res, event_builder),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait representing the connector integration interface
|
||||
///
|
||||
/// This trait defines the methods required for a connector integration interface.
|
||||
pub trait ConnectorIntegrationInterface<F, ResourceCommonData, Req, Resp>: Send + Sync {
|
||||
/// Clone the connector integration interface
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A `Box` containing the cloned connector integration interface
|
||||
fn clone_box(
|
||||
&self,
|
||||
) -> Box<dyn ConnectorIntegrationInterface<F, ResourceCommonData, Req, Resp> + Send + Sync>;
|
||||
/// Get the multiple capture sync method
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A `CustomResult` containing the `CaptureSyncMethod` or a `ConnectorError`
|
||||
fn get_multiple_capture_sync_method(
|
||||
&self,
|
||||
) -> CustomResult<CaptureSyncMethod, errors::ConnectorError>;
|
||||
/// Build a request for the connector integration
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `req` - A reference to the RouterData
|
||||
/// # Returns
|
||||
///
|
||||
/// A `CustomResult` containing an optional Request or a ConnectorError
|
||||
fn build_request(
|
||||
&self,
|
||||
req: &RouterData<F, Req, Resp>,
|
||||
_connectors: &Connectors,
|
||||
) -> CustomResult<Option<Request>, errors::ConnectorError>;
|
||||
/// handles response from the connector
|
||||
fn handle_response(
|
||||
&self,
|
||||
data: &RouterData<F, Req, Resp>,
|
||||
event_builder: Option<&mut ConnectorEvent>,
|
||||
_res: types::Response,
|
||||
) -> CustomResult<RouterData<F, Req, Resp>, errors::ConnectorError>
|
||||
where
|
||||
F: Clone,
|
||||
Req: Clone,
|
||||
Resp: Clone;
|
||||
/// Get the error response
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `res` - The response
|
||||
/// * `event_builder` - An optional event builder
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A `CustomResult` containing the `ErrorResponse` or a `ConnectorError`
|
||||
fn get_error_response(
|
||||
&self,
|
||||
res: types::Response,
|
||||
event_builder: Option<&mut ConnectorEvent>,
|
||||
) -> CustomResult<ErrorResponse, errors::ConnectorError>;
|
||||
/// Get the 5xx error response
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `res` - The response
|
||||
/// * `event_builder` - An optional event builder
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A `CustomResult` containing the `ErrorResponse` or a `ConnectorError`
|
||||
fn get_5xx_error_response(
|
||||
&self,
|
||||
res: types::Response,
|
||||
event_builder: Option<&mut ConnectorEvent>,
|
||||
) -> CustomResult<ErrorResponse, errors::ConnectorError>;
|
||||
}
|
||||
|
||||
impl<T: 'static, ResourceCommonData: 'static, Req: 'static, Resp: 'static>
|
||||
ConnectorIntegrationInterface<T, ResourceCommonData, Req, Resp>
|
||||
for ConnectorIntegrationEnum<'static, T, ResourceCommonData, Req, Resp>
|
||||
where
|
||||
ResourceCommonData: RouterDataConversion<T, Req, Resp> + Clone,
|
||||
T: Clone,
|
||||
Req: Clone,
|
||||
Resp: Clone,
|
||||
{
|
||||
fn get_multiple_capture_sync_method(
|
||||
&self,
|
||||
) -> CustomResult<CaptureSyncMethod, errors::ConnectorError> {
|
||||
match self {
|
||||
ConnectorIntegrationEnum::Old(old_integration) => {
|
||||
old_integration.get_multiple_capture_sync_method()
|
||||
}
|
||||
ConnectorIntegrationEnum::New(new_integration) => {
|
||||
new_integration.get_multiple_capture_sync_method()
|
||||
}
|
||||
}
|
||||
}
|
||||
fn build_request(
|
||||
&self,
|
||||
req: &RouterData<T, Req, Resp>,
|
||||
connectors: &Connectors,
|
||||
) -> CustomResult<Option<Request>, errors::ConnectorError> {
|
||||
match self {
|
||||
ConnectorIntegrationEnum::Old(old_integration) => {
|
||||
old_integration.build_request(req, connectors)
|
||||
}
|
||||
ConnectorIntegrationEnum::New(new_integration) => {
|
||||
let new_router_data = ResourceCommonData::from_old_router_data(req)?;
|
||||
new_integration.build_request_v2(&new_router_data)
|
||||
}
|
||||
}
|
||||
}
|
||||
fn handle_response(
|
||||
&self,
|
||||
data: &RouterData<T, Req, Resp>,
|
||||
event_builder: Option<&mut ConnectorEvent>,
|
||||
res: types::Response,
|
||||
) -> CustomResult<RouterData<T, Req, Resp>, errors::ConnectorError>
|
||||
where
|
||||
T: Clone,
|
||||
Req: Clone,
|
||||
Resp: Clone,
|
||||
{
|
||||
match self {
|
||||
ConnectorIntegrationEnum::Old(old_integration) => {
|
||||
old_integration.handle_response(data, event_builder, res)
|
||||
}
|
||||
ConnectorIntegrationEnum::New(new_integration) => {
|
||||
let new_router_data = ResourceCommonData::from_old_router_data(data)?;
|
||||
new_integration
|
||||
.handle_response_v2(&new_router_data, event_builder, res)
|
||||
.map(ResourceCommonData::to_old_router_data)?
|
||||
}
|
||||
}
|
||||
}
|
||||
fn get_error_response(
|
||||
&self,
|
||||
res: types::Response,
|
||||
event_builder: Option<&mut ConnectorEvent>,
|
||||
) -> CustomResult<ErrorResponse, errors::ConnectorError> {
|
||||
match self {
|
||||
ConnectorIntegrationEnum::Old(old_integration) => {
|
||||
old_integration.get_error_response(res, event_builder)
|
||||
}
|
||||
ConnectorIntegrationEnum::New(new_integration) => {
|
||||
new_integration.get_error_response_v2(res, event_builder)
|
||||
}
|
||||
}
|
||||
}
|
||||
fn get_5xx_error_response(
|
||||
&self,
|
||||
res: types::Response,
|
||||
event_builder: Option<&mut ConnectorEvent>,
|
||||
) -> CustomResult<ErrorResponse, errors::ConnectorError> {
|
||||
match self {
|
||||
ConnectorIntegrationEnum::Old(old_integration) => {
|
||||
old_integration.get_5xx_error_response(res, event_builder)
|
||||
}
|
||||
ConnectorIntegrationEnum::New(new_integration) => {
|
||||
new_integration.get_5xx_error_response(res, event_builder)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn clone_box(
|
||||
&self,
|
||||
) -> Box<dyn ConnectorIntegrationInterface<T, ResourceCommonData, Req, Resp> + Send + Sync>
|
||||
{
|
||||
Box::new(self.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl api::ConnectorTransactionId for ConnectorEnum {
|
||||
/// Get the connector transaction ID
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `payment_attempt` - The payment attempt
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A `Result` containing an optional transaction ID or an ApiErrorResponse
|
||||
fn connector_transaction_id(
|
||||
&self,
|
||||
payment_attempt: hyperswitch_domain_models::payments::payment_attempt::PaymentAttempt,
|
||||
) -> Result<Option<String>, ApiErrorResponse> {
|
||||
match self {
|
||||
Self::Old(connector) => connector.connector_transaction_id(payment_attempt),
|
||||
Self::New(connector) => connector.connector_transaction_id(payment_attempt),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
//! definition of the new connector integration trait
|
||||
|
||||
use common_utils::{
|
||||
errors::CustomResult,
|
||||
request::{Method, Request, RequestBuilder, RequestContent},
|
||||
@ -8,9 +9,54 @@ use masking::Maskable;
|
||||
use serde_json::json;
|
||||
|
||||
use crate::{
|
||||
api::CaptureSyncMethod, errors, events::connector_api_logs::ConnectorEvent, metrics, types,
|
||||
api::{self, CaptureSyncMethod},
|
||||
errors,
|
||||
events::connector_api_logs::ConnectorEvent,
|
||||
metrics, types, webhooks,
|
||||
};
|
||||
|
||||
/// ConnectorV2 trait
|
||||
pub trait ConnectorV2:
|
||||
Send
|
||||
+ api::refunds_v2::RefundV2
|
||||
+ api::payments_v2::PaymentV2
|
||||
+ api::ConnectorRedirectResponse
|
||||
+ webhooks::IncomingWebhook
|
||||
+ api::ConnectorAccessTokenV2
|
||||
+ api::disputes_v2::DisputeV2
|
||||
+ api::files_v2::FileUploadV2
|
||||
+ api::ConnectorTransactionId
|
||||
+ api::PayoutsV2
|
||||
+ api::ConnectorVerifyWebhookSourceV2
|
||||
+ api::FraudCheckV2
|
||||
+ api::ConnectorMandateRevokeV2
|
||||
+ api::authentication_v2::ExternalAuthenticationV2
|
||||
+ api::UnifiedAuthenticationServiceV2
|
||||
{
|
||||
}
|
||||
impl<
|
||||
T: api::refunds_v2::RefundV2
|
||||
+ api::payments_v2::PaymentV2
|
||||
+ api::ConnectorRedirectResponse
|
||||
+ Send
|
||||
+ webhooks::IncomingWebhook
|
||||
+ api::ConnectorAccessTokenV2
|
||||
+ api::disputes_v2::DisputeV2
|
||||
+ api::files_v2::FileUploadV2
|
||||
+ api::ConnectorTransactionId
|
||||
+ api::PayoutsV2
|
||||
+ api::ConnectorVerifyWebhookSourceV2
|
||||
+ api::FraudCheckV2
|
||||
+ api::ConnectorMandateRevokeV2
|
||||
+ api::authentication_v2::ExternalAuthenticationV2
|
||||
+ api::UnifiedAuthenticationServiceV2,
|
||||
> ConnectorV2 for T
|
||||
{
|
||||
}
|
||||
|
||||
/// Alias for Box<&'static (dyn ConnectorV2 + Sync)>
|
||||
pub type BoxedConnectorV2 = Box<&'static (dyn ConnectorV2 + Sync)>;
|
||||
|
||||
/// alias for Box of a type that implements trait ConnectorIntegrationV2
|
||||
pub type BoxedConnectorIntegrationV2<'a, Flow, ResourceCommonData, Req, Resp> =
|
||||
Box<&'a (dyn ConnectorIntegrationV2<Flow, ResourceCommonData, Req, Resp> + Send + Sync)>;
|
||||
@ -39,7 +85,7 @@ where
|
||||
|
||||
/// The new connector integration trait with an additional ResourceCommonData generic parameter
|
||||
pub trait ConnectorIntegrationV2<Flow, ResourceCommonData, Req, Resp>:
|
||||
ConnectorIntegrationAnyV2<Flow, ResourceCommonData, Req, Resp> + Sync + super::api::ConnectorCommon
|
||||
ConnectorIntegrationAnyV2<Flow, ResourceCommonData, Req, Resp> + Sync + api::ConnectorCommon
|
||||
{
|
||||
/// returns a vec of tuple of header key and value
|
||||
fn get_headers(
|
||||
|
||||
800
crates/hyperswitch_interfaces/src/conversion_impls.rs
Normal file
800
crates/hyperswitch_interfaces/src/conversion_impls.rs
Normal file
@ -0,0 +1,800 @@
|
||||
use common_utils::{errors::CustomResult, id_type};
|
||||
use error_stack::ResultExt;
|
||||
#[cfg(feature = "frm")]
|
||||
use hyperswitch_domain_models::router_data_v2::flow_common_types::FrmFlowData;
|
||||
#[cfg(feature = "payouts")]
|
||||
use hyperswitch_domain_models::router_data_v2::flow_common_types::PayoutFlowData;
|
||||
use hyperswitch_domain_models::{
|
||||
payment_address::PaymentAddress,
|
||||
router_data::{self, RouterData},
|
||||
router_data_v2::{
|
||||
flow_common_types::{
|
||||
AccessTokenFlowData, DisputesFlowData, ExternalAuthenticationFlowData, FilesFlowData,
|
||||
MandateRevokeFlowData, PaymentFlowData, RefundFlowData, RevenueRecoveryRecordBackData,
|
||||
UasFlowData, WebhookSourceVerifyData,
|
||||
},
|
||||
RouterDataV2,
|
||||
},
|
||||
};
|
||||
|
||||
use crate::{connector_integration_interface::RouterDataConversion, errors::ConnectorError};
|
||||
|
||||
fn get_irrelevant_id_string(id_name: &str, flow_name: &str) -> String {
|
||||
format!("irrelevant {id_name} in {flow_name} flow")
|
||||
}
|
||||
fn get_default_router_data<F, Req, Resp>(
|
||||
tenant_id: id_type::TenantId,
|
||||
flow_name: &str,
|
||||
request: Req,
|
||||
response: Result<Resp, router_data::ErrorResponse>,
|
||||
) -> RouterData<F, Req, Resp> {
|
||||
RouterData {
|
||||
tenant_id,
|
||||
flow: std::marker::PhantomData,
|
||||
merchant_id: id_type::MerchantId::get_irrelevant_merchant_id(),
|
||||
customer_id: None,
|
||||
connector_customer: None,
|
||||
connector: get_irrelevant_id_string("connector", flow_name),
|
||||
payment_id: id_type::PaymentId::get_irrelevant_id(flow_name)
|
||||
.get_string_repr()
|
||||
.to_owned(),
|
||||
attempt_id: get_irrelevant_id_string("attempt_id", flow_name),
|
||||
status: common_enums::AttemptStatus::default(),
|
||||
payment_method: common_enums::PaymentMethod::default(),
|
||||
connector_auth_type: router_data::ConnectorAuthType::default(),
|
||||
description: None,
|
||||
address: PaymentAddress::default(),
|
||||
auth_type: common_enums::AuthenticationType::default(),
|
||||
connector_meta_data: None,
|
||||
connector_wallets_details: None,
|
||||
amount_captured: None,
|
||||
access_token: None,
|
||||
session_token: None,
|
||||
reference_id: None,
|
||||
payment_method_token: None,
|
||||
recurring_mandate_payment_data: None,
|
||||
preprocessing_id: None,
|
||||
payment_method_balance: None,
|
||||
connector_api_version: None,
|
||||
request,
|
||||
response,
|
||||
connector_request_reference_id: get_irrelevant_id_string(
|
||||
"connector_request_reference_id",
|
||||
flow_name,
|
||||
),
|
||||
#[cfg(feature = "payouts")]
|
||||
payout_method_data: None,
|
||||
#[cfg(feature = "payouts")]
|
||||
quote_id: None,
|
||||
test_mode: None,
|
||||
connector_http_status_code: None,
|
||||
external_latency: None,
|
||||
apple_pay_flow: None,
|
||||
frm_metadata: None,
|
||||
dispute_id: None,
|
||||
refund_id: None,
|
||||
connector_response: None,
|
||||
payment_method_status: None,
|
||||
minor_amount_captured: None,
|
||||
integrity_check: Ok(()),
|
||||
additional_merchant_data: None,
|
||||
header_payload: None,
|
||||
connector_mandate_request_reference_id: None,
|
||||
authentication_id: None,
|
||||
psd2_sca_exemption_type: None,
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for AccessTokenFlowData {
|
||||
fn from_old_router_data(
|
||||
old_router_data: &RouterData<T, Req, Resp>,
|
||||
) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let resource_common_data = Self {};
|
||||
Ok(RouterDataV2 {
|
||||
flow: std::marker::PhantomData,
|
||||
tenant_id: old_router_data.tenant_id.clone(),
|
||||
resource_common_data,
|
||||
connector_auth_type: old_router_data.connector_auth_type.clone(),
|
||||
request: old_router_data.request.clone(),
|
||||
response: old_router_data.response.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_old_router_data(
|
||||
new_router_data: RouterDataV2<T, Self, Req, Resp>,
|
||||
) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let Self {} = new_router_data.resource_common_data;
|
||||
let request = new_router_data.request.clone();
|
||||
let response = new_router_data.response.clone();
|
||||
let router_data = get_default_router_data(
|
||||
new_router_data.tenant_id.clone(),
|
||||
"access token",
|
||||
request,
|
||||
response,
|
||||
);
|
||||
Ok(router_data)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for PaymentFlowData {
|
||||
fn from_old_router_data(
|
||||
old_router_data: &RouterData<T, Req, Resp>,
|
||||
) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let resource_common_data = Self {
|
||||
merchant_id: old_router_data.merchant_id.clone(),
|
||||
customer_id: old_router_data.customer_id.clone(),
|
||||
connector_customer: old_router_data.connector_customer.clone(),
|
||||
payment_id: old_router_data.payment_id.clone(),
|
||||
attempt_id: old_router_data.attempt_id.clone(),
|
||||
status: old_router_data.status,
|
||||
payment_method: old_router_data.payment_method,
|
||||
description: old_router_data.description.clone(),
|
||||
address: old_router_data.address.clone(),
|
||||
auth_type: old_router_data.auth_type,
|
||||
connector_meta_data: old_router_data.connector_meta_data.clone(),
|
||||
amount_captured: old_router_data.amount_captured,
|
||||
minor_amount_captured: old_router_data.minor_amount_captured,
|
||||
access_token: old_router_data.access_token.clone(),
|
||||
session_token: old_router_data.session_token.clone(),
|
||||
reference_id: old_router_data.reference_id.clone(),
|
||||
payment_method_token: old_router_data.payment_method_token.clone(),
|
||||
recurring_mandate_payment_data: old_router_data.recurring_mandate_payment_data.clone(),
|
||||
preprocessing_id: old_router_data.preprocessing_id.clone(),
|
||||
payment_method_balance: old_router_data.payment_method_balance.clone(),
|
||||
connector_api_version: old_router_data.connector_api_version.clone(),
|
||||
connector_request_reference_id: old_router_data.connector_request_reference_id.clone(),
|
||||
test_mode: old_router_data.test_mode,
|
||||
connector_http_status_code: old_router_data.connector_http_status_code,
|
||||
external_latency: old_router_data.external_latency,
|
||||
apple_pay_flow: old_router_data.apple_pay_flow.clone(),
|
||||
connector_response: old_router_data.connector_response.clone(),
|
||||
payment_method_status: old_router_data.payment_method_status,
|
||||
};
|
||||
Ok(RouterDataV2 {
|
||||
flow: std::marker::PhantomData,
|
||||
tenant_id: old_router_data.tenant_id.clone(),
|
||||
resource_common_data,
|
||||
connector_auth_type: old_router_data.connector_auth_type.clone(),
|
||||
request: old_router_data.request.clone(),
|
||||
response: old_router_data.response.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_old_router_data(
|
||||
new_router_data: RouterDataV2<T, Self, Req, Resp>,
|
||||
) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let Self {
|
||||
merchant_id,
|
||||
customer_id,
|
||||
connector_customer,
|
||||
payment_id,
|
||||
attempt_id,
|
||||
status,
|
||||
payment_method,
|
||||
description,
|
||||
address,
|
||||
auth_type,
|
||||
connector_meta_data,
|
||||
amount_captured,
|
||||
minor_amount_captured,
|
||||
access_token,
|
||||
session_token,
|
||||
reference_id,
|
||||
payment_method_token,
|
||||
recurring_mandate_payment_data,
|
||||
preprocessing_id,
|
||||
payment_method_balance,
|
||||
connector_api_version,
|
||||
connector_request_reference_id,
|
||||
test_mode,
|
||||
connector_http_status_code,
|
||||
external_latency,
|
||||
apple_pay_flow,
|
||||
connector_response,
|
||||
payment_method_status,
|
||||
} = new_router_data.resource_common_data;
|
||||
let mut router_data = get_default_router_data(
|
||||
new_router_data.tenant_id.clone(),
|
||||
"payment",
|
||||
new_router_data.request,
|
||||
new_router_data.response,
|
||||
);
|
||||
router_data.merchant_id = merchant_id;
|
||||
router_data.customer_id = customer_id;
|
||||
router_data.connector_customer = connector_customer;
|
||||
router_data.payment_id = payment_id;
|
||||
router_data.attempt_id = attempt_id;
|
||||
router_data.status = status;
|
||||
router_data.payment_method = payment_method;
|
||||
router_data.description = description;
|
||||
router_data.address = address;
|
||||
router_data.auth_type = auth_type;
|
||||
router_data.connector_meta_data = connector_meta_data;
|
||||
router_data.amount_captured = amount_captured;
|
||||
router_data.minor_amount_captured = minor_amount_captured;
|
||||
router_data.access_token = access_token;
|
||||
router_data.session_token = session_token;
|
||||
router_data.reference_id = reference_id;
|
||||
router_data.payment_method_token = payment_method_token;
|
||||
router_data.recurring_mandate_payment_data = recurring_mandate_payment_data;
|
||||
router_data.preprocessing_id = preprocessing_id;
|
||||
router_data.payment_method_balance = payment_method_balance;
|
||||
router_data.connector_api_version = connector_api_version;
|
||||
router_data.connector_request_reference_id = connector_request_reference_id;
|
||||
router_data.test_mode = test_mode;
|
||||
router_data.connector_http_status_code = connector_http_status_code;
|
||||
router_data.external_latency = external_latency;
|
||||
router_data.apple_pay_flow = apple_pay_flow;
|
||||
router_data.connector_response = connector_response;
|
||||
router_data.payment_method_status = payment_method_status;
|
||||
Ok(router_data)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for RefundFlowData {
|
||||
fn from_old_router_data(
|
||||
old_router_data: &RouterData<T, Req, Resp>,
|
||||
) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let resource_common_data = Self {
|
||||
merchant_id: old_router_data.merchant_id.clone(),
|
||||
customer_id: old_router_data.customer_id.clone(),
|
||||
payment_id: old_router_data.payment_id.clone(),
|
||||
attempt_id: old_router_data.attempt_id.clone(),
|
||||
status: old_router_data.status,
|
||||
payment_method: old_router_data.payment_method,
|
||||
connector_meta_data: old_router_data.connector_meta_data.clone(),
|
||||
amount_captured: old_router_data.amount_captured,
|
||||
minor_amount_captured: old_router_data.minor_amount_captured,
|
||||
connector_request_reference_id: old_router_data.connector_request_reference_id.clone(),
|
||||
refund_id: old_router_data.refund_id.clone().ok_or(
|
||||
ConnectorError::MissingRequiredField {
|
||||
field_name: "refund_id",
|
||||
},
|
||||
)?,
|
||||
};
|
||||
Ok(RouterDataV2 {
|
||||
flow: std::marker::PhantomData,
|
||||
tenant_id: old_router_data.tenant_id.clone(),
|
||||
resource_common_data,
|
||||
connector_auth_type: old_router_data.connector_auth_type.clone(),
|
||||
request: old_router_data.request.clone(),
|
||||
response: old_router_data.response.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_old_router_data(
|
||||
new_router_data: RouterDataV2<T, Self, Req, Resp>,
|
||||
) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let Self {
|
||||
merchant_id,
|
||||
customer_id,
|
||||
payment_id,
|
||||
attempt_id,
|
||||
status,
|
||||
payment_method,
|
||||
connector_meta_data,
|
||||
amount_captured,
|
||||
minor_amount_captured,
|
||||
connector_request_reference_id,
|
||||
refund_id,
|
||||
} = new_router_data.resource_common_data;
|
||||
let mut router_data = get_default_router_data(
|
||||
new_router_data.tenant_id.clone(),
|
||||
"refund",
|
||||
new_router_data.request,
|
||||
new_router_data.response,
|
||||
);
|
||||
router_data.merchant_id = merchant_id;
|
||||
router_data.customer_id = customer_id;
|
||||
router_data.payment_id = payment_id;
|
||||
router_data.attempt_id = attempt_id;
|
||||
router_data.status = status;
|
||||
router_data.payment_method = payment_method;
|
||||
router_data.connector_meta_data = connector_meta_data;
|
||||
router_data.amount_captured = amount_captured;
|
||||
router_data.minor_amount_captured = minor_amount_captured;
|
||||
router_data.connector_request_reference_id = connector_request_reference_id;
|
||||
router_data.refund_id = Some(refund_id);
|
||||
Ok(router_data)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for DisputesFlowData {
|
||||
fn from_old_router_data(
|
||||
old_router_data: &RouterData<T, Req, Resp>,
|
||||
) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let resource_common_data = Self {
|
||||
merchant_id: old_router_data.merchant_id.clone(),
|
||||
payment_id: old_router_data.payment_id.clone(),
|
||||
attempt_id: old_router_data.attempt_id.clone(),
|
||||
payment_method: old_router_data.payment_method,
|
||||
connector_meta_data: old_router_data.connector_meta_data.clone(),
|
||||
amount_captured: old_router_data.amount_captured,
|
||||
minor_amount_captured: old_router_data.minor_amount_captured,
|
||||
connector_request_reference_id: old_router_data.connector_request_reference_id.clone(),
|
||||
dispute_id: old_router_data.dispute_id.clone().ok_or(
|
||||
ConnectorError::MissingRequiredField {
|
||||
field_name: "dispute_id",
|
||||
},
|
||||
)?,
|
||||
};
|
||||
Ok(RouterDataV2 {
|
||||
flow: std::marker::PhantomData,
|
||||
tenant_id: old_router_data.tenant_id.clone(),
|
||||
resource_common_data,
|
||||
connector_auth_type: old_router_data.connector_auth_type.clone(),
|
||||
request: old_router_data.request.clone(),
|
||||
response: old_router_data.response.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_old_router_data(
|
||||
new_router_data: RouterDataV2<T, Self, Req, Resp>,
|
||||
) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let Self {
|
||||
merchant_id,
|
||||
payment_id,
|
||||
attempt_id,
|
||||
payment_method,
|
||||
connector_meta_data,
|
||||
amount_captured,
|
||||
minor_amount_captured,
|
||||
connector_request_reference_id,
|
||||
dispute_id,
|
||||
} = new_router_data.resource_common_data;
|
||||
let mut router_data = get_default_router_data(
|
||||
new_router_data.tenant_id.clone(),
|
||||
"Disputes",
|
||||
new_router_data.request,
|
||||
new_router_data.response,
|
||||
);
|
||||
router_data.merchant_id = merchant_id;
|
||||
router_data.payment_id = payment_id;
|
||||
router_data.attempt_id = attempt_id;
|
||||
router_data.payment_method = payment_method;
|
||||
router_data.connector_meta_data = connector_meta_data;
|
||||
router_data.amount_captured = amount_captured;
|
||||
router_data.minor_amount_captured = minor_amount_captured;
|
||||
router_data.connector_request_reference_id = connector_request_reference_id;
|
||||
router_data.dispute_id = Some(dispute_id);
|
||||
Ok(router_data)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "frm")]
|
||||
impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for FrmFlowData {
|
||||
fn from_old_router_data(
|
||||
old_router_data: &RouterData<T, Req, Resp>,
|
||||
) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let resource_common_data = Self {
|
||||
merchant_id: old_router_data.merchant_id.clone(),
|
||||
payment_id: old_router_data.payment_id.clone(),
|
||||
attempt_id: old_router_data.attempt_id.clone(),
|
||||
payment_method: old_router_data.payment_method,
|
||||
connector_request_reference_id: old_router_data.connector_request_reference_id.clone(),
|
||||
auth_type: old_router_data.auth_type,
|
||||
connector_wallets_details: old_router_data.connector_wallets_details.clone(),
|
||||
connector_meta_data: old_router_data.connector_meta_data.clone(),
|
||||
amount_captured: old_router_data.amount_captured,
|
||||
minor_amount_captured: old_router_data.minor_amount_captured,
|
||||
};
|
||||
Ok(RouterDataV2 {
|
||||
tenant_id: old_router_data.tenant_id.clone(),
|
||||
flow: std::marker::PhantomData,
|
||||
resource_common_data,
|
||||
connector_auth_type: old_router_data.connector_auth_type.clone(),
|
||||
request: old_router_data.request.clone(),
|
||||
response: old_router_data.response.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_old_router_data(
|
||||
new_router_data: RouterDataV2<T, Self, Req, Resp>,
|
||||
) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let Self {
|
||||
merchant_id,
|
||||
payment_id,
|
||||
attempt_id,
|
||||
payment_method,
|
||||
connector_request_reference_id,
|
||||
auth_type,
|
||||
connector_wallets_details,
|
||||
connector_meta_data,
|
||||
amount_captured,
|
||||
minor_amount_captured,
|
||||
} = new_router_data.resource_common_data;
|
||||
let mut router_data = get_default_router_data(
|
||||
new_router_data.tenant_id.clone(),
|
||||
"frm",
|
||||
new_router_data.request,
|
||||
new_router_data.response,
|
||||
);
|
||||
|
||||
router_data.merchant_id = merchant_id;
|
||||
router_data.payment_id = payment_id;
|
||||
router_data.attempt_id = attempt_id;
|
||||
router_data.payment_method = payment_method;
|
||||
router_data.connector_request_reference_id = connector_request_reference_id;
|
||||
router_data.auth_type = auth_type;
|
||||
router_data.connector_wallets_details = connector_wallets_details;
|
||||
router_data.connector_meta_data = connector_meta_data;
|
||||
router_data.amount_captured = amount_captured;
|
||||
router_data.minor_amount_captured = minor_amount_captured;
|
||||
|
||||
Ok(router_data)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for FilesFlowData {
|
||||
fn from_old_router_data(
|
||||
old_router_data: &RouterData<T, Req, Resp>,
|
||||
) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let resource_common_data = Self {
|
||||
merchant_id: old_router_data.merchant_id.clone(),
|
||||
payment_id: old_router_data.payment_id.clone(),
|
||||
attempt_id: old_router_data.attempt_id.clone(),
|
||||
connector_meta_data: old_router_data.connector_meta_data.clone(),
|
||||
connector_request_reference_id: old_router_data.connector_request_reference_id.clone(),
|
||||
};
|
||||
Ok(RouterDataV2 {
|
||||
flow: std::marker::PhantomData,
|
||||
tenant_id: old_router_data.tenant_id.clone(),
|
||||
resource_common_data,
|
||||
connector_auth_type: old_router_data.connector_auth_type.clone(),
|
||||
request: old_router_data.request.clone(),
|
||||
response: old_router_data.response.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_old_router_data(
|
||||
new_router_data: RouterDataV2<T, Self, Req, Resp>,
|
||||
) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let Self {
|
||||
merchant_id,
|
||||
payment_id,
|
||||
attempt_id,
|
||||
connector_meta_data,
|
||||
connector_request_reference_id,
|
||||
} = new_router_data.resource_common_data;
|
||||
let mut router_data = get_default_router_data(
|
||||
new_router_data.tenant_id.clone(),
|
||||
"files",
|
||||
new_router_data.request,
|
||||
new_router_data.response,
|
||||
);
|
||||
router_data.merchant_id = merchant_id;
|
||||
router_data.payment_id = payment_id;
|
||||
router_data.attempt_id = attempt_id;
|
||||
router_data.connector_meta_data = connector_meta_data;
|
||||
router_data.connector_request_reference_id = connector_request_reference_id;
|
||||
|
||||
Ok(router_data)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for WebhookSourceVerifyData {
|
||||
fn from_old_router_data(
|
||||
old_router_data: &RouterData<T, Req, Resp>,
|
||||
) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let resource_common_data = Self {
|
||||
merchant_id: old_router_data.merchant_id.clone(),
|
||||
};
|
||||
Ok(RouterDataV2 {
|
||||
tenant_id: old_router_data.tenant_id.clone(),
|
||||
flow: std::marker::PhantomData,
|
||||
resource_common_data,
|
||||
connector_auth_type: old_router_data.connector_auth_type.clone(),
|
||||
request: old_router_data.request.clone(),
|
||||
response: old_router_data.response.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_old_router_data(
|
||||
new_router_data: RouterDataV2<T, Self, Req, Resp>,
|
||||
) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let Self { merchant_id } = new_router_data.resource_common_data;
|
||||
let mut router_data = get_default_router_data(
|
||||
new_router_data.tenant_id.clone(),
|
||||
"webhook source verify",
|
||||
new_router_data.request,
|
||||
new_router_data.response,
|
||||
);
|
||||
router_data.merchant_id = merchant_id;
|
||||
Ok(router_data)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for MandateRevokeFlowData {
|
||||
fn from_old_router_data(
|
||||
old_router_data: &RouterData<T, Req, Resp>,
|
||||
) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let resource_common_data = Self {
|
||||
merchant_id: old_router_data.merchant_id.clone(),
|
||||
customer_id: old_router_data.customer_id.clone().ok_or(
|
||||
ConnectorError::MissingRequiredField {
|
||||
field_name: "customer_id",
|
||||
},
|
||||
)?,
|
||||
payment_id: Some(old_router_data.payment_id.clone()),
|
||||
};
|
||||
Ok(RouterDataV2 {
|
||||
flow: std::marker::PhantomData,
|
||||
tenant_id: old_router_data.tenant_id.clone(),
|
||||
resource_common_data,
|
||||
connector_auth_type: old_router_data.connector_auth_type.clone(),
|
||||
request: old_router_data.request.clone(),
|
||||
response: old_router_data.response.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_old_router_data(
|
||||
new_router_data: RouterDataV2<T, Self, Req, Resp>,
|
||||
) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let Self {
|
||||
merchant_id,
|
||||
customer_id,
|
||||
payment_id,
|
||||
} = new_router_data.resource_common_data;
|
||||
let mut router_data = get_default_router_data(
|
||||
new_router_data.tenant_id.clone(),
|
||||
"mandate revoke",
|
||||
new_router_data.request,
|
||||
new_router_data.response,
|
||||
);
|
||||
router_data.merchant_id = merchant_id;
|
||||
router_data.customer_id = Some(customer_id);
|
||||
router_data.payment_id = payment_id
|
||||
.unwrap_or_else(|| {
|
||||
id_type::PaymentId::get_irrelevant_id("mandate revoke")
|
||||
.get_string_repr()
|
||||
.to_owned()
|
||||
})
|
||||
.to_owned();
|
||||
Ok(router_data)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "payouts")]
|
||||
impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for PayoutFlowData {
|
||||
fn from_old_router_data(
|
||||
old_router_data: &RouterData<T, Req, Resp>,
|
||||
) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let resource_common_data = Self {
|
||||
merchant_id: old_router_data.merchant_id.clone(),
|
||||
customer_id: old_router_data.customer_id.clone(),
|
||||
connector_customer: old_router_data.connector_customer.clone(),
|
||||
address: old_router_data.address.clone(),
|
||||
connector_meta_data: old_router_data.connector_meta_data.clone(),
|
||||
connector_wallets_details: old_router_data.connector_wallets_details.clone(),
|
||||
connector_request_reference_id: old_router_data.connector_request_reference_id.clone(),
|
||||
payout_method_data: old_router_data.payout_method_data.clone(),
|
||||
quote_id: old_router_data.quote_id.clone(),
|
||||
};
|
||||
Ok(RouterDataV2 {
|
||||
tenant_id: old_router_data.tenant_id.clone(),
|
||||
flow: std::marker::PhantomData,
|
||||
resource_common_data,
|
||||
connector_auth_type: old_router_data.connector_auth_type.clone(),
|
||||
request: old_router_data.request.clone(),
|
||||
response: old_router_data.response.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_old_router_data(
|
||||
new_router_data: RouterDataV2<T, Self, Req, Resp>,
|
||||
) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let Self {
|
||||
merchant_id,
|
||||
customer_id,
|
||||
connector_customer,
|
||||
address,
|
||||
connector_meta_data,
|
||||
connector_wallets_details,
|
||||
connector_request_reference_id,
|
||||
payout_method_data,
|
||||
quote_id,
|
||||
} = new_router_data.resource_common_data;
|
||||
let mut router_data = get_default_router_data(
|
||||
new_router_data.tenant_id.clone(),
|
||||
"payout",
|
||||
new_router_data.request,
|
||||
new_router_data.response,
|
||||
);
|
||||
router_data.merchant_id = merchant_id;
|
||||
router_data.customer_id = customer_id;
|
||||
router_data.connector_customer = connector_customer;
|
||||
router_data.address = address;
|
||||
router_data.connector_meta_data = connector_meta_data;
|
||||
router_data.connector_wallets_details = connector_wallets_details;
|
||||
router_data.connector_request_reference_id = connector_request_reference_id;
|
||||
router_data.payout_method_data = payout_method_data;
|
||||
router_data.quote_id = quote_id;
|
||||
Ok(router_data)
|
||||
}
|
||||
}
|
||||
impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp>
|
||||
for ExternalAuthenticationFlowData
|
||||
{
|
||||
fn from_old_router_data(
|
||||
old_router_data: &RouterData<T, Req, Resp>,
|
||||
) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let resource_common_data = Self {
|
||||
merchant_id: old_router_data.merchant_id.clone(),
|
||||
connector_meta_data: old_router_data.connector_meta_data.clone(),
|
||||
address: old_router_data.address.clone(),
|
||||
};
|
||||
Ok(RouterDataV2 {
|
||||
tenant_id: old_router_data.tenant_id.clone(),
|
||||
flow: std::marker::PhantomData,
|
||||
resource_common_data,
|
||||
connector_auth_type: old_router_data.connector_auth_type.clone(),
|
||||
request: old_router_data.request.clone(),
|
||||
response: old_router_data.response.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_old_router_data(
|
||||
new_router_data: RouterDataV2<T, Self, Req, Resp>,
|
||||
) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let Self {
|
||||
merchant_id,
|
||||
connector_meta_data,
|
||||
address,
|
||||
} = new_router_data.resource_common_data;
|
||||
let mut router_data = get_default_router_data(
|
||||
new_router_data.tenant_id.clone(),
|
||||
"external authentication",
|
||||
new_router_data.request,
|
||||
new_router_data.response,
|
||||
);
|
||||
router_data.merchant_id = merchant_id;
|
||||
router_data.connector_meta_data = connector_meta_data;
|
||||
router_data.address = address;
|
||||
Ok(router_data)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp>
|
||||
for RevenueRecoveryRecordBackData
|
||||
{
|
||||
fn from_old_router_data(
|
||||
old_router_data: &RouterData<T, Req, Resp>,
|
||||
) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let resource_common_data = Self {};
|
||||
Ok(RouterDataV2 {
|
||||
flow: std::marker::PhantomData,
|
||||
tenant_id: old_router_data.tenant_id.clone(),
|
||||
resource_common_data,
|
||||
connector_auth_type: old_router_data.connector_auth_type.clone(),
|
||||
request: old_router_data.request.clone(),
|
||||
response: old_router_data.response.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_old_router_data(
|
||||
new_router_data: RouterDataV2<T, Self, Req, Resp>,
|
||||
) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let router_data = get_default_router_data(
|
||||
new_router_data.tenant_id.clone(),
|
||||
"recovery_record_back",
|
||||
new_router_data.request,
|
||||
new_router_data.response,
|
||||
);
|
||||
Ok(router_data)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for UasFlowData {
|
||||
fn from_old_router_data(
|
||||
old_router_data: &RouterData<T, Req, Resp>,
|
||||
) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let resource_common_data = Self {
|
||||
authenticate_by: old_router_data.connector.clone(),
|
||||
source_authentication_id: old_router_data
|
||||
.authentication_id
|
||||
.clone()
|
||||
.ok_or(ConnectorError::MissingRequiredField {
|
||||
field_name: "source_authentication_id",
|
||||
})
|
||||
.attach_printable("missing authentication id for uas")?,
|
||||
};
|
||||
Ok(RouterDataV2 {
|
||||
flow: std::marker::PhantomData,
|
||||
tenant_id: old_router_data.tenant_id.clone(),
|
||||
resource_common_data,
|
||||
connector_auth_type: old_router_data.connector_auth_type.clone(),
|
||||
request: old_router_data.request.clone(),
|
||||
response: old_router_data.response.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_old_router_data(
|
||||
new_router_data: RouterDataV2<T, Self, Req, Resp>,
|
||||
) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let Self {
|
||||
authenticate_by,
|
||||
source_authentication_id,
|
||||
} = new_router_data.resource_common_data;
|
||||
let mut router_data = get_default_router_data(
|
||||
new_router_data.tenant_id.clone(),
|
||||
"uas",
|
||||
new_router_data.request,
|
||||
new_router_data.response,
|
||||
);
|
||||
router_data.connector = authenticate_by;
|
||||
router_data.authentication_id = Some(source_authentication_id);
|
||||
Ok(router_data)
|
||||
}
|
||||
}
|
||||
@ -3,10 +3,16 @@
|
||||
|
||||
pub mod api;
|
||||
pub mod authentication;
|
||||
/// Configuration related functionalities
|
||||
pub mod configs;
|
||||
/// Connector integration interface module
|
||||
pub mod connector_integration_interface;
|
||||
/// definition of the new connector integration trait
|
||||
pub mod connector_integration_v2;
|
||||
/// Constants used throughout the application
|
||||
pub mod consts;
|
||||
/// Conversion implementations
|
||||
pub mod conversion_impls;
|
||||
pub mod disputes;
|
||||
pub mod encryption_interface;
|
||||
pub mod errors;
|
||||
|
||||
Reference in New Issue
Block a user