mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-28 04:04:55 +08:00
feat(router): use payment confirm for confirmed payments in payments create and update (#165)
Co-authored-by: Arun Raj M <jarnura47@gmail.com>
This commit is contained in:
@ -482,6 +482,7 @@ pub struct CustomerDetails {
|
|||||||
pub fn if_not_create_change_operation<'a, Op, F>(
|
pub fn if_not_create_change_operation<'a, Op, F>(
|
||||||
is_update: bool,
|
is_update: bool,
|
||||||
status: storage_enums::IntentStatus,
|
status: storage_enums::IntentStatus,
|
||||||
|
confirm: Option<bool>,
|
||||||
current: &'a Op,
|
current: &'a Op,
|
||||||
) -> BoxedOperation<F, api::PaymentsRequest>
|
) -> BoxedOperation<F, api::PaymentsRequest>
|
||||||
where
|
where
|
||||||
@ -489,6 +490,9 @@ where
|
|||||||
Op: Operation<F, api::PaymentsRequest> + Send + Sync,
|
Op: Operation<F, api::PaymentsRequest> + Send + Sync,
|
||||||
&'a Op: Operation<F, api::PaymentsRequest>,
|
&'a Op: Operation<F, api::PaymentsRequest>,
|
||||||
{
|
{
|
||||||
|
if confirm.unwrap_or(false) {
|
||||||
|
Box::new(PaymentConfirm)
|
||||||
|
} else {
|
||||||
match status {
|
match status {
|
||||||
storage_enums::IntentStatus::RequiresConfirmation
|
storage_enums::IntentStatus::RequiresConfirmation
|
||||||
| storage_enums::IntentStatus::RequiresCustomerAction
|
| storage_enums::IntentStatus::RequiresCustomerAction
|
||||||
@ -502,6 +506,7 @@ where
|
|||||||
_ => Box::new(&PaymentStatus),
|
_ => Box::new(&PaymentStatus),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_confirm<'a, F: Clone + Send, R, Op>(
|
pub fn is_confirm<'a, F: Clone + Send, R, Op>(
|
||||||
operation: &'a Op,
|
operation: &'a Op,
|
||||||
|
|||||||
@ -257,7 +257,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
|
|||||||
db: &dyn StorageInterface,
|
db: &dyn StorageInterface,
|
||||||
_payment_id: &api::PaymentIdType,
|
_payment_id: &api::PaymentIdType,
|
||||||
mut payment_data: PaymentData<F>,
|
mut payment_data: PaymentData<F>,
|
||||||
_customer: Option<storage::Customer>,
|
customer: Option<storage::Customer>,
|
||||||
storage_scheme: enums::MerchantStorageScheme,
|
storage_scheme: enums::MerchantStorageScheme,
|
||||||
) -> RouterResult<(BoxedOperation<'b, F, api::PaymentsRequest>, PaymentData<F>)>
|
) -> RouterResult<(BoxedOperation<'b, F, api::PaymentsRequest>, PaymentData<F>)>
|
||||||
where
|
where
|
||||||
@ -285,8 +285,11 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
|
|||||||
.update_payment_attempt(
|
.update_payment_attempt(
|
||||||
payment_data.payment_attempt,
|
payment_data.payment_attempt,
|
||||||
storage::PaymentAttemptUpdate::ConfirmUpdate {
|
storage::PaymentAttemptUpdate::ConfirmUpdate {
|
||||||
|
amount: payment_data.amount.into(),
|
||||||
|
currency: payment_data.currency,
|
||||||
status: attempt_status,
|
status: attempt_status,
|
||||||
payment_method,
|
payment_method,
|
||||||
|
authentication_type: None,
|
||||||
browser_info,
|
browser_info,
|
||||||
connector,
|
connector,
|
||||||
payment_token,
|
payment_token,
|
||||||
@ -303,11 +306,16 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
|
|||||||
payment_data.payment_intent.billing_address_id.clone(),
|
payment_data.payment_intent.billing_address_id.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let customer_id = customer.map(|c| c.customer_id);
|
||||||
|
|
||||||
payment_data.payment_intent = db
|
payment_data.payment_intent = db
|
||||||
.update_payment_intent(
|
.update_payment_intent(
|
||||||
payment_data.payment_intent,
|
payment_data.payment_intent,
|
||||||
storage::PaymentIntentUpdate::MerchantStatusUpdate {
|
storage::PaymentIntentUpdate::Update {
|
||||||
|
amount: payment_data.amount.into(),
|
||||||
|
currency: payment_data.currency,
|
||||||
status: intent_status,
|
status: intent_status,
|
||||||
|
customer_id,
|
||||||
shipping_address_id: shipping_address,
|
shipping_address_id: shipping_address,
|
||||||
billing_address_id: billing_address,
|
billing_address_id: billing_address,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -185,6 +185,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
|||||||
let operation = payments::if_not_create_change_operation::<_, F>(
|
let operation = payments::if_not_create_change_operation::<_, F>(
|
||||||
is_update,
|
is_update,
|
||||||
payment_intent.status,
|
payment_intent.status,
|
||||||
|
request.confirm,
|
||||||
self,
|
self,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -280,10 +281,10 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentCreate {
|
|||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
async fn add_task_to_process_tracker<'a>(
|
async fn add_task_to_process_tracker<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
state: &'a AppState,
|
_state: &'a AppState,
|
||||||
payment_attempt: &storage::PaymentAttempt,
|
_payment_attempt: &storage::PaymentAttempt,
|
||||||
) -> CustomResult<(), errors::ApiErrorResponse> {
|
) -> CustomResult<(), errors::ApiErrorResponse> {
|
||||||
helpers::add_domain_task_to_pt(self, state, payment_attempt).await
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_connector<'a>(
|
async fn get_connector<'a>(
|
||||||
@ -388,6 +389,13 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsRequest> for PaymentCreate
|
|||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if let Some(true) = request.confirm {
|
||||||
|
helpers::validate_pm_or_token_given(
|
||||||
|
&request.payment_token,
|
||||||
|
&request.payment_method_data,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
let request_merchant_id = request.merchant_id.as_deref();
|
let request_merchant_id = request.merchant_id.as_deref();
|
||||||
helpers::validate_merchant_id(&merchant_account.merchant_id, request_merchant_id)
|
helpers::validate_merchant_id(&merchant_account.merchant_id, request_merchant_id)
|
||||||
.change_context(errors::ApiErrorResponse::MerchantAccountNotFound)?;
|
.change_context(errors::ApiErrorResponse::MerchantAccountNotFound)?;
|
||||||
|
|||||||
@ -126,6 +126,13 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
|||||||
.attach_printable("Database error when finding connector response")
|
.attach_printable("Database error when finding connector response")
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
let next_operation: BoxedOperation<'a, F, api::PaymentsRequest> =
|
||||||
|
if request.confirm.unwrap_or(false) {
|
||||||
|
Box::new(operations::PaymentConfirm)
|
||||||
|
} else {
|
||||||
|
Box::new(self)
|
||||||
|
};
|
||||||
|
|
||||||
match payment_intent.status {
|
match payment_intent.status {
|
||||||
enums::IntentStatus::Succeeded | enums::IntentStatus::Failed => {
|
enums::IntentStatus::Succeeded | enums::IntentStatus::Failed => {
|
||||||
Err(report!(errors::ApiErrorResponse::PreconditionFailed {
|
Err(report!(errors::ApiErrorResponse::PreconditionFailed {
|
||||||
@ -135,7 +142,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
_ => Ok((
|
_ => Ok((
|
||||||
Box::new(self),
|
next_operation,
|
||||||
PaymentData {
|
PaymentData {
|
||||||
flow: PhantomData,
|
flow: PhantomData,
|
||||||
payment_intent,
|
payment_intent,
|
||||||
@ -227,10 +234,10 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentUpdate {
|
|||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
async fn add_task_to_process_tracker<'a>(
|
async fn add_task_to_process_tracker<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
state: &'a AppState,
|
_state: &'a AppState,
|
||||||
payment_attempt: &storage::PaymentAttempt,
|
_payment_attempt: &storage::PaymentAttempt,
|
||||||
) -> CustomResult<(), errors::ApiErrorResponse> {
|
) -> CustomResult<(), errors::ApiErrorResponse> {
|
||||||
helpers::add_domain_task_to_pt(self, state, payment_attempt).await
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_connector<'a>(
|
async fn get_connector<'a>(
|
||||||
@ -352,6 +359,13 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsRequest> for PaymentUpdate
|
|||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if let Some(true) = request.confirm {
|
||||||
|
helpers::validate_pm_or_token_given(
|
||||||
|
&request.payment_token,
|
||||||
|
&request.payment_method_data,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
let request_merchant_id = request.merchant_id.as_deref();
|
let request_merchant_id = request.merchant_id.as_deref();
|
||||||
helpers::validate_merchant_id(&merchant_account.merchant_id, request_merchant_id)
|
helpers::validate_merchant_id(&merchant_account.merchant_id, request_merchant_id)
|
||||||
.change_context(errors::ApiErrorResponse::InvalidDataFormat {
|
.change_context(errors::ApiErrorResponse::InvalidDataFormat {
|
||||||
|
|||||||
@ -95,7 +95,10 @@ pub enum PaymentAttemptUpdate {
|
|||||||
authentication_type: storage_enums::AuthenticationType,
|
authentication_type: storage_enums::AuthenticationType,
|
||||||
},
|
},
|
||||||
ConfirmUpdate {
|
ConfirmUpdate {
|
||||||
|
amount: i64,
|
||||||
|
currency: storage_enums::Currency,
|
||||||
status: storage_enums::AttemptStatus,
|
status: storage_enums::AttemptStatus,
|
||||||
|
authentication_type: Option<storage_enums::AuthenticationType>,
|
||||||
payment_method: Option<storage_enums::PaymentMethodType>,
|
payment_method: Option<storage_enums::PaymentMethodType>,
|
||||||
browser_info: Option<serde_json::Value>,
|
browser_info: Option<serde_json::Value>,
|
||||||
connector: Option<String>,
|
connector: Option<String>,
|
||||||
@ -199,12 +202,18 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
PaymentAttemptUpdate::ConfirmUpdate {
|
PaymentAttemptUpdate::ConfirmUpdate {
|
||||||
|
amount,
|
||||||
|
currency,
|
||||||
|
authentication_type,
|
||||||
status,
|
status,
|
||||||
payment_method,
|
payment_method,
|
||||||
browser_info,
|
browser_info,
|
||||||
connector,
|
connector,
|
||||||
payment_token,
|
payment_token,
|
||||||
} => Self {
|
} => Self {
|
||||||
|
amount: Some(amount),
|
||||||
|
currency: Some(currency),
|
||||||
|
authentication_type,
|
||||||
status: Some(status),
|
status: Some(status),
|
||||||
payment_method,
|
payment_method,
|
||||||
modified_at: Some(common_utils::date_time::now()),
|
modified_at: Some(common_utils::date_time::now()),
|
||||||
|
|||||||
Reference in New Issue
Block a user