mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-01 11:06:50 +08:00
feat(core): billing_details inclusion in Payment Intent (#5090)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@ -151,7 +151,7 @@ impl TryFrom<&RapydRouterData<&types::PaymentsAuthorizeRouterData>> for RapydPay
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
.get_required_value("payment_method not implemnted")
|
||||
.get_required_value("payment_method not implemented")
|
||||
.change_context(errors::ConnectorError::NotImplemented(
|
||||
"payment_method".to_owned(),
|
||||
))?;
|
||||
|
||||
@ -341,7 +341,7 @@ impl<Flow, Request, Response> RouterData for types::RouterData<Flow, Request, Re
|
||||
billing_address
|
||||
.clone()
|
||||
.address
|
||||
.and_then(|billing_address_details| billing_address_details.first_name.clone())
|
||||
.and_then(|billing_details| billing_details.first_name.clone())
|
||||
})
|
||||
.ok_or_else(missing_field_err(
|
||||
"payment_method_data.billing.address.first_name",
|
||||
@ -364,7 +364,7 @@ impl<Flow, Request, Response> RouterData for types::RouterData<Flow, Request, Re
|
||||
billing_address
|
||||
.clone()
|
||||
.address
|
||||
.and_then(|billing_address_details| billing_address_details.last_name.clone())
|
||||
.and_then(|billing_details| billing_details.last_name.clone())
|
||||
})
|
||||
.ok_or_else(missing_field_err(
|
||||
"payment_method_data.billing.address.last_name",
|
||||
@ -378,7 +378,7 @@ impl<Flow, Request, Response> RouterData for types::RouterData<Flow, Request, Re
|
||||
billing_address
|
||||
.clone()
|
||||
.address
|
||||
.and_then(|billing_address_details| billing_address_details.line1.clone())
|
||||
.and_then(|billing_details| billing_details.line1.clone())
|
||||
})
|
||||
.ok_or_else(missing_field_err(
|
||||
"payment_method_data.billing.address.line1",
|
||||
@ -391,7 +391,7 @@ impl<Flow, Request, Response> RouterData for types::RouterData<Flow, Request, Re
|
||||
billing_address
|
||||
.clone()
|
||||
.address
|
||||
.and_then(|billing_address_details| billing_address_details.city)
|
||||
.and_then(|billing_details| billing_details.city)
|
||||
})
|
||||
.ok_or_else(missing_field_err(
|
||||
"payment_method_data.billing.address.city",
|
||||
@ -421,7 +421,7 @@ impl<Flow, Request, Response> RouterData for types::RouterData<Flow, Request, Re
|
||||
billing_address
|
||||
.clone()
|
||||
.address
|
||||
.and_then(|billing_address_details| billing_address_details.line1)
|
||||
.and_then(|billing_details| billing_details.line1)
|
||||
})
|
||||
}
|
||||
|
||||
@ -432,7 +432,7 @@ impl<Flow, Request, Response> RouterData for types::RouterData<Flow, Request, Re
|
||||
billing_address
|
||||
.clone()
|
||||
.address
|
||||
.and_then(|billing_address_details| billing_address_details.line2)
|
||||
.and_then(|billing_details| billing_details.line2)
|
||||
})
|
||||
}
|
||||
|
||||
@ -443,7 +443,7 @@ impl<Flow, Request, Response> RouterData for types::RouterData<Flow, Request, Re
|
||||
billing_address
|
||||
.clone()
|
||||
.address
|
||||
.and_then(|billing_address_details| billing_address_details.city)
|
||||
.and_then(|billing_details| billing_details.city)
|
||||
})
|
||||
}
|
||||
|
||||
@ -454,7 +454,7 @@ impl<Flow, Request, Response> RouterData for types::RouterData<Flow, Request, Re
|
||||
billing_address
|
||||
.clone()
|
||||
.address
|
||||
.and_then(|billing_address_details| billing_address_details.country)
|
||||
.and_then(|billing_details| billing_details.country)
|
||||
})
|
||||
}
|
||||
|
||||
@ -465,7 +465,7 @@ impl<Flow, Request, Response> RouterData for types::RouterData<Flow, Request, Re
|
||||
billing_address
|
||||
.clone()
|
||||
.address
|
||||
.and_then(|billing_address_details| billing_address_details.zip)
|
||||
.and_then(|billing_details| billing_details.zip)
|
||||
})
|
||||
}
|
||||
|
||||
@ -476,7 +476,7 @@ impl<Flow, Request, Response> RouterData for types::RouterData<Flow, Request, Re
|
||||
billing_address
|
||||
.clone()
|
||||
.address
|
||||
.and_then(|billing_address_details| billing_address_details.state)
|
||||
.and_then(|billing_details| billing_details.state)
|
||||
})
|
||||
}
|
||||
|
||||
@ -487,7 +487,7 @@ impl<Flow, Request, Response> RouterData for types::RouterData<Flow, Request, Re
|
||||
billing_address
|
||||
.clone()
|
||||
.address
|
||||
.and_then(|billing_address_details| billing_address_details.first_name)
|
||||
.and_then(|billing_details| billing_details.first_name)
|
||||
})
|
||||
}
|
||||
|
||||
@ -498,7 +498,7 @@ impl<Flow, Request, Response> RouterData for types::RouterData<Flow, Request, Re
|
||||
billing_address
|
||||
.clone()
|
||||
.address
|
||||
.and_then(|billing_address_details| billing_address_details.last_name)
|
||||
.and_then(|billing_details| billing_details.last_name)
|
||||
})
|
||||
}
|
||||
|
||||
@ -615,7 +615,7 @@ impl AddressData for api::Address {
|
||||
fn get_optional_country(&self) -> Option<enums::CountryAlpha2> {
|
||||
self.address
|
||||
.as_ref()
|
||||
.and_then(|billing_address_details| billing_address_details.country)
|
||||
.and_then(|billing_details| billing_details.country)
|
||||
}
|
||||
|
||||
fn get_optional_full_name(&self) -> Option<Secret<String>> {
|
||||
|
||||
@ -3151,6 +3151,7 @@ mod tests {
|
||||
charges: None,
|
||||
frm_metadata: None,
|
||||
customer_details: None,
|
||||
billing_details: None,
|
||||
merchant_order_reference_id: None,
|
||||
};
|
||||
let req_cs = Some("1".to_string());
|
||||
@ -3212,6 +3213,7 @@ mod tests {
|
||||
charges: None,
|
||||
frm_metadata: None,
|
||||
customer_details: None,
|
||||
billing_details: None,
|
||||
merchant_order_reference_id: None,
|
||||
};
|
||||
let req_cs = Some("1".to_string());
|
||||
@ -3272,6 +3274,7 @@ mod tests {
|
||||
charges: None,
|
||||
frm_metadata: None,
|
||||
customer_details: None,
|
||||
billing_details: None,
|
||||
merchant_order_reference_id: None,
|
||||
};
|
||||
let req_cs = Some("1".to_string());
|
||||
|
||||
@ -22,6 +22,7 @@ use crate::{
|
||||
blocklist::utils as blocklist_utils,
|
||||
errors::{self, CustomResult, RouterResult, StorageErrorExt},
|
||||
mandate::helpers as m_helpers,
|
||||
payment_methods::cards::create_encrypted_data,
|
||||
payments::{
|
||||
self, helpers, operations, populate_surcharge_details, CustomerDetails, PaymentAddress,
|
||||
PaymentData,
|
||||
@ -1218,6 +1219,10 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
|
||||
.in_current_span(),
|
||||
);
|
||||
|
||||
let billing_address = payment_data.address.get_payment_billing();
|
||||
let billing_details = billing_address
|
||||
.async_and_then(|_| async { create_encrypted_data(key_store, billing_address).await })
|
||||
.await;
|
||||
let m_payment_data_payment_intent = payment_data.payment_intent.clone();
|
||||
let m_customer_id = customer_id.clone();
|
||||
let m_shipping_address_id = shipping_address_id.clone();
|
||||
@ -1263,6 +1268,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
|
||||
frm_metadata: m_frm_metadata,
|
||||
customer_details,
|
||||
merchant_order_reference_id: None,
|
||||
billing_details,
|
||||
},
|
||||
&m_key_store,
|
||||
storage_scheme,
|
||||
|
||||
@ -1045,6 +1045,16 @@ impl PaymentCreate {
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?
|
||||
.map(Secret::new);
|
||||
|
||||
// Derivation of directly supplied Billing Address data in our Payment Create Request
|
||||
// Encrypting our Billing Address Details to be stored in Payment Intent
|
||||
let billing_details = request
|
||||
.billing
|
||||
.clone()
|
||||
.async_and_then(|_| async {
|
||||
create_encrypted_data(key_store, request.billing.clone()).await
|
||||
})
|
||||
.await;
|
||||
|
||||
// Derivation of directly supplied Customer data in our Payment Create Request
|
||||
let raw_customer_details = if request.customer_id.is_none()
|
||||
&& (request.name.is_some()
|
||||
@ -1116,6 +1126,7 @@ impl PaymentCreate {
|
||||
.request_external_three_ds_authentication,
|
||||
charges,
|
||||
frm_metadata: request.frm_metadata.clone(),
|
||||
billing_details,
|
||||
customer_details,
|
||||
merchant_order_reference_id: request.merchant_order_reference_id.clone(),
|
||||
})
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use api_models::{
|
||||
enums::FrmSuggestion, mandates::RecurringDetails, payments::RequestSurchargeDetails,
|
||||
enums::FrmSuggestion,
|
||||
mandates::RecurringDetails,
|
||||
payments::{Address, RequestSurchargeDetails},
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use common_utils::{
|
||||
@ -18,6 +20,7 @@ use crate::{
|
||||
core::{
|
||||
errors::{self, CustomResult, RouterResult, StorageErrorExt},
|
||||
mandate::helpers as m_helpers,
|
||||
payment_methods::cards::create_encrypted_data,
|
||||
payments::{self, helpers, operations, CustomerDetails, PaymentAddress, PaymentData},
|
||||
utils as core_utils,
|
||||
},
|
||||
@ -218,6 +221,14 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
||||
)
|
||||
.await?;
|
||||
|
||||
let billing_details: Option<Address> = billing_address.as_ref().map(From::from);
|
||||
payment_intent.billing_details = billing_details
|
||||
.clone()
|
||||
.async_and_then(|_| async {
|
||||
create_encrypted_data(key_store, billing_details.clone()).await
|
||||
})
|
||||
.await;
|
||||
|
||||
let payment_method_billing = helpers::create_or_update_address_for_payment_by_request(
|
||||
db,
|
||||
request
|
||||
@ -438,7 +449,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
||||
customer_acceptance,
|
||||
address: PaymentAddress::new(
|
||||
shipping_address.as_ref().map(From::from),
|
||||
billing_address.as_ref().map(From::from),
|
||||
billing_details,
|
||||
payment_method_billing.as_ref().map(From::from),
|
||||
business_profile.use_billing_as_payment_method_billing,
|
||||
),
|
||||
@ -716,7 +727,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
|
||||
.payment_intent
|
||||
.merchant_order_reference_id
|
||||
.clone();
|
||||
|
||||
let billing_details = payment_data.payment_intent.billing_details.clone();
|
||||
payment_data.payment_intent = state
|
||||
.store
|
||||
.update_payment_intent(
|
||||
@ -747,6 +758,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
|
||||
frm_metadata,
|
||||
customer_details,
|
||||
merchant_order_reference_id,
|
||||
billing_details,
|
||||
},
|
||||
key_store,
|
||||
storage_scheme,
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use common_utils::{id_type, types::MinorUnit};
|
||||
use common_utils::{crypto::Encryptable, id_type, types::MinorUnit};
|
||||
use diesel_models::enums as storage_enums;
|
||||
use hyperswitch_domain_models::payments::PaymentIntent;
|
||||
use masking::Secret;
|
||||
use time::OffsetDateTime;
|
||||
|
||||
#[derive(serde::Serialize, Debug)]
|
||||
@ -31,6 +32,7 @@ pub struct KafkaPaymentIntent<'a> {
|
||||
pub business_label: Option<&'a String>,
|
||||
pub attempt_count: i16,
|
||||
pub payment_confirm_source: Option<storage_enums::PaymentSource>,
|
||||
pub billing_details: Option<Encryptable<Secret<serde_json::Value>>>,
|
||||
}
|
||||
|
||||
impl<'a> KafkaPaymentIntent<'a> {
|
||||
@ -59,6 +61,7 @@ impl<'a> KafkaPaymentIntent<'a> {
|
||||
business_label: intent.business_label.as_ref(),
|
||||
attempt_count: intent.attempt_count,
|
||||
payment_confirm_source: intent.payment_confirm_source,
|
||||
billing_details: intent.billing_details.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use common_utils::{id_type, types::MinorUnit};
|
||||
use common_utils::{crypto::Encryptable, id_type, types::MinorUnit};
|
||||
use diesel_models::enums as storage_enums;
|
||||
use hyperswitch_domain_models::payments::PaymentIntent;
|
||||
use masking::Secret;
|
||||
use time::OffsetDateTime;
|
||||
|
||||
#[serde_with::skip_serializing_none]
|
||||
@ -32,6 +33,7 @@ pub struct KafkaPaymentIntentEvent<'a> {
|
||||
pub business_label: Option<&'a String>,
|
||||
pub attempt_count: i16,
|
||||
pub payment_confirm_source: Option<storage_enums::PaymentSource>,
|
||||
pub billing_details: Option<Encryptable<Secret<serde_json::Value>>>,
|
||||
}
|
||||
|
||||
impl<'a> KafkaPaymentIntentEvent<'a> {
|
||||
@ -60,6 +62,7 @@ impl<'a> KafkaPaymentIntentEvent<'a> {
|
||||
business_label: intent.business_label.as_ref(),
|
||||
attempt_count: intent.attempt_count,
|
||||
payment_confirm_source: intent.payment_confirm_source,
|
||||
billing_details: intent.billing_details.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,6 +226,7 @@ pub async fn generate_sample_data(
|
||||
charges: None,
|
||||
frm_metadata: Default::default(),
|
||||
customer_details: None,
|
||||
billing_details: None,
|
||||
merchant_order_reference_id: Default::default(),
|
||||
};
|
||||
let payment_attempt = PaymentAttemptBatchNew {
|
||||
|
||||
Reference in New Issue
Block a user