mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-28 04:04:55 +08:00
feat(core): consume card details from billing connectors and first error codes and store them in payment intent table (#8250)
Co-authored-by: Nishanth Challa <nishanth.challa@Nishanth-Challa-C0WGKCFHLF.local> Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
1ed2f210b2
commit
abe9708d1c
@ -199,6 +199,8 @@ impl<F: Send + Clone + Sync>
|
||||
retry_count: request.retry_count,
|
||||
invoice_next_billing_time: request.invoice_next_billing_time,
|
||||
triggered_by: request.triggered_by,
|
||||
card_network: request.card_network.clone(),
|
||||
card_issuer: request.card_issuer.clone(),
|
||||
};
|
||||
let payment_address = hyperswitch_domain_models::payment_address::PaymentAddress::new(
|
||||
payment_intent
|
||||
|
||||
@ -4900,6 +4900,22 @@ impl ForeignFrom<&diesel_models::types::BillingConnectorPaymentDetails>
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "v2")]
|
||||
impl ForeignFrom<&diesel_models::types::BillingConnectorPaymentMethodDetails>
|
||||
for api_models::payments::BillingConnectorPaymentMethodDetails
|
||||
{
|
||||
fn foreign_from(metadata: &diesel_models::types::BillingConnectorPaymentMethodDetails) -> Self {
|
||||
match metadata {
|
||||
diesel_models::types::BillingConnectorPaymentMethodDetails::Card(card_details) => {
|
||||
Self::Card(api_models::payments::BillingConnectorAdditionalCardInfo {
|
||||
card_issuer: card_details.card_issuer.clone(),
|
||||
card_network: card_details.card_network.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "v2")]
|
||||
impl ForeignFrom<&hyperswitch_domain_models::payments::payment_attempt::ErrorDetails>
|
||||
for api_models::payments::ErrorDetails
|
||||
@ -4965,6 +4981,17 @@ impl ForeignFrom<&diesel_models::types::FeatureMetadata> for api_models::payment
|
||||
),
|
||||
invoice_next_billing_time: payment_revenue_recovery_metadata
|
||||
.invoice_next_billing_time,
|
||||
billing_connector_payment_method_details:payment_revenue_recovery_metadata
|
||||
.billing_connector_payment_method_details.as_ref().map(api_models::payments::BillingConnectorPaymentMethodDetails::foreign_from),
|
||||
first_payment_attempt_network_advice_code: payment_revenue_recovery_metadata
|
||||
.first_payment_attempt_network_advice_code
|
||||
.clone(),
|
||||
first_payment_attempt_network_decline_code: payment_revenue_recovery_metadata
|
||||
.first_payment_attempt_network_decline_code
|
||||
.clone(),
|
||||
first_payment_attempt_pg_error_code: payment_revenue_recovery_metadata
|
||||
.first_payment_attempt_pg_error_code
|
||||
.clone(),
|
||||
}
|
||||
});
|
||||
let apple_pay_details = feature_metadata
|
||||
|
||||
@ -69,14 +69,14 @@ pub async fn perform_execute_payment(
|
||||
|
||||
match record_attempt {
|
||||
Ok(_) => {
|
||||
let action = types::Action::execute_payment(
|
||||
let action = Box::pin(types::Action::execute_payment(
|
||||
state,
|
||||
revenue_recovery_payment_data.merchant_account.get_id(),
|
||||
payment_intent,
|
||||
execute_task_process,
|
||||
revenue_recovery_payment_data,
|
||||
&revenue_recovery_metadata,
|
||||
)
|
||||
))
|
||||
.await?;
|
||||
Box::pin(action.execute_payment_task_response_handler(
|
||||
state,
|
||||
|
||||
@ -183,16 +183,22 @@ pub async fn record_internal_attempt_api(
|
||||
message: "get_revenue_recovery_attempt was not constructed".to_string(),
|
||||
})?;
|
||||
|
||||
let request_payload = revenue_recovery_attempt_data.create_payment_record_request(
|
||||
&revenue_recovery_payment_data.billing_mca.id,
|
||||
Some(
|
||||
revenue_recovery_metadata
|
||||
.active_attempt_payment_connector_id
|
||||
.clone(),
|
||||
),
|
||||
Some(revenue_recovery_metadata.connector),
|
||||
common_enums::TriggeredBy::Internal,
|
||||
);
|
||||
let request_payload = revenue_recovery_attempt_data
|
||||
.create_payment_record_request(
|
||||
state,
|
||||
&revenue_recovery_payment_data.billing_mca.id,
|
||||
Some(
|
||||
revenue_recovery_metadata
|
||||
.active_attempt_payment_connector_id
|
||||
.clone(),
|
||||
),
|
||||
Some(revenue_recovery_metadata.connector),
|
||||
common_enums::TriggeredBy::Internal,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::GenericNotFoundError {
|
||||
message: "Cannot Create the payment record Request".to_string(),
|
||||
})?;
|
||||
|
||||
let merchant_context_from_revenue_recovery_payment_data =
|
||||
MerchantContext::NormalMerchant(Box::new(Context(
|
||||
|
||||
@ -545,14 +545,17 @@ impl RevenueRecoveryAttempt {
|
||||
errors::RevenueRecoveryError,
|
||||
> {
|
||||
let payment_connector_id = payment_connector_account.as_ref().map(|account: &hyperswitch_domain_models::merchant_connector_account::MerchantConnectorAccount| account.id.clone());
|
||||
let request_payload = self.create_payment_record_request(
|
||||
billing_connector_account_id,
|
||||
payment_connector_id,
|
||||
payment_connector_account
|
||||
.as_ref()
|
||||
.map(|account| account.connector_name),
|
||||
common_enums::TriggeredBy::External,
|
||||
);
|
||||
let request_payload = self
|
||||
.create_payment_record_request(
|
||||
state,
|
||||
billing_connector_account_id,
|
||||
payment_connector_id,
|
||||
payment_connector_account
|
||||
.as_ref()
|
||||
.map(|account| account.connector_name),
|
||||
common_enums::TriggeredBy::External,
|
||||
)
|
||||
.await?;
|
||||
let attempt_response = Box::pin(payments::record_attempt_core(
|
||||
state.clone(),
|
||||
req_state.clone(),
|
||||
@ -593,13 +596,15 @@ impl RevenueRecoveryAttempt {
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
pub fn create_payment_record_request(
|
||||
pub async fn create_payment_record_request(
|
||||
&self,
|
||||
state: &SessionState,
|
||||
billing_merchant_connector_account_id: &id_type::MerchantConnectorAccountId,
|
||||
payment_merchant_connector_account_id: Option<id_type::MerchantConnectorAccountId>,
|
||||
payment_connector: Option<common_enums::connector_enums::Connector>,
|
||||
triggered_by: common_enums::TriggeredBy,
|
||||
) -> api_payments::PaymentsAttemptRecordRequest {
|
||||
) -> CustomResult<api_payments::PaymentsAttemptRecordRequest, errors::RevenueRecoveryError>
|
||||
{
|
||||
let revenue_recovery_attempt_data = &self.0;
|
||||
let amount_details =
|
||||
api_payments::PaymentAttemptAmountDetails::from(revenue_recovery_attempt_data);
|
||||
@ -609,9 +614,27 @@ impl RevenueRecoveryAttempt {
|
||||
attempt_triggered_by: triggered_by,
|
||||
}),
|
||||
};
|
||||
|
||||
let card_info = revenue_recovery_attempt_data
|
||||
.card_isin
|
||||
.clone()
|
||||
.async_and_then(|isin| async move {
|
||||
let issuer_identifier_number = isin.clone();
|
||||
state
|
||||
.store
|
||||
.get_card_info(issuer_identifier_number.as_str())
|
||||
.await
|
||||
.map_err(|error| services::logger::warn!(card_info_error=?error))
|
||||
.ok()
|
||||
})
|
||||
.await
|
||||
.flatten();
|
||||
|
||||
let card_issuer = card_info.and_then(|info| info.card_issuer);
|
||||
|
||||
let error =
|
||||
Option::<api_payments::RecordAttemptErrorDetails>::from(revenue_recovery_attempt_data);
|
||||
api_payments::PaymentsAttemptRecordRequest {
|
||||
Ok(api_payments::PaymentsAttemptRecordRequest {
|
||||
amount_details,
|
||||
status: revenue_recovery_attempt_data.status,
|
||||
billing: None,
|
||||
@ -637,7 +660,9 @@ impl RevenueRecoveryAttempt {
|
||||
retry_count: revenue_recovery_attempt_data.retry_count,
|
||||
invoice_next_billing_time: revenue_recovery_attempt_data.invoice_next_billing_time,
|
||||
triggered_by,
|
||||
}
|
||||
card_network: revenue_recovery_attempt_data.card_network.clone(),
|
||||
card_issuer,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn find_payment_merchant_connector_account(
|
||||
|
||||
Reference in New Issue
Block a user