mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-01 19:42:27 +08:00
refactor(customer_v2): fixed customer_v2 create panic issue (#5699)
This commit is contained in:
@ -142,7 +142,7 @@ impl DBOperation {
|
||||
Updateable::CustomerUpdate(cust) => DBResult::Customer(Box::new(
|
||||
Customer::update_by_customer_id_merchant_id(
|
||||
conn,
|
||||
cust.orig.get_customer_id().clone(),
|
||||
cust.orig.customer_id.clone(),
|
||||
cust.orig.merchant_id.clone(),
|
||||
cust.update_data,
|
||||
)
|
||||
|
||||
@ -61,20 +61,6 @@ pub struct Customer {
|
||||
pub version: common_enums::ApiVersion,
|
||||
}
|
||||
|
||||
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))]
|
||||
impl Customer {
|
||||
pub fn get_customer_id(&self) -> id_type::CustomerId {
|
||||
self.customer_id.clone()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "customer_v2"))]
|
||||
impl Customer {
|
||||
pub fn get_customer_id(&self) -> id_type::CustomerId {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))]
|
||||
#[async_trait::async_trait]
|
||||
impl super::behaviour::Conversion for Customer {
|
||||
|
||||
@ -29,6 +29,22 @@ use crate::{
|
||||
impl ConstructFlowSpecificData<frm_api::Checkout, FraudCheckCheckoutData, FraudCheckResponseData>
|
||||
for FrmData
|
||||
{
|
||||
#[cfg(all(feature = "v2", feature = "customer_v2"))]
|
||||
async fn construct_router_data<'a>(
|
||||
&self,
|
||||
_state: &SessionState,
|
||||
_connector_id: &str,
|
||||
_merchant_account: &domain::MerchantAccount,
|
||||
_key_store: &domain::MerchantKeyStore,
|
||||
_customer: &Option<domain::Customer>,
|
||||
_merchant_connector_account: &helpers::MerchantConnectorAccountType,
|
||||
_merchant_recipient_data: Option<MerchantRecipientData>,
|
||||
) -> RouterResult<RouterData<frm_api::Checkout, FraudCheckCheckoutData, FraudCheckResponseData>>
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))]
|
||||
async fn construct_router_data<'a>(
|
||||
&self,
|
||||
_state: &SessionState,
|
||||
@ -50,9 +66,7 @@ impl ConstructFlowSpecificData<frm_api::Checkout, FraudCheckCheckoutData, FraudC
|
||||
})?;
|
||||
|
||||
let browser_info: Option<BrowserInformation> = self.payment_attempt.get_browser_info().ok();
|
||||
let customer_id = customer
|
||||
.to_owned()
|
||||
.map(|customer| customer.get_customer_id());
|
||||
let customer_id = customer.to_owned().map(|customer| customer.customer_id);
|
||||
|
||||
let router_data = RouterData {
|
||||
flow: std::marker::PhantomData,
|
||||
|
||||
@ -26,6 +26,22 @@ use crate::{
|
||||
impl ConstructFlowSpecificData<RecordReturn, FraudCheckRecordReturnData, FraudCheckResponseData>
|
||||
for FrmData
|
||||
{
|
||||
#[cfg(all(feature = "v2", feature = "customer_v2"))]
|
||||
async fn construct_router_data<'a>(
|
||||
&self,
|
||||
_state: &SessionState,
|
||||
_connector_id: &str,
|
||||
_merchant_account: &domain::MerchantAccount,
|
||||
_key_store: &domain::MerchantKeyStore,
|
||||
_customer: &Option<domain::Customer>,
|
||||
_merchant_connector_account: &helpers::MerchantConnectorAccountType,
|
||||
_merchant_recipient_data: Option<MerchantRecipientData>,
|
||||
) -> RouterResult<RouterData<RecordReturn, FraudCheckRecordReturnData, FraudCheckResponseData>>
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))]
|
||||
async fn construct_router_data<'a>(
|
||||
&self,
|
||||
_state: &SessionState,
|
||||
@ -46,9 +62,7 @@ impl ConstructFlowSpecificData<RecordReturn, FraudCheckRecordReturnData, FraudCh
|
||||
id: "ConnectorAuthType".to_string(),
|
||||
})?;
|
||||
|
||||
let customer_id = customer
|
||||
.to_owned()
|
||||
.map(|customer| customer.get_customer_id());
|
||||
let customer_id = customer.to_owned().map(|customer| customer.customer_id);
|
||||
let currency = self.payment_attempt.clone().currency;
|
||||
let router_data = RouterData {
|
||||
flow: std::marker::PhantomData,
|
||||
|
||||
@ -24,6 +24,21 @@ use crate::{
|
||||
impl ConstructFlowSpecificData<frm_api::Sale, FraudCheckSaleData, FraudCheckResponseData>
|
||||
for FrmData
|
||||
{
|
||||
#[cfg(all(feature = "v2", feature = "customer_v2"))]
|
||||
async fn construct_router_data<'a>(
|
||||
&self,
|
||||
_state: &SessionState,
|
||||
_connector_id: &str,
|
||||
_merchant_account: &domain::MerchantAccount,
|
||||
_key_store: &domain::MerchantKeyStore,
|
||||
_customer: &Option<domain::Customer>,
|
||||
_merchant_connector_account: &helpers::MerchantConnectorAccountType,
|
||||
_merchant_recipient_data: Option<MerchantRecipientData>,
|
||||
) -> RouterResult<RouterData<frm_api::Sale, FraudCheckSaleData, FraudCheckResponseData>> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))]
|
||||
async fn construct_router_data<'a>(
|
||||
&self,
|
||||
_state: &SessionState,
|
||||
@ -43,9 +58,7 @@ impl ConstructFlowSpecificData<frm_api::Sale, FraudCheckSaleData, FraudCheckResp
|
||||
id: "ConnectorAuthType".to_string(),
|
||||
})?;
|
||||
|
||||
let customer_id = customer
|
||||
.to_owned()
|
||||
.map(|customer| customer.get_customer_id());
|
||||
let customer_id = customer.to_owned().map(|customer| customer.customer_id);
|
||||
|
||||
let router_data = RouterData {
|
||||
flow: std::marker::PhantomData,
|
||||
|
||||
@ -29,6 +29,23 @@ impl
|
||||
FraudCheckResponseData,
|
||||
> for FrmData
|
||||
{
|
||||
#[cfg(all(feature = "v2", feature = "customer_v2"))]
|
||||
async fn construct_router_data<'a>(
|
||||
&self,
|
||||
_state: &SessionState,
|
||||
_connector_id: &str,
|
||||
_merchant_account: &domain::MerchantAccount,
|
||||
_key_store: &domain::MerchantKeyStore,
|
||||
_customer: &Option<domain::Customer>,
|
||||
_merchant_connector_account: &helpers::MerchantConnectorAccountType,
|
||||
_merchant_recipient_data: Option<MerchantRecipientData>,
|
||||
) -> RouterResult<
|
||||
RouterData<frm_api::Transaction, FraudCheckTransactionData, FraudCheckResponseData>,
|
||||
> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))]
|
||||
async fn construct_router_data<'a>(
|
||||
&self,
|
||||
_state: &SessionState,
|
||||
@ -50,9 +67,7 @@ impl
|
||||
id: "ConnectorAuthType".to_string(),
|
||||
})?;
|
||||
|
||||
let customer_id = customer
|
||||
.to_owned()
|
||||
.map(|customer| customer.get_customer_id());
|
||||
let customer_id = customer.to_owned().map(|customer| customer.customer_id);
|
||||
|
||||
let payment_method = self.payment_attempt.payment_method;
|
||||
let currency = self.payment_attempt.currency;
|
||||
|
||||
@ -135,6 +135,22 @@ impl GetTracker<PaymentToFrmData> for FraudCheckPre {
|
||||
|
||||
#[async_trait]
|
||||
impl<F: Send + Clone> Domain<F> for FraudCheckPre {
|
||||
#[cfg(all(feature = "v2", feature = "customer_v2"))]
|
||||
#[instrument(skip_all)]
|
||||
async fn post_payment_frm<'a>(
|
||||
&'a self,
|
||||
_state: &'a SessionState,
|
||||
_req_state: ReqState,
|
||||
_payment_data: &mut payments::PaymentData<F>,
|
||||
_frm_data: &mut FrmData,
|
||||
_merchant_account: &domain::MerchantAccount,
|
||||
_customer: &Option<domain::Customer>,
|
||||
_key_store: domain::MerchantKeyStore,
|
||||
) -> RouterResult<Option<FrmRouterData>> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))]
|
||||
#[instrument(skip_all)]
|
||||
async fn post_payment_frm<'a>(
|
||||
&'a self,
|
||||
|
||||
@ -311,7 +311,7 @@ pub async fn render_pm_collect_link(
|
||||
publishable_key: masking::Secret::new(merchant_account.publishable_key),
|
||||
client_secret: link_data.client_secret.clone(),
|
||||
pm_collect_link_id: pm_collect_link.link_id,
|
||||
customer_id: customer.get_customer_id(),
|
||||
customer_id: customer.customer_id,
|
||||
session_expiry: pm_collect_link.expiry,
|
||||
return_url: pm_collect_link.return_url,
|
||||
ui_config: ui_config_data,
|
||||
|
||||
@ -2830,7 +2830,7 @@ pub async fn list_payment_methods(
|
||||
if wallet_pm_exists {
|
||||
match db
|
||||
.find_payment_method_by_customer_id_merchant_id_list(
|
||||
&customer.get_customer_id(),
|
||||
&customer.customer_id,
|
||||
merchant_account.get_id(),
|
||||
None,
|
||||
)
|
||||
@ -5353,7 +5353,7 @@ pub async fn set_default_payment_method(
|
||||
},
|
||||
)?;
|
||||
|
||||
let customer_id = customer.get_customer_id().clone();
|
||||
let customer_id = customer.customer_id.clone();
|
||||
|
||||
let customer_update = CustomerUpdate::UpdateDefaultPaymentMethod {
|
||||
default_payment_method_id: Some(Some(payment_method_id.to_owned())),
|
||||
|
||||
@ -27,6 +27,7 @@ use crate::{
|
||||
#[async_trait]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub trait ConstructFlowSpecificData<F, Req, Res> {
|
||||
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))]
|
||||
async fn construct_router_data<'a>(
|
||||
&self,
|
||||
state: &SessionState,
|
||||
@ -38,6 +39,18 @@ pub trait ConstructFlowSpecificData<F, Req, Res> {
|
||||
merchant_recipient_data: Option<types::MerchantRecipientData>,
|
||||
) -> RouterResult<types::RouterData<F, Req, Res>>;
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "customer_v2"))]
|
||||
async fn construct_router_data<'a>(
|
||||
&self,
|
||||
_state: &SessionState,
|
||||
_connector_id: &str,
|
||||
_merchant_account: &domain::MerchantAccount,
|
||||
_key_store: &domain::MerchantKeyStore,
|
||||
_customer: &Option<domain::Customer>,
|
||||
_merchant_connector_account: &helpers::MerchantConnectorAccountType,
|
||||
_merchant_recipient_data: Option<types::MerchantRecipientData>,
|
||||
) -> RouterResult<types::RouterData<F, Req, Res>>;
|
||||
|
||||
async fn get_merchant_recipient_data<'a>(
|
||||
&self,
|
||||
state: &SessionState,
|
||||
|
||||
@ -193,7 +193,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Co
|
||||
let customer_id = payment_intent
|
||||
.customer_id
|
||||
.as_ref()
|
||||
.or(request.get_customer_id())
|
||||
.or(request.customer_id.as_ref())
|
||||
.cloned();
|
||||
|
||||
helpers::validate_customer_id_mandatory_cases(
|
||||
|
||||
@ -1209,7 +1209,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
|
||||
.clone(),
|
||||
);
|
||||
|
||||
let customer_id = customer.clone().map(|c| c.get_customer_id());
|
||||
let customer_id = customer.clone().map(|c| c.customer_id);
|
||||
let return_url = payment_data.payment_intent.return_url.take();
|
||||
let setup_future_usage = payment_data.payment_intent.setup_future_usage;
|
||||
let business_label = payment_data.payment_intent.business_label.clone();
|
||||
@ -1414,7 +1414,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
|
||||
let key_manager_state = state.into();
|
||||
tokio::spawn(
|
||||
async move {
|
||||
let m_customer_customer_id = customer.get_customer_id().to_owned();
|
||||
let m_customer_customer_id = customer.customer_id.to_owned();
|
||||
m_db.update_customer_by_customer_id_merchant_id(
|
||||
&key_manager_state,
|
||||
m_customer_customer_id,
|
||||
|
||||
@ -839,7 +839,7 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsRequest> for PaymentCreate
|
||||
|
||||
helpers::validate_customer_id_mandatory_cases(
|
||||
request.setup_future_usage.is_some(),
|
||||
request.get_customer_id(),
|
||||
request.customer_id.as_ref(),
|
||||
)?;
|
||||
}
|
||||
|
||||
@ -1164,7 +1164,7 @@ impl PaymentCreate {
|
||||
.attach_printable("Unable to encrypt shipping details")?;
|
||||
|
||||
// Derivation of directly supplied Customer data in our Payment Create Request
|
||||
let raw_customer_details = if request.get_customer_id().is_none()
|
||||
let raw_customer_details = if request.customer_id.is_none()
|
||||
&& (request.name.is_some()
|
||||
|| request.email.is_some()
|
||||
|| request.phone.is_some()
|
||||
|
||||
@ -577,6 +577,27 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentUpdate {
|
||||
|
||||
#[async_trait]
|
||||
impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for PaymentUpdate {
|
||||
#[cfg(all(feature = "v2", feature = "customer_v2"))]
|
||||
#[instrument(skip_all)]
|
||||
async fn update_trackers<'b>(
|
||||
&'b self,
|
||||
_state: &'b SessionState,
|
||||
_req_state: ReqState,
|
||||
mut _payment_data: PaymentData<F>,
|
||||
_customer: Option<domain::Customer>,
|
||||
_storage_scheme: storage_enums::MerchantStorageScheme,
|
||||
_updated_customer: Option<storage::CustomerUpdate>,
|
||||
_key_store: &domain::MerchantKeyStore,
|
||||
_frm_suggestion: Option<FrmSuggestion>,
|
||||
_header_payload: api::HeaderPayload,
|
||||
) -> RouterResult<(BoxedOperation<'b, F, api::PaymentsRequest>, PaymentData<F>)>
|
||||
where
|
||||
F: 'b + Send,
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))]
|
||||
#[instrument(skip_all)]
|
||||
async fn update_trackers<'b>(
|
||||
&'b self,
|
||||
@ -676,7 +697,7 @@ impl<F: Clone> UpdateTracker<F, PaymentData<F>, api::PaymentsRequest> for Paymen
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
|
||||
|
||||
let customer_id = customer.clone().map(|c| c.get_customer_id());
|
||||
let customer_id = customer.clone().map(|c| c.customer_id);
|
||||
|
||||
let intent_status = {
|
||||
let current_intent_status = payment_data.payment_intent.status;
|
||||
|
||||
@ -36,6 +36,30 @@ use crate::{
|
||||
utils::{OptionExt, ValueExt},
|
||||
};
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "customer_v2"))]
|
||||
#[instrument(skip_all)]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn construct_payment_router_data<'a, F, T>(
|
||||
_state: &'a SessionState,
|
||||
_payment_data: PaymentData<F>,
|
||||
_connector_id: &str,
|
||||
_merchant_account: &domain::MerchantAccount,
|
||||
_key_store: &domain::MerchantKeyStore,
|
||||
_customer: &'a Option<domain::Customer>,
|
||||
_merchant_connector_account: &helpers::MerchantConnectorAccountType,
|
||||
_merchant_recipient_data: Option<types::MerchantRecipientData>,
|
||||
) -> RouterResult<types::RouterData<F, T, types::PaymentsResponseData>>
|
||||
where
|
||||
T: TryFrom<PaymentAdditionalData<'a, F>>,
|
||||
types::RouterData<F, T, types::PaymentsResponseData>: Feature<F, T>,
|
||||
F: Clone,
|
||||
error_stack::Report<errors::ApiErrorResponse>:
|
||||
From<<T as TryFrom<PaymentAdditionalData<'a, F>>>::Error>,
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))]
|
||||
#[instrument(skip_all)]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn construct_payment_router_data<'a, F, T>(
|
||||
@ -104,9 +128,7 @@ where
|
||||
customer_data: customer,
|
||||
};
|
||||
|
||||
let customer_id = customer
|
||||
.to_owned()
|
||||
.map(|customer| customer.get_customer_id());
|
||||
let customer_id = customer.to_owned().map(|customer| customer.customer_id);
|
||||
|
||||
let supported_connector = &state
|
||||
.conf
|
||||
@ -329,6 +351,23 @@ where
|
||||
F: Clone,
|
||||
Op: Debug,
|
||||
{
|
||||
#[cfg(all(feature = "v2", feature = "customer_v2"))]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn generate_response(
|
||||
_data: PaymentData<F>,
|
||||
_customer: Option<domain::Customer>,
|
||||
_auth_flow: services::AuthFlow,
|
||||
_base_url: &str,
|
||||
_operation: Op,
|
||||
_connector_request_reference_id_config: &ConnectorRequestReferenceIdConfig,
|
||||
_connector_http_status_code: Option<u16>,
|
||||
_external_latency: Option<u128>,
|
||||
_is_latency_header_enabled: Option<bool>,
|
||||
) -> RouterResponse<Self> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn generate_response(
|
||||
data: PaymentData<F>,
|
||||
@ -357,7 +396,7 @@ where
|
||||
verify_id: Some(data.payment_intent.payment_id),
|
||||
merchant_id: Some(data.payment_intent.merchant_id),
|
||||
client_secret: data.payment_intent.client_secret.map(Secret::new),
|
||||
customer_id: customer.as_ref().map(|x| x.get_customer_id().clone()),
|
||||
customer_id: customer.as_ref().map(|x| x.customer_id.clone()),
|
||||
email: customer
|
||||
.as_ref()
|
||||
.and_then(|cus| cus.email.as_ref().map(|s| s.to_owned())),
|
||||
@ -381,6 +420,30 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "customer_v2"))]
|
||||
#[instrument(skip_all)]
|
||||
// try to use router data here so that already validated things , we don't want to repeat the validations.
|
||||
// Add internal value not found and external value not found so that we can give 500 / Internal server error for internal value not found
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn payments_to_payments_response<Op, F: Clone>(
|
||||
_payment_data: PaymentData<F>,
|
||||
_captures: Option<Vec<storage::Capture>>,
|
||||
_customer: Option<domain::Customer>,
|
||||
_auth_flow: services::AuthFlow,
|
||||
_base_url: &str,
|
||||
_operation: &Op,
|
||||
_connector_request_reference_id_config: &ConnectorRequestReferenceIdConfig,
|
||||
_connector_http_status_code: Option<u16>,
|
||||
_external_latency: Option<u128>,
|
||||
_is_latency_header_enabled: Option<bool>,
|
||||
) -> RouterResponse<api::PaymentsResponse>
|
||||
where
|
||||
Op: Debug,
|
||||
{
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))]
|
||||
#[instrument(skip_all)]
|
||||
// try to use router data here so that already validated things , we don't want to repeat the validations.
|
||||
// Add internal value not found and external value not found so that we can give 500 / Internal server error for internal value not found
|
||||
@ -802,7 +865,7 @@ where
|
||||
client_secret: payment_intent.client_secret.map(Secret::new),
|
||||
created: Some(payment_intent.created_at),
|
||||
currency: currency.to_string(),
|
||||
customer_id: customer.as_ref().map(|cus| cus.clone().get_customer_id()),
|
||||
customer_id: customer.as_ref().map(|cus| cus.clone().customer_id),
|
||||
customer: customer_details_response,
|
||||
description: payment_intent.description,
|
||||
refunds: refunds_response,
|
||||
@ -1262,6 +1325,17 @@ where
|
||||
state: &'a SessionState,
|
||||
customer_data: &'a Option<domain::Customer>,
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "customer_v2"))]
|
||||
impl<F: Clone> TryFrom<PaymentAdditionalData<'_, F>> for types::PaymentsAuthorizeData {
|
||||
type Error = error_stack::Report<errors::ApiErrorResponse>;
|
||||
|
||||
fn try_from(_additional_data: PaymentAdditionalData<'_, F>) -> Result<Self, Self::Error> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))]
|
||||
impl<F: Clone> TryFrom<PaymentAdditionalData<'_, F>> for types::PaymentsAuthorizeData {
|
||||
type Error = error_stack::Report<errors::ApiErrorResponse>;
|
||||
|
||||
@ -1355,7 +1429,7 @@ impl<F: Clone> TryFrom<PaymentAdditionalData<'_, F>> for types::PaymentsAuthoriz
|
||||
let customer_id = additional_data
|
||||
.customer_data
|
||||
.as_ref()
|
||||
.map(|data| data.get_customer_id().clone());
|
||||
.map(|data| data.customer_id.clone());
|
||||
|
||||
let charges = match payment_data.payment_intent.charges {
|
||||
Some(charges) => charges
|
||||
|
||||
@ -193,7 +193,7 @@ pub async fn initiate_payout_link(
|
||||
client_secret: link_data.client_secret.clone(),
|
||||
payout_link_id: payout_link.link_id,
|
||||
payout_id: payout_link.primary_reference,
|
||||
customer_id: customer.get_customer_id(),
|
||||
customer_id: customer.customer_id,
|
||||
session_expiry: payout_link.expiry,
|
||||
return_url: payout_link
|
||||
.return_url
|
||||
|
||||
@ -1196,7 +1196,7 @@ pub async fn create_recipient(
|
||||
not(feature = "customer_v2")
|
||||
))]
|
||||
{
|
||||
let customer_id = customer.get_customer_id().to_owned();
|
||||
let customer_id = customer.customer_id.to_owned();
|
||||
payout_data.customer_details = Some(
|
||||
db.update_customer_by_customer_id_merchant_id(
|
||||
&state.into(),
|
||||
@ -2213,7 +2213,24 @@ pub async fn response_handler(
|
||||
Ok(services::ApplicationResponse::Json(response))
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "customer_v2"))]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn payout_create_db_entries(
|
||||
_state: &SessionState,
|
||||
_merchant_account: &domain::MerchantAccount,
|
||||
_key_store: &domain::MerchantKeyStore,
|
||||
_req: &payouts::PayoutCreateRequest,
|
||||
_payout_id: &String,
|
||||
_profile_id: &String,
|
||||
_stored_payout_method_data: Option<&payouts::PayoutMethodData>,
|
||||
_locale: &String,
|
||||
_customer: Option<&domain::Customer>,
|
||||
) -> RouterResult<PayoutData> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
// DB entries
|
||||
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn payout_create_db_entries(
|
||||
state: &SessionState,
|
||||
@ -2228,7 +2245,7 @@ pub async fn payout_create_db_entries(
|
||||
) -> RouterResult<PayoutData> {
|
||||
let db = &*state.store;
|
||||
let merchant_id = merchant_account.get_id();
|
||||
let customer_id = customer.map(|cust| cust.get_customer_id());
|
||||
let customer_id = customer.map(|cust| cust.customer_id.clone());
|
||||
|
||||
// Validate whether profile_id passed in request is valid and is linked to the merchant
|
||||
let business_profile =
|
||||
@ -2477,7 +2494,7 @@ pub async fn make_payout_data(
|
||||
Some(payout_token) => {
|
||||
let customer_id = customer_details
|
||||
.as_ref()
|
||||
.map(|cd| cd.get_customer_id().to_owned())
|
||||
.map(|cd| cd.customer_id.to_owned())
|
||||
.get_required_value("customer_id when payout_token is sent")?;
|
||||
helpers::make_payout_method_data(
|
||||
state,
|
||||
|
||||
@ -1043,6 +1043,18 @@ pub(super) async fn filter_by_constraints(
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "customer_v2"))]
|
||||
pub async fn update_payouts_and_payout_attempt(
|
||||
_payout_data: &mut PayoutData,
|
||||
_merchant_account: &domain::MerchantAccount,
|
||||
_req: &payouts::PayoutCreateRequest,
|
||||
_state: &SessionState,
|
||||
_merchant_key_store: &domain::MerchantKeyStore,
|
||||
) -> CustomResult<(), errors::ApiErrorResponse> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))]
|
||||
pub async fn update_payouts_and_payout_attempt(
|
||||
payout_data: &mut PayoutData,
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
@ -1077,7 +1089,7 @@ pub async fn update_payouts_and_payout_attempt(
|
||||
payout_data
|
||||
.customer_details
|
||||
.as_ref()
|
||||
.map(|customer| customer.get_customer_id())
|
||||
.map(|customer| customer.customer_id.clone())
|
||||
} else {
|
||||
payout_data.payouts.customer_id.clone()
|
||||
};
|
||||
|
||||
@ -1,8 +1,36 @@
|
||||
use crate::types::{
|
||||
api, domain, storage,
|
||||
transformers::{ForeignFrom, ForeignInto},
|
||||
};
|
||||
#[cfg(all(
|
||||
any(feature = "v1", feature = "v2"),
|
||||
not(feature = "customer_v2"),
|
||||
feature = "olap"
|
||||
))]
|
||||
use crate::types::transformers::ForeignInto;
|
||||
#[cfg(feature = "olap")]
|
||||
use crate::types::{api, domain, storage, transformers::ForeignFrom};
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "customer_v2", feature = "olap"))]
|
||||
impl
|
||||
ForeignFrom<(
|
||||
storage::Payouts,
|
||||
storage::PayoutAttempt,
|
||||
Option<domain::Customer>,
|
||||
)> for api::PayoutCreateResponse
|
||||
{
|
||||
fn foreign_from(
|
||||
item: (
|
||||
storage::Payouts,
|
||||
storage::PayoutAttempt,
|
||||
Option<domain::Customer>,
|
||||
),
|
||||
) -> Self {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
any(feature = "v1", feature = "v2"),
|
||||
not(feature = "customer_v2"),
|
||||
feature = "olap"
|
||||
))]
|
||||
impl
|
||||
ForeignFrom<(
|
||||
storage::Payouts,
|
||||
@ -42,7 +70,7 @@ impl
|
||||
connector: payout_attempt.connector,
|
||||
payout_type: payout.payout_type,
|
||||
auto_fulfill: payout.auto_fulfill,
|
||||
customer_id: customer.as_ref().map(|cust| cust.get_customer_id()),
|
||||
customer_id: customer.as_ref().map(|cust| cust.customer_id.clone()),
|
||||
customer: customer.as_ref().map(|cust| cust.foreign_into()),
|
||||
return_url: payout.return_url,
|
||||
business_country: payout_attempt.business_country,
|
||||
|
||||
@ -46,10 +46,26 @@ pub async fn validate_uniqueness_of_payout_id_against_merchant_id(
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "customer_v2"))]
|
||||
pub async fn validate_create_request(
|
||||
_state: &SessionState,
|
||||
_merchant_account: &domain::MerchantAccount,
|
||||
_req: &payouts::PayoutCreateRequest,
|
||||
_merchant_key_store: &domain::MerchantKeyStore,
|
||||
) -> RouterResult<(
|
||||
String,
|
||||
Option<payouts::PayoutMethodData>,
|
||||
String,
|
||||
Option<domain::Customer>,
|
||||
)> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// Validates the request on below checks
|
||||
/// - merchant_id passed is same as the one in merchant_account table
|
||||
/// - payout_id is unique against merchant_id
|
||||
/// - payout_token provided is legitimate
|
||||
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))]
|
||||
pub async fn validate_create_request(
|
||||
state: &SessionState,
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
@ -131,7 +147,7 @@ pub async fn validate_create_request(
|
||||
state,
|
||||
req.payout_method_data.as_ref(),
|
||||
Some(payout_token),
|
||||
&customer.get_customer_id(),
|
||||
&customer.customer_id,
|
||||
merchant_account.get_id(),
|
||||
req.payout_type,
|
||||
merchant_key_store,
|
||||
|
||||
@ -45,7 +45,21 @@ pub const IRRELEVANT_CONNECTOR_REQUEST_REFERENCE_ID_IN_PAYOUTS_FLOW: &str =
|
||||
const IRRELEVANT_PAYMENT_ID_IN_DISPUTE_FLOW: &str = "irrelevant_payment_id_in_dispute_flow";
|
||||
const IRRELEVANT_ATTEMPT_ID_IN_DISPUTE_FLOW: &str = "irrelevant_attempt_id_in_dispute_flow";
|
||||
|
||||
#[cfg(feature = "payouts")]
|
||||
#[cfg(all(feature = "payouts", feature = "v2", feature = "customer_v2"))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn construct_payout_router_data<'a, F>(
|
||||
_connector_data: &api::ConnectorData,
|
||||
_merchant_account: &domain::MerchantAccount,
|
||||
_payout_data: &mut PayoutData,
|
||||
) -> RouterResult<types::PayoutsRouterData<F>> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
feature = "payouts",
|
||||
any(feature = "v1", feature = "v2"),
|
||||
not(feature = "customer_v2")
|
||||
))]
|
||||
#[instrument(skip_all)]
|
||||
pub async fn construct_payout_router_data<'a, F>(
|
||||
connector_data: &api::ConnectorData,
|
||||
@ -131,7 +145,7 @@ pub async fn construct_payout_router_data<'a, F>(
|
||||
let router_data = types::RouterData {
|
||||
flow: PhantomData,
|
||||
merchant_id: merchant_account.get_id().to_owned(),
|
||||
customer_id: customer_details.to_owned().map(|c| c.get_customer_id()),
|
||||
customer_id: customer_details.to_owned().map(|c| c.customer_id),
|
||||
connector_customer: connector_customer_id,
|
||||
connector: connector_name.to_string(),
|
||||
payment_id: "".to_string(),
|
||||
@ -162,7 +176,7 @@ pub async fn construct_payout_router_data<'a, F>(
|
||||
customer_details: customer_details
|
||||
.to_owned()
|
||||
.map(|c| payments::CustomerDetails {
|
||||
customer_id: Some(c.get_customer_id()),
|
||||
customer_id: Some(c.customer_id),
|
||||
name: c.name.map(Encryptable::into_inner),
|
||||
email: c.email.map(Email::from),
|
||||
phone: c.phone.map(Encryptable::into_inner),
|
||||
|
||||
@ -230,7 +230,7 @@ mod storage {
|
||||
async fn find_optional_by_merchant_id_merchant_reference_id(
|
||||
&self,
|
||||
state: &KeyManagerState,
|
||||
customer_id: &id_type::CustomerId,
|
||||
merchant_reference_id: &id_type::CustomerId,
|
||||
merchant_id: &id_type::MerchantId,
|
||||
key_store: &domain::MerchantKeyStore,
|
||||
storage_scheme: MerchantStorageScheme,
|
||||
@ -239,7 +239,7 @@ mod storage {
|
||||
let database_call = || async {
|
||||
storage_types::Customer::find_optional_by_merchant_id_merchant_reference_id(
|
||||
&conn,
|
||||
customer_id,
|
||||
merchant_reference_id,
|
||||
merchant_id,
|
||||
)
|
||||
.await
|
||||
@ -253,9 +253,9 @@ mod storage {
|
||||
MerchantStorageScheme::RedisKv => {
|
||||
let key = PartitionKey::MerchantIdCustomerId {
|
||||
merchant_id,
|
||||
customer_id: customer_id.get_string_repr(),
|
||||
customer_id: merchant_reference_id.get_string_repr(),
|
||||
};
|
||||
let field = format!("cust_{}", customer_id.get_string_repr());
|
||||
let field = format!("cust_{}", merchant_reference_id.get_string_repr());
|
||||
Box::pin(db_utils::try_redis_get_else_try_database_get(
|
||||
// check for ValueNotFound
|
||||
async {
|
||||
@ -1192,7 +1192,7 @@ impl CustomerInterface for MockDb {
|
||||
let customer = customers
|
||||
.iter()
|
||||
.find(|customer| {
|
||||
customer.get_customer_id() == *customer_id && &customer.merchant_id == merchant_id
|
||||
customer.customer_id == *customer_id && &customer.merchant_id == merchant_id
|
||||
})
|
||||
.cloned();
|
||||
customer
|
||||
@ -1219,25 +1219,7 @@ impl CustomerInterface for MockDb {
|
||||
key_store: &domain::MerchantKeyStore,
|
||||
_storage_scheme: MerchantStorageScheme,
|
||||
) -> CustomResult<Option<customer::Customer>, errors::StorageError> {
|
||||
let customers = self.customers.lock().await;
|
||||
let customer = customers
|
||||
.iter()
|
||||
.find(|customer| {
|
||||
customer.get_customer_id() == *customer_id && &customer.merchant_id == merchant_id
|
||||
})
|
||||
.cloned();
|
||||
customer
|
||||
.async_map(|c| async {
|
||||
c.convert(
|
||||
state,
|
||||
key_store.key.get_inner(),
|
||||
key_store.merchant_id.clone().into(),
|
||||
)
|
||||
.await
|
||||
.change_context(errors::StorageError::DecryptionError)
|
||||
})
|
||||
.await
|
||||
.transpose()
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn list_customers_by_merchant_id(
|
||||
|
||||
@ -49,7 +49,7 @@ impl ForeignFrom<(domain::Customer, Option<payments::AddressDetails>)> for Custo
|
||||
impl ForeignFrom<customer::Customer> for CustomerResponse {
|
||||
fn foreign_from(cust: domain::Customer) -> Self {
|
||||
customers::CustomerResponse {
|
||||
merchant_reference_id: Some(cust.get_customer_id()),
|
||||
merchant_reference_id: cust.merchant_reference_id,
|
||||
name: cust.name,
|
||||
email: cust.email,
|
||||
phone: cust.phone,
|
||||
|
||||
@ -1536,10 +1536,18 @@ impl ForeignFrom<storage::GatewayStatusMap> for gsm_api_types::GsmResponse {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "customer_v2"))]
|
||||
impl ForeignFrom<&domain::Customer> for payments::CustomerDetailsResponse {
|
||||
fn foreign_from(_customer: &domain::Customer) -> Self {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))]
|
||||
impl ForeignFrom<&domain::Customer> for payments::CustomerDetailsResponse {
|
||||
fn foreign_from(customer: &domain::Customer) -> Self {
|
||||
Self {
|
||||
id: Some(customer.get_customer_id().clone()),
|
||||
id: Some(customer.customer_id.clone()),
|
||||
name: customer
|
||||
.name
|
||||
.as_ref()
|
||||
|
||||
Reference in New Issue
Block a user