From 0d3dd0033c5ec9eabc967cb1872f0699546aba89 Mon Sep 17 00:00:00 2001 From: Sai Harsha Vardhan <56996463+sai-harsha-vardhan@users.noreply.github.com> Date: Wed, 27 Sep 2023 12:48:28 +0530 Subject: [PATCH] fix(router): allow address updates in payments update flow (#2375) --- crates/router/src/core/payments/helpers.rs | 133 ++++++++++++++++++ .../payments/operations/payment_update.rs | 4 +- 2 files changed, 135 insertions(+), 2 deletions(-) diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index 21050dcedaa0..dbde763b5281 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -103,6 +103,139 @@ pub fn filter_mca_based_on_business_profile( } } +#[instrument(skip_all)] +#[allow(clippy::too_many_arguments)] +pub async fn create_or_update_address_for_payment_by_request( + db: &dyn StorageInterface, + req_address: Option<&api::Address>, + address_id: Option<&str>, + merchant_id: &str, + customer_id: Option<&String>, + merchant_key_store: &domain::MerchantKeyStore, + payment_id: &str, + storage_scheme: storage_enums::MerchantStorageScheme, +) -> CustomResult, errors::ApiErrorResponse> { + let key = merchant_key_store.key.get_inner().peek(); + + Ok(match address_id { + Some(id) => match req_address { + Some(address) => { + let address_update = async { + Ok(storage::AddressUpdate::Update { + city: address + .address + .as_ref() + .and_then(|value| value.city.clone()), + country: address.address.as_ref().and_then(|value| value.country), + line1: address + .address + .as_ref() + .and_then(|value| value.line1.clone()) + .async_lift(|inner| types::encrypt_optional(inner, key)) + .await?, + line2: address + .address + .as_ref() + .and_then(|value| value.line2.clone()) + .async_lift(|inner| types::encrypt_optional(inner, key)) + .await?, + line3: address + .address + .as_ref() + .and_then(|value| value.line3.clone()) + .async_lift(|inner| types::encrypt_optional(inner, key)) + .await?, + state: address + .address + .as_ref() + .and_then(|value| value.state.clone()) + .async_lift(|inner| types::encrypt_optional(inner, key)) + .await?, + zip: address + .address + .as_ref() + .and_then(|value| value.zip.clone()) + .async_lift(|inner| types::encrypt_optional(inner, key)) + .await?, + first_name: address + .address + .as_ref() + .and_then(|value| value.first_name.clone()) + .async_lift(|inner| types::encrypt_optional(inner, key)) + .await?, + last_name: address + .address + .as_ref() + .and_then(|value| value.last_name.clone()) + .async_lift(|inner| types::encrypt_optional(inner, key)) + .await?, + phone_number: address + .phone + .as_ref() + .and_then(|value| value.number.clone()) + .async_lift(|inner| types::encrypt_optional(inner, key)) + .await?, + country_code: address + .phone + .as_ref() + .and_then(|value| value.country_code.clone()), + }) + } + .await + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Failed while encrypting address")?; + Some( + db.update_address(id.to_owned(), address_update, merchant_key_store) + .await + .to_not_found_response(errors::ApiErrorResponse::AddressNotFound)?, + ) + } + None => Some( + db.find_address_by_merchant_id_payment_id_address_id( + merchant_id, + payment_id, + id, + merchant_key_store, + storage_scheme, + ) + .await, + ) + .transpose() + .to_not_found_response(errors::ApiErrorResponse::AddressNotFound)?, + }, + None => match req_address { + Some(address) => { + // generate a new address here + let customer_id = customer_id.get_required_value("customer_id")?; + + let address_details = address.address.clone().unwrap_or_default(); + Some( + db.insert_address_for_payments( + payment_id, + get_domain_address_for_payments( + address_details, + address, + merchant_id, + customer_id, + payment_id, + key, + ) + .await + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Failed while encrypting address while insert")?, + merchant_key_store, + storage_scheme, + ) + .await + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Failed while inserting new address")?, + ) + } + None => None, + }, + }) +} + #[instrument(skip_all)] #[allow(clippy::too_many_arguments)] pub async fn create_or_find_address_for_payment_by_request( diff --git a/crates/router/src/core/payments/operations/payment_update.rs b/crates/router/src/core/payments/operations/payment_update.rs index 800abd2cb039..04f36d51c2c8 100644 --- a/crates/router/src/core/payments/operations/payment_update.rs +++ b/crates/router/src/core/payments/operations/payment_update.rs @@ -146,7 +146,7 @@ impl GetTracker, api::PaymentsRequest> for Pa )?; } - let shipping_address = helpers::create_or_find_address_for_payment_by_request( + let shipping_address = helpers::create_or_update_address_for_payment_by_request( db, request.shipping.as_ref(), payment_intent.shipping_address_id.as_deref(), @@ -160,7 +160,7 @@ impl GetTracker, api::PaymentsRequest> for Pa merchant_account.storage_scheme, ) .await?; - let billing_address = helpers::create_or_find_address_for_payment_by_request( + let billing_address = helpers::create_or_update_address_for_payment_by_request( db, request.billing.as_ref(), payment_intent.billing_address_id.as_deref(),