mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-01 19:42:27 +08:00
feat(ucs): call pre-authentication during authorize as per connector (#9949)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@ -138,6 +138,38 @@ impl UnifiedConnectorServiceClient {
|
||||
}
|
||||
}
|
||||
|
||||
/// Performs Payment Pre Authenticate
|
||||
pub async fn payment_pre_authenticate(
|
||||
&self,
|
||||
payment_pre_authenticate_request: payments_grpc::PaymentServicePreAuthenticateRequest,
|
||||
connector_auth_metadata: ConnectorAuthMetadata,
|
||||
grpc_headers: GrpcHeadersUcs,
|
||||
) -> UnifiedConnectorServiceResult<
|
||||
tonic::Response<payments_grpc::PaymentServicePreAuthenticateResponse>,
|
||||
> {
|
||||
let mut request = tonic::Request::new(payment_pre_authenticate_request);
|
||||
|
||||
let connector_name = connector_auth_metadata.connector_name.clone();
|
||||
let metadata =
|
||||
build_unified_connector_service_grpc_headers(connector_auth_metadata, grpc_headers)?;
|
||||
|
||||
*request.metadata_mut() = metadata;
|
||||
|
||||
self.client
|
||||
.clone()
|
||||
.pre_authenticate(request)
|
||||
.await
|
||||
.change_context(UnifiedConnectorServiceError::PaymentPreAuthenticateFailure)
|
||||
.inspect_err(|error| {
|
||||
logger::error!(
|
||||
grpc_error=?error,
|
||||
method="payment_pre_authenticate",
|
||||
connector_name=?connector_name,
|
||||
"UCS payment pre authenticate gRPC call failed"
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Performs Payment Authorize
|
||||
pub async fn payment_authorize(
|
||||
&self,
|
||||
|
||||
@ -753,12 +753,7 @@ impl ConnectorIntegration<PreAuthenticate, PaymentsPreAuthenticateData, Payments
|
||||
req: &PaymentsPreAuthenticateRouterData,
|
||||
_connectors: &Connectors,
|
||||
) -> CustomResult<RequestContent, errors::ConnectorError> {
|
||||
let minor_amount =
|
||||
req.request
|
||||
.minor_amount
|
||||
.ok_or(errors::ConnectorError::MissingRequiredField {
|
||||
field_name: "minor_amount",
|
||||
})?;
|
||||
let minor_amount = req.request.minor_amount;
|
||||
let currency =
|
||||
req.request
|
||||
.currency
|
||||
|
||||
@ -2698,16 +2698,9 @@ impl TryFrom<&CybersourceRouterData<&PaymentsPreAuthenticateRouterData>>
|
||||
fn try_from(
|
||||
item: &CybersourceRouterData<&PaymentsPreAuthenticateRouterData>,
|
||||
) -> Result<Self, Self::Error> {
|
||||
let payment_method_data = item
|
||||
.router_data
|
||||
.request
|
||||
.payment_method_data
|
||||
.as_ref()
|
||||
.ok_or(errors::ConnectorError::MissingRequiredField {
|
||||
field_name: "payment_method_data",
|
||||
})?;
|
||||
let payment_method_data = item.router_data.request.payment_method_data.clone();
|
||||
|
||||
match payment_method_data.clone() {
|
||||
match payment_method_data {
|
||||
PaymentMethodData::Card(ccard) => {
|
||||
let card_type = match ccard
|
||||
.card_network
|
||||
|
||||
@ -618,20 +618,19 @@ impl TryFrom<PaymentsAuthorizeData> for PaymentsPreProcessingData {
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct PaymentsPreAuthenticateData {
|
||||
pub payment_method_data: Option<PaymentMethodData>,
|
||||
pub amount: Option<i64>,
|
||||
pub payment_method_data: PaymentMethodData,
|
||||
pub amount: i64,
|
||||
pub email: Option<pii::Email>,
|
||||
pub currency: Option<storage_enums::Currency>,
|
||||
pub payment_method_type: Option<storage_enums::PaymentMethodType>,
|
||||
pub router_return_url: Option<String>,
|
||||
pub complete_authorize_url: Option<String>,
|
||||
pub browser_info: Option<BrowserInformation>,
|
||||
pub connector_transaction_id: Option<String>,
|
||||
pub enrolled_for_3ds: bool,
|
||||
pub redirect_response: Option<CompleteAuthorizeRedirectResponse>,
|
||||
|
||||
pub customer_name: Option<Secret<String>>,
|
||||
pub metadata: Option<pii::SecretSerdeValue>,
|
||||
// New amount for amount frame work
|
||||
pub minor_amount: Option<MinorUnit>,
|
||||
pub minor_amount: MinorUnit,
|
||||
}
|
||||
|
||||
impl TryFrom<PaymentsAuthorizeData> for PaymentsPreAuthenticateData {
|
||||
@ -639,17 +638,17 @@ impl TryFrom<PaymentsAuthorizeData> for PaymentsPreAuthenticateData {
|
||||
|
||||
fn try_from(data: PaymentsAuthorizeData) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
payment_method_data: Some(data.payment_method_data),
|
||||
amount: Some(data.amount),
|
||||
minor_amount: Some(data.minor_amount),
|
||||
payment_method_data: data.payment_method_data,
|
||||
customer_name: data.customer_name,
|
||||
metadata: data.metadata.map(Secret::new),
|
||||
amount: data.amount,
|
||||
minor_amount: data.minor_amount,
|
||||
email: data.email,
|
||||
currency: Some(data.currency),
|
||||
payment_method_type: data.payment_method_type,
|
||||
router_return_url: data.router_return_url,
|
||||
complete_authorize_url: data.complete_authorize_url,
|
||||
browser_info: data.browser_info,
|
||||
connector_transaction_id: None,
|
||||
redirect_response: None,
|
||||
enrolled_for_3ds: data.enrolled_for_3ds,
|
||||
})
|
||||
}
|
||||
|
||||
@ -77,6 +77,10 @@ pub enum UnifiedConnectorServiceError {
|
||||
#[error("Failed to perform Payment Authorize from gRPC Server")]
|
||||
PaymentAuthorizeFailure,
|
||||
|
||||
/// Failed to perform Payment Authenticate from gRPC Server
|
||||
#[error("Failed to perform Payment Pre Authenticate from gRPC Server")]
|
||||
PaymentPreAuthenticateFailure,
|
||||
|
||||
/// Failed to perform Payment Get from gRPC Server
|
||||
#[error("Failed to perform Payment Get from gRPC Server")]
|
||||
PaymentGetFailure,
|
||||
|
||||
@ -26,7 +26,7 @@ use crate::{
|
||||
self, access_token, customers, helpers, tokenization, transformers, PaymentData,
|
||||
},
|
||||
unified_connector_service::{
|
||||
build_unified_connector_service_auth_metadata,
|
||||
self, build_unified_connector_service_auth_metadata,
|
||||
handle_unified_connector_service_response_for_payment_authorize,
|
||||
handle_unified_connector_service_response_for_payment_repeat, ucs_logging_wrapper,
|
||||
},
|
||||
@ -565,7 +565,46 @@ impl Feature<api::Authorize, types::PaymentsAuthorizeData> for types::PaymentsAu
|
||||
);
|
||||
match alternate_flow {
|
||||
Some(api_interface::AlternateFlow::PreAuthenticate) => {
|
||||
// Todo: Call UCS PreAuthenticate here
|
||||
let authorize_request_data = self.request.clone();
|
||||
let pre_authneticate_request_data =
|
||||
types::PaymentsPreAuthenticateData::try_from(self.request.to_owned())?;
|
||||
let pre_authneticate_response_data: Result<
|
||||
types::PaymentsResponseData,
|
||||
types::ErrorResponse,
|
||||
> = Err(types::ErrorResponse::default());
|
||||
let mut pre_authenticate_router_data = helpers::router_data_type_conversion::<
|
||||
_,
|
||||
api::PreAuthenticate,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
>(
|
||||
self.clone(),
|
||||
pre_authneticate_request_data,
|
||||
pre_authneticate_response_data,
|
||||
);
|
||||
let _ = call_unified_connector_service_pre_authenticate(
|
||||
&mut pre_authenticate_router_data,
|
||||
state,
|
||||
header_payload,
|
||||
lineage_ids,
|
||||
merchant_connector_account,
|
||||
merchant_context,
|
||||
unified_connector_service_execution_mode,
|
||||
merchant_order_reference_id,
|
||||
)
|
||||
.await;
|
||||
// Convert back to authorize router data while preserving preprocessing response data.
|
||||
let pre_authenticate_response = pre_authenticate_router_data.response.clone();
|
||||
let authorize_router_data =
|
||||
helpers::router_data_type_conversion::<_, api::Authorize, _, _, _, _>(
|
||||
pre_authenticate_router_data,
|
||||
authorize_request_data,
|
||||
pre_authenticate_response,
|
||||
);
|
||||
*self = authorize_router_data;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
None => {
|
||||
@ -962,6 +1001,99 @@ async fn call_unified_connector_service_authorize(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn call_unified_connector_service_pre_authenticate(
|
||||
router_data: &mut types::RouterData<
|
||||
api::PreAuthenticate,
|
||||
types::PaymentsPreAuthenticateData,
|
||||
types::PaymentsResponseData,
|
||||
>,
|
||||
state: &SessionState,
|
||||
header_payload: &domain_payments::HeaderPayload,
|
||||
lineage_ids: grpc_client::LineageIds,
|
||||
#[cfg(feature = "v1")] merchant_connector_account: helpers::MerchantConnectorAccountType,
|
||||
#[cfg(feature = "v2")] merchant_connector_account: domain::MerchantConnectorAccountTypeDetails,
|
||||
merchant_context: &domain::MerchantContext,
|
||||
unified_connector_service_execution_mode: enums::ExecutionMode,
|
||||
merchant_order_reference_id: Option<String>,
|
||||
) -> RouterResult<()> {
|
||||
let client = state
|
||||
.grpc_client
|
||||
.unified_connector_service_client
|
||||
.clone()
|
||||
.ok_or(ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed to fetch Unified Connector Service client")?;
|
||||
|
||||
let payment_pre_authenticate_request =
|
||||
payments_grpc::PaymentServicePreAuthenticateRequest::foreign_try_from(&*router_data)
|
||||
.change_context(ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed to construct Payment Authorize Request")?;
|
||||
|
||||
let connector_auth_metadata =
|
||||
build_unified_connector_service_auth_metadata(merchant_connector_account, merchant_context)
|
||||
.change_context(ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed to construct request metadata")?;
|
||||
let merchant_reference_id = header_payload
|
||||
.x_reference_id
|
||||
.clone()
|
||||
.or(merchant_order_reference_id)
|
||||
.map(|id| id_type::PaymentReferenceId::from_str(id.as_str()))
|
||||
.transpose()
|
||||
.inspect_err(|err| logger::warn!(error=?err, "Invalid Merchant ReferenceId found"))
|
||||
.ok()
|
||||
.flatten()
|
||||
.map(ucs_types::UcsReferenceId::Payment);
|
||||
let headers_builder = state
|
||||
.get_grpc_headers_ucs(unified_connector_service_execution_mode)
|
||||
.external_vault_proxy_metadata(None)
|
||||
.merchant_reference_id(merchant_reference_id)
|
||||
.lineage_ids(lineage_ids);
|
||||
let updated_router_data = Box::pin(ucs_logging_wrapper(
|
||||
router_data.clone(),
|
||||
state,
|
||||
payment_pre_authenticate_request,
|
||||
headers_builder,
|
||||
|mut router_data, payment_pre_authenticate_request, grpc_headers| async move {
|
||||
let response = client
|
||||
.payment_pre_authenticate(
|
||||
payment_pre_authenticate_request,
|
||||
connector_auth_metadata,
|
||||
grpc_headers,
|
||||
)
|
||||
.await
|
||||
.change_context(ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed to authorize payment")?;
|
||||
|
||||
let payment_pre_authenticate_response = response.into_inner();
|
||||
|
||||
let (router_data_response, status_code) =
|
||||
unified_connector_service::handle_unified_connector_service_response_for_payment_pre_authenticate(
|
||||
payment_pre_authenticate_response.clone(),
|
||||
)
|
||||
.change_context(ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed to deserialize UCS response")?;
|
||||
|
||||
let router_data_response = router_data_response.map(|(response, status)| {
|
||||
router_data.status = status;
|
||||
response
|
||||
});
|
||||
router_data.response = router_data_response;
|
||||
router_data.raw_connector_response = payment_pre_authenticate_response
|
||||
.raw_connector_response
|
||||
.clone()
|
||||
.map(|raw_connector_response| raw_connector_response.expose().into());
|
||||
router_data.connector_http_status_code = Some(status_code);
|
||||
|
||||
Ok((router_data, payment_pre_authenticate_response))
|
||||
},
|
||||
))
|
||||
.await?;
|
||||
|
||||
// Copy back the updated data
|
||||
*router_data = updated_router_data;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn call_unified_connector_service_repeat_payment(
|
||||
router_data: &mut types::RouterData<
|
||||
|
||||
@ -770,6 +770,17 @@ pub fn handle_unified_connector_service_response_for_payment_authorize(
|
||||
Ok((router_data_response, status_code))
|
||||
}
|
||||
|
||||
pub fn handle_unified_connector_service_response_for_payment_pre_authenticate(
|
||||
response: payments_grpc::PaymentServicePreAuthenticateResponse,
|
||||
) -> UnifiedConnectorServiceResult {
|
||||
let status_code = transformers::convert_connector_service_status_code(response.status_code)?;
|
||||
|
||||
let router_data_response =
|
||||
Result::<(PaymentsResponseData, AttemptStatus), ErrorResponse>::foreign_try_from(response)?;
|
||||
|
||||
Ok((router_data_response, status_code))
|
||||
}
|
||||
|
||||
pub fn handle_unified_connector_service_response_for_payment_capture(
|
||||
response: payments_grpc::PaymentServiceCaptureResponse,
|
||||
) -> UnifiedConnectorServiceResult {
|
||||
|
||||
@ -9,10 +9,10 @@ use hyperswitch_domain_models::{
|
||||
router_data::{ErrorResponse, RouterData},
|
||||
router_flow_types::{
|
||||
payments::{Authorize, Capture, PSync, SetupMandate},
|
||||
ExternalVaultProxy,
|
||||
unified_authentication_service as uas_flows, ExternalVaultProxy,
|
||||
},
|
||||
router_request_types::{
|
||||
AuthenticationData, ExternalVaultProxyPaymentsData, PaymentsAuthorizeData,
|
||||
self, AuthenticationData, ExternalVaultProxyPaymentsData, PaymentsAuthorizeData,
|
||||
PaymentsCancelData, PaymentsCaptureData, PaymentsSyncData, SetupMandateRequestData,
|
||||
},
|
||||
router_response_types::{PaymentsResponseData, RedirectForm},
|
||||
@ -118,6 +118,101 @@ impl
|
||||
}
|
||||
}
|
||||
|
||||
impl
|
||||
transformers::ForeignTryFrom<
|
||||
&RouterData<
|
||||
uas_flows::PreAuthenticate,
|
||||
router_request_types::PaymentsPreAuthenticateData,
|
||||
PaymentsResponseData,
|
||||
>,
|
||||
> for payments_grpc::PaymentServicePreAuthenticateRequest
|
||||
{
|
||||
type Error = error_stack::Report<UnifiedConnectorServiceError>;
|
||||
fn foreign_try_from(
|
||||
router_data: &RouterData<
|
||||
uas_flows::PreAuthenticate,
|
||||
router_request_types::PaymentsPreAuthenticateData,
|
||||
PaymentsResponseData,
|
||||
>,
|
||||
) -> Result<Self, Self::Error> {
|
||||
let currency = payments_grpc::Currency::foreign_try_from(
|
||||
router_data.request.currency.unwrap_or_default(),
|
||||
)?;
|
||||
|
||||
let payment_method = router_data
|
||||
.request
|
||||
.payment_method_type
|
||||
.map(|payment_method_type| {
|
||||
unified_connector_service::build_unified_connector_service_payment_method(
|
||||
router_data.request.payment_method_data.clone(),
|
||||
payment_method_type,
|
||||
)
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
let address = payments_grpc::PaymentAddress::foreign_try_from(router_data.address.clone())?;
|
||||
let connector_metadata_string = router_data
|
||||
.connector_meta_data
|
||||
.as_ref()
|
||||
.map(|metadata| metadata.encode_to_string_of_json())
|
||||
.transpose()
|
||||
.change_context(
|
||||
UnifiedConnectorServiceError::RequestEncodingFailedWithReason(
|
||||
"Failed to serialize router_data.connector_meta_data to string of json"
|
||||
.to_string(),
|
||||
),
|
||||
)?;
|
||||
let mut metadata = router_data
|
||||
.request
|
||||
.metadata
|
||||
.as_ref()
|
||||
.and_then(|val| val.peek().as_object())
|
||||
.map(|map| {
|
||||
map.iter()
|
||||
.filter_map(|(k, v)| v.as_str().map(|s| (k.clone(), s.to_string())))
|
||||
.collect::<HashMap<String, String>>()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
metadata.extend(
|
||||
connector_metadata_string
|
||||
.map(|connector_metadata| ("connector_meta_data".to_string(), connector_metadata)),
|
||||
);
|
||||
Ok(Self {
|
||||
request_ref_id: Some(Identifier {
|
||||
id_type: Some(payments_grpc::identifier::IdType::Id(
|
||||
router_data.connector_request_reference_id.clone(),
|
||||
)),
|
||||
}),
|
||||
amount: router_data.request.amount,
|
||||
currency: currency.into(),
|
||||
minor_amount: router_data.request.minor_amount.get_amount_as_i64(),
|
||||
payment_method,
|
||||
email: router_data
|
||||
.request
|
||||
.email
|
||||
.clone()
|
||||
.map(|e| e.expose().expose().into()),
|
||||
customer_name: router_data
|
||||
.request
|
||||
.customer_name
|
||||
.clone()
|
||||
.map(|customer_name| customer_name.peek().to_owned()),
|
||||
address: Some(address),
|
||||
enrolled_for_3ds: router_data.request.enrolled_for_3ds,
|
||||
metadata,
|
||||
return_url: router_data.request.router_return_url.clone(),
|
||||
continue_redirection_url: router_data.request.complete_authorize_url.clone(),
|
||||
access_token: None,
|
||||
browser_info: router_data
|
||||
.request
|
||||
.browser_info
|
||||
.clone()
|
||||
.map(payments_grpc::BrowserInformation::foreign_try_from)
|
||||
.transpose()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl transformers::ForeignTryFrom<&RouterData<Capture, PaymentsCaptureData, PaymentsResponseData>>
|
||||
for payments_grpc::PaymentServiceCaptureRequest
|
||||
{
|
||||
@ -229,7 +324,32 @@ impl
|
||||
.clone()
|
||||
.map(payments_grpc::AuthenticationData::foreign_try_from)
|
||||
.transpose()?;
|
||||
|
||||
let connector_metadata_string = router_data
|
||||
.connector_meta_data
|
||||
.as_ref()
|
||||
.map(|metadata| metadata.encode_to_string_of_json())
|
||||
.transpose()
|
||||
.change_context(
|
||||
UnifiedConnectorServiceError::RequestEncodingFailedWithReason(
|
||||
"Failed to serialize router_data.connector_meta_data to string of json"
|
||||
.to_string(),
|
||||
),
|
||||
)?;
|
||||
let mut metadata = router_data
|
||||
.request
|
||||
.metadata
|
||||
.as_ref()
|
||||
.and_then(|val| val.as_object())
|
||||
.map(|map| {
|
||||
map.iter()
|
||||
.filter_map(|(k, v)| v.as_str().map(|s| (k.clone(), s.to_string())))
|
||||
.collect::<HashMap<String, String>>()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
metadata.extend(
|
||||
connector_metadata_string
|
||||
.map(|connector_metadata| ("connector_meta_data".to_string(), connector_metadata)),
|
||||
);
|
||||
Ok(Self {
|
||||
amount: router_data.request.amount,
|
||||
currency: currency.into(),
|
||||
@ -287,17 +407,7 @@ impl
|
||||
.customer_id
|
||||
.as_ref()
|
||||
.map(|id| id.get_string_repr().to_string()),
|
||||
metadata: router_data
|
||||
.request
|
||||
.metadata
|
||||
.as_ref()
|
||||
.and_then(|val| val.as_object())
|
||||
.map(|map| {
|
||||
map.iter()
|
||||
.filter_map(|(k, v)| v.as_str().map(|s| (k.clone(), s.to_string())))
|
||||
.collect::<HashMap<String, String>>()
|
||||
})
|
||||
.unwrap_or_default(),
|
||||
metadata,
|
||||
test_mode: router_data.test_mode,
|
||||
connector_customer_id: router_data.connector_customer.clone(),
|
||||
merchant_account_metadata: HashMap::new(),
|
||||
@ -629,6 +739,111 @@ impl
|
||||
}
|
||||
}
|
||||
|
||||
impl transformers::ForeignTryFrom<payments_grpc::PaymentServicePreAuthenticateResponse>
|
||||
for Result<(PaymentsResponseData, AttemptStatus), ErrorResponse>
|
||||
{
|
||||
type Error = error_stack::Report<UnifiedConnectorServiceError>;
|
||||
fn foreign_try_from(
|
||||
response: payments_grpc::PaymentServicePreAuthenticateResponse,
|
||||
) -> Result<Self, Self::Error> {
|
||||
let connector_response_reference_id =
|
||||
response.response_ref_id.as_ref().and_then(|identifier| {
|
||||
identifier
|
||||
.id_type
|
||||
.clone()
|
||||
.and_then(|id_type| match id_type {
|
||||
payments_grpc::identifier::IdType::Id(id) => Some(id),
|
||||
payments_grpc::identifier::IdType::EncodedData(encoded_data) => {
|
||||
Some(encoded_data)
|
||||
}
|
||||
payments_grpc::identifier::IdType::NoResponseIdMarker(_) => None,
|
||||
})
|
||||
});
|
||||
|
||||
let resource_id: router_request_types::ResponseId = match response
|
||||
.transaction_id
|
||||
.as_ref()
|
||||
.and_then(|id| id.id_type.clone())
|
||||
{
|
||||
Some(payments_grpc::identifier::IdType::Id(id)) => {
|
||||
router_request_types::ResponseId::ConnectorTransactionId(id)
|
||||
}
|
||||
Some(payments_grpc::identifier::IdType::EncodedData(encoded_data)) => {
|
||||
router_request_types::ResponseId::EncodedData(encoded_data)
|
||||
}
|
||||
Some(payments_grpc::identifier::IdType::NoResponseIdMarker(_)) | None => {
|
||||
router_request_types::ResponseId::NoResponseId
|
||||
}
|
||||
};
|
||||
|
||||
let (connector_metadata, redirection_data) = match response.redirection_data.clone() {
|
||||
Some(redirection_data) => match redirection_data.form_type {
|
||||
Some(ref form_type) => match form_type {
|
||||
payments_grpc::redirect_form::FormType::Uri(uri) => {
|
||||
// For UPI intent, store the URI in connector_metadata for SDK UPI intent pattern
|
||||
let sdk_uri_info = api_models::payments::SdkUpiIntentInformation {
|
||||
sdk_uri: Url::parse(&uri.uri)
|
||||
.change_context(UnifiedConnectorServiceError::ParsingFailed)?,
|
||||
};
|
||||
(
|
||||
Some(sdk_uri_info.encode_to_value())
|
||||
.transpose()
|
||||
.change_context(UnifiedConnectorServiceError::ParsingFailed)?,
|
||||
None,
|
||||
)
|
||||
}
|
||||
_ => (
|
||||
None,
|
||||
Some(RedirectForm::foreign_try_from(redirection_data)).transpose()?,
|
||||
),
|
||||
},
|
||||
None => (None, None),
|
||||
},
|
||||
None => (None, None),
|
||||
};
|
||||
|
||||
let status_code = convert_connector_service_status_code(response.status_code)?;
|
||||
|
||||
let response = if response.error_code.is_some() {
|
||||
let attempt_status = match response.status() {
|
||||
payments_grpc::PaymentStatus::AttemptStatusUnspecified => None,
|
||||
_ => Some(AttemptStatus::foreign_try_from(response.status())?),
|
||||
};
|
||||
|
||||
Err(ErrorResponse {
|
||||
code: response.error_code().to_owned(),
|
||||
message: response.error_message().to_owned(),
|
||||
reason: Some(response.error_message().to_owned()),
|
||||
status_code,
|
||||
attempt_status,
|
||||
connector_transaction_id: connector_response_reference_id,
|
||||
network_decline_code: None,
|
||||
network_advice_code: None,
|
||||
network_error_message: None,
|
||||
connector_metadata: None,
|
||||
})
|
||||
} else {
|
||||
let status = AttemptStatus::foreign_try_from(response.status())?;
|
||||
|
||||
Ok((
|
||||
PaymentsResponseData::TransactionResponse {
|
||||
resource_id,
|
||||
redirection_data: Box::new(redirection_data),
|
||||
mandate_reference: Box::new(None),
|
||||
connector_metadata,
|
||||
network_txn_id: response.network_txn_id.clone(),
|
||||
connector_response_reference_id,
|
||||
incremental_authorization_allowed: None,
|
||||
charges: None,
|
||||
},
|
||||
status,
|
||||
))
|
||||
};
|
||||
|
||||
Ok(response)
|
||||
}
|
||||
}
|
||||
|
||||
impl transformers::ForeignTryFrom<payments_grpc::PaymentServiceAuthorizeResponse>
|
||||
for Result<(PaymentsResponseData, AttemptStatus), ErrorResponse>
|
||||
{
|
||||
@ -651,10 +866,20 @@ impl transformers::ForeignTryFrom<payments_grpc::PaymentServiceAuthorizeResponse
|
||||
})
|
||||
});
|
||||
|
||||
let resource_id: hyperswitch_domain_models::router_request_types::ResponseId = match response.transaction_id.as_ref().and_then(|id| id.id_type.clone()) {
|
||||
Some(payments_grpc::identifier::IdType::Id(id)) => hyperswitch_domain_models::router_request_types::ResponseId::ConnectorTransactionId(id),
|
||||
Some(payments_grpc::identifier::IdType::EncodedData(encoded_data)) => hyperswitch_domain_models::router_request_types::ResponseId::EncodedData(encoded_data),
|
||||
Some(payments_grpc::identifier::IdType::NoResponseIdMarker(_)) | None => hyperswitch_domain_models::router_request_types::ResponseId::NoResponseId,
|
||||
let resource_id: router_request_types::ResponseId = match response
|
||||
.transaction_id
|
||||
.as_ref()
|
||||
.and_then(|id| id.id_type.clone())
|
||||
{
|
||||
Some(payments_grpc::identifier::IdType::Id(id)) => {
|
||||
router_request_types::ResponseId::ConnectorTransactionId(id)
|
||||
}
|
||||
Some(payments_grpc::identifier::IdType::EncodedData(encoded_data)) => {
|
||||
router_request_types::ResponseId::EncodedData(encoded_data)
|
||||
}
|
||||
Some(payments_grpc::identifier::IdType::NoResponseIdMarker(_)) | None => {
|
||||
router_request_types::ResponseId::NoResponseId
|
||||
}
|
||||
};
|
||||
|
||||
let (connector_metadata, redirection_data) = match response.redirection_data.clone() {
|
||||
@ -749,10 +974,20 @@ impl transformers::ForeignTryFrom<payments_grpc::PaymentServiceCaptureResponse>
|
||||
|
||||
let status_code = convert_connector_service_status_code(response.status_code)?;
|
||||
|
||||
let resource_id: hyperswitch_domain_models::router_request_types::ResponseId = match response.transaction_id.as_ref().and_then(|id| id.id_type.clone()) {
|
||||
Some(payments_grpc::identifier::IdType::Id(id)) => hyperswitch_domain_models::router_request_types::ResponseId::ConnectorTransactionId(id),
|
||||
Some(payments_grpc::identifier::IdType::EncodedData(encoded_data)) => hyperswitch_domain_models::router_request_types::ResponseId::EncodedData(encoded_data),
|
||||
Some(payments_grpc::identifier::IdType::NoResponseIdMarker(_)) | None => hyperswitch_domain_models::router_request_types::ResponseId::NoResponseId,
|
||||
let resource_id: router_request_types::ResponseId = match response
|
||||
.transaction_id
|
||||
.as_ref()
|
||||
.and_then(|id| id.id_type.clone())
|
||||
{
|
||||
Some(payments_grpc::identifier::IdType::Id(id)) => {
|
||||
router_request_types::ResponseId::ConnectorTransactionId(id)
|
||||
}
|
||||
Some(payments_grpc::identifier::IdType::EncodedData(encoded_data)) => {
|
||||
router_request_types::ResponseId::EncodedData(encoded_data)
|
||||
}
|
||||
Some(payments_grpc::identifier::IdType::NoResponseIdMarker(_)) | None => {
|
||||
router_request_types::ResponseId::NoResponseId
|
||||
}
|
||||
};
|
||||
|
||||
let response = if response.error_code.is_some() {
|
||||
@ -846,44 +1081,57 @@ impl transformers::ForeignTryFrom<payments_grpc::PaymentServiceRegisterResponse>
|
||||
} else {
|
||||
let status = AttemptStatus::foreign_try_from(response.status())?;
|
||||
|
||||
Ok((PaymentsResponseData::TransactionResponse {
|
||||
resource_id: response.registration_id.as_ref().and_then(|identifier| {
|
||||
Ok((
|
||||
PaymentsResponseData::TransactionResponse {
|
||||
resource_id: response
|
||||
.registration_id
|
||||
.as_ref()
|
||||
.and_then(|identifier| {
|
||||
identifier
|
||||
.id_type
|
||||
.clone()
|
||||
.and_then(|id_type| match id_type {
|
||||
payments_grpc::identifier::IdType::Id(id) => Some(
|
||||
hyperswitch_domain_models::router_request_types::ResponseId::ConnectorTransactionId(id),
|
||||
router_request_types::ResponseId::ConnectorTransactionId(
|
||||
id,
|
||||
),
|
||||
payments_grpc::identifier::IdType::EncodedData(encoded_data) => Some(
|
||||
hyperswitch_domain_models::router_request_types::ResponseId::ConnectorTransactionId(encoded_data),
|
||||
),
|
||||
payments_grpc::identifier::IdType::NoResponseIdMarker(_) => None,
|
||||
payments_grpc::identifier::IdType::EncodedData(
|
||||
encoded_data,
|
||||
) => Some(
|
||||
router_request_types::ResponseId::ConnectorTransactionId(
|
||||
encoded_data,
|
||||
),
|
||||
),
|
||||
payments_grpc::identifier::IdType::NoResponseIdMarker(_) => {
|
||||
None
|
||||
}
|
||||
})
|
||||
}).unwrap_or(hyperswitch_domain_models::router_request_types::ResponseId::NoResponseId),
|
||||
})
|
||||
.unwrap_or(router_request_types::ResponseId::NoResponseId),
|
||||
redirection_data: Box::new(
|
||||
response
|
||||
.redirection_data
|
||||
.clone()
|
||||
.map(RedirectForm::foreign_try_from)
|
||||
.transpose()?
|
||||
.transpose()?,
|
||||
),
|
||||
mandate_reference: Box::new(
|
||||
response.mandate_reference.map(|grpc_mandate| {
|
||||
mandate_reference: Box::new(response.mandate_reference.map(|grpc_mandate| {
|
||||
hyperswitch_domain_models::router_response_types::MandateReference {
|
||||
connector_mandate_id: grpc_mandate.mandate_id,
|
||||
payment_method_id: grpc_mandate.payment_method_id,
|
||||
mandate_metadata: None,
|
||||
connector_mandate_request_reference_id: None,
|
||||
}
|
||||
})
|
||||
),
|
||||
})),
|
||||
connector_metadata: None,
|
||||
network_txn_id: response.network_txn_id,
|
||||
connector_response_reference_id,
|
||||
incremental_authorization_allowed: response.incremental_authorization_allowed,
|
||||
charges: None,
|
||||
}, status))
|
||||
},
|
||||
status,
|
||||
))
|
||||
};
|
||||
|
||||
Ok(response)
|
||||
@ -942,10 +1190,15 @@ impl transformers::ForeignTryFrom<payments_grpc::PaymentServiceRepeatEverythingR
|
||||
} else {
|
||||
let status = AttemptStatus::foreign_try_from(response.status())?;
|
||||
|
||||
Ok((PaymentsResponseData::TransactionResponse {
|
||||
Ok((
|
||||
PaymentsResponseData::TransactionResponse {
|
||||
resource_id: match transaction_id.as_ref() {
|
||||
Some(transaction_id) => hyperswitch_domain_models::router_request_types::ResponseId::ConnectorTransactionId(transaction_id.clone()),
|
||||
None => hyperswitch_domain_models::router_request_types::ResponseId::NoResponseId,
|
||||
Some(transaction_id) => {
|
||||
router_request_types::ResponseId::ConnectorTransactionId(
|
||||
transaction_id.clone(),
|
||||
)
|
||||
}
|
||||
None => router_request_types::ResponseId::NoResponseId,
|
||||
},
|
||||
redirection_data: Box::new(None),
|
||||
mandate_reference: Box::new(None),
|
||||
@ -954,7 +1207,9 @@ impl transformers::ForeignTryFrom<payments_grpc::PaymentServiceRepeatEverythingR
|
||||
connector_response_reference_id,
|
||||
incremental_authorization_allowed: None,
|
||||
charges: None,
|
||||
}, status))
|
||||
},
|
||||
status,
|
||||
))
|
||||
};
|
||||
|
||||
Ok(response)
|
||||
@ -1132,15 +1387,13 @@ impl transformers::ForeignTryFrom<AuthenticationType> for payments_grpc::Authent
|
||||
}
|
||||
}
|
||||
|
||||
impl
|
||||
transformers::ForeignTryFrom<
|
||||
hyperswitch_domain_models::router_request_types::BrowserInformation,
|
||||
> for payments_grpc::BrowserInformation
|
||||
impl transformers::ForeignTryFrom<router_request_types::BrowserInformation>
|
||||
for payments_grpc::BrowserInformation
|
||||
{
|
||||
type Error = error_stack::Report<UnifiedConnectorServiceError>;
|
||||
|
||||
fn foreign_try_from(
|
||||
browser_info: hyperswitch_domain_models::router_request_types::BrowserInformation,
|
||||
browser_info: router_request_types::BrowserInformation,
|
||||
) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
color_depth: browser_info.color_depth.map(|v| v.into()),
|
||||
@ -1497,31 +1750,41 @@ impl transformers::ForeignTryFrom<payments_grpc::PaymentServiceVoidResponse>
|
||||
|
||||
Ok((
|
||||
PaymentsResponseData::TransactionResponse {
|
||||
resource_id: response.transaction_id.as_ref().and_then(|identifier| {
|
||||
resource_id: response
|
||||
.transaction_id
|
||||
.as_ref()
|
||||
.and_then(|identifier| {
|
||||
identifier
|
||||
.id_type
|
||||
.clone()
|
||||
.and_then(|id_type| match id_type {
|
||||
payments_grpc::identifier::IdType::Id(id) => Some(
|
||||
hyperswitch_domain_models::router_request_types::ResponseId::ConnectorTransactionId(id),
|
||||
router_request_types::ResponseId::ConnectorTransactionId(
|
||||
id,
|
||||
),
|
||||
payments_grpc::identifier::IdType::EncodedData(encoded_data) => Some(
|
||||
hyperswitch_domain_models::router_request_types::ResponseId::ConnectorTransactionId(encoded_data),
|
||||
),
|
||||
payments_grpc::identifier::IdType::NoResponseIdMarker(_) => None,
|
||||
payments_grpc::identifier::IdType::EncodedData(
|
||||
encoded_data,
|
||||
) => Some(
|
||||
router_request_types::ResponseId::ConnectorTransactionId(
|
||||
encoded_data,
|
||||
),
|
||||
),
|
||||
payments_grpc::identifier::IdType::NoResponseIdMarker(_) => {
|
||||
None
|
||||
}
|
||||
})
|
||||
}).unwrap_or(hyperswitch_domain_models::router_request_types::ResponseId::NoResponseId),
|
||||
})
|
||||
.unwrap_or(router_request_types::ResponseId::NoResponseId),
|
||||
redirection_data: Box::new(None),
|
||||
mandate_reference: Box::new(
|
||||
response.mandate_reference.map(|grpc_mandate| {
|
||||
mandate_reference: Box::new(response.mandate_reference.map(|grpc_mandate| {
|
||||
hyperswitch_domain_models::router_response_types::MandateReference {
|
||||
connector_mandate_id: grpc_mandate.mandate_id,
|
||||
payment_method_id: grpc_mandate.payment_method_id,
|
||||
mandate_metadata: None,
|
||||
connector_mandate_request_reference_id: None,
|
||||
}
|
||||
})
|
||||
),
|
||||
})),
|
||||
connector_metadata: None,
|
||||
network_txn_id: None,
|
||||
connector_response_reference_id,
|
||||
|
||||
@ -77,12 +77,12 @@ pub use hyperswitch_domain_models::{
|
||||
PaymentMethodTokenizationData, PaymentsApproveData, PaymentsAuthorizeData,
|
||||
PaymentsCancelData, PaymentsCancelPostCaptureData, PaymentsCaptureData,
|
||||
PaymentsExtendAuthorizationData, PaymentsIncrementalAuthorizationData,
|
||||
PaymentsPostProcessingData, PaymentsPostSessionTokensData, PaymentsPreProcessingData,
|
||||
PaymentsRejectData, PaymentsSessionData, PaymentsSyncData, PaymentsTaxCalculationData,
|
||||
PaymentsUpdateMetadataData, RefundsData, ResponseId, RetrieveFileRequestData,
|
||||
SdkPaymentsSessionUpdateData, SetupMandateRequestData, SplitRefundsRequest,
|
||||
SubmitEvidenceRequestData, SyncRequestType, UploadFileRequestData, VaultRequestData,
|
||||
VerifyWebhookSourceRequestData,
|
||||
PaymentsPostProcessingData, PaymentsPostSessionTokensData, PaymentsPreAuthenticateData,
|
||||
PaymentsPreProcessingData, PaymentsRejectData, PaymentsSessionData, PaymentsSyncData,
|
||||
PaymentsTaxCalculationData, PaymentsUpdateMetadataData, RefundsData, ResponseId,
|
||||
RetrieveFileRequestData, SdkPaymentsSessionUpdateData, SetupMandateRequestData,
|
||||
SplitRefundsRequest, SubmitEvidenceRequestData, SyncRequestType, UploadFileRequestData,
|
||||
VaultRequestData, VerifyWebhookSourceRequestData,
|
||||
},
|
||||
router_response_types::{
|
||||
revenue_recovery::{
|
||||
|
||||
@ -46,6 +46,7 @@ use error_stack::ResultExt;
|
||||
pub use hyperswitch_domain_models::router_flow_types::{
|
||||
access_token_auth::{AccessTokenAuth, AccessTokenAuthentication},
|
||||
mandate_revoke::MandateRevoke,
|
||||
unified_authentication_service::*,
|
||||
webhooks::VerifyWebhookSource,
|
||||
};
|
||||
pub use hyperswitch_interfaces::{
|
||||
|
||||
Reference in New Issue
Block a user