diff --git a/connector-template/transformers.rs b/connector-template/transformers.rs index 9ba5dd7e3546..844a091f2e0e 100644 --- a/connector-template/transformers.rs +++ b/connector-template/transformers.rs @@ -126,6 +126,7 @@ impl TryFrom TryFrom TryFrom connector_response_reference_id: Some(item.response.order_number.to_string()), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -562,6 +565,7 @@ impl connector_response_reference_id: Some(item.response.order_number.to_string()), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -597,6 +601,7 @@ impl connector_response_reference_id: Some(item.response.order_number.to_string()), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -632,6 +637,7 @@ impl connector_response_reference_id: Some(item.response.order_number.to_string()), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) diff --git a/crates/hyperswitch_connectors/src/connectors/bitpay/transformers.rs b/crates/hyperswitch_connectors/src/connectors/bitpay/transformers.rs index 1c42bfd08c83..bf755f372993 100644 --- a/crates/hyperswitch_connectors/src/connectors/bitpay/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/bitpay/transformers.rs @@ -170,6 +170,7 @@ impl TryFrom TryFrom TryFrom connector_response_reference_id: item.response.invoice_number.clone(), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), status: enums::AttemptStatus::from(item.response), ..item.data @@ -429,6 +430,7 @@ impl connector_response_reference_id: item.response.invoice_number.clone(), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), status: enums::AttemptStatus::from(item.response), ..item.data @@ -478,6 +480,7 @@ impl connector_response_reference_id: item.response.invoice_number.clone(), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), status: enums::AttemptStatus::from(item.response), ..item.data @@ -558,6 +561,7 @@ impl connector_response_reference_id: item.response.invoice_number.clone(), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), status: enums::AttemptStatus::from(item.response), ..item.data @@ -615,6 +619,7 @@ impl connector_response_reference_id: item.response.invoice_number.clone(), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), status: enums::AttemptStatus::from(item.response), ..item.data diff --git a/crates/hyperswitch_connectors/src/connectors/stax/transformers.rs b/crates/hyperswitch_connectors/src/connectors/stax/transformers.rs index 8c767e848da5..c07cbe00f946 100644 --- a/crates/hyperswitch_connectors/src/connectors/stax/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/stax/transformers.rs @@ -367,6 +367,7 @@ impl TryFrom, incremental_authorization_allowed: Option, charge_id: Option, + connector_customer_id: Option, }, MultipleCaptureResponse { // pending_capture_id_list: Vec, diff --git a/crates/router/src/connector/aci/transformers.rs b/crates/router/src/connector/aci/transformers.rs index 175138add758..3059d84f3991 100644 --- a/crates/router/src/connector/aci/transformers.rs +++ b/crates/router/src/connector/aci/transformers.rs @@ -776,6 +776,7 @@ impl connector_response_reference_id: Some(item.response.id), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) diff --git a/crates/router/src/connector/adyen/transformers.rs b/crates/router/src/connector/adyen/transformers.rs index b1f14e8305be..284597231bc2 100644 --- a/crates/router/src/connector/adyen/transformers.rs +++ b/crates/router/src/connector/adyen/transformers.rs @@ -3195,6 +3195,7 @@ impl TryFrom> connector_response_reference_id: Some(item.response.reference), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -3230,6 +3231,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), payment_method_balance: Some(types::PaymentMethodBalance { currency: item.response.balance.currency, @@ -3295,6 +3297,7 @@ pub fn get_adyen_response( connector_response_reference_id: Some(response.merchant_reference), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }; Ok((status, error, payments_response_data)) } @@ -3359,6 +3362,7 @@ pub fn get_webhook_response( connector_response_reference_id: Some(response.merchant_reference_id), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }; Ok((status, error, payments_response_data)) } @@ -3432,6 +3436,7 @@ pub fn get_redirection_response( .or(response.psp_reference), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }; Ok((status, error, payments_response_data)) } @@ -3490,6 +3495,7 @@ pub fn get_present_to_shopper_response( .or(response.psp_reference), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }; Ok((status, error, payments_response_data)) } @@ -3547,6 +3553,7 @@ pub fn get_qr_code_response( .or(response.psp_reference), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }; Ok((status, error, payments_response_data)) } @@ -3590,6 +3597,7 @@ pub fn get_redirection_error_response( .or(response.psp_reference), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }; Ok((status, error, payments_response_data)) @@ -3957,6 +3965,7 @@ impl TryFrom> connector_response_reference_id: Some(item.response.reference), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), amount_captured: Some(0), ..item.data diff --git a/crates/router/src/connector/airwallex/transformers.rs b/crates/router/src/connector/airwallex/transformers.rs index 9fab84559b54..8e3e314aabfb 100644 --- a/crates/router/src/connector/airwallex/transformers.rs +++ b/crates/router/src/connector/airwallex/transformers.rs @@ -574,6 +574,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -617,6 +618,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) diff --git a/crates/router/src/connector/authorizedotnet/transformers.rs b/crates/router/src/connector/authorizedotnet/transformers.rs index 33570a782fd8..230e596cd55a 100644 --- a/crates/router/src/connector/authorizedotnet/transformers.rs +++ b/crates/router/src/connector/authorizedotnet/transformers.rs @@ -404,6 +404,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }), @@ -1124,6 +1125,7 @@ impl ), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), }, ..item.data @@ -1197,6 +1199,7 @@ impl ), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), }, ..item.data @@ -1522,6 +1525,7 @@ impl connector_response_reference_id: Some(transaction.transaction_id.clone()), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), status: payment_status, ..item.data diff --git a/crates/router/src/connector/bamboraapac/transformers.rs b/crates/router/src/connector/bamboraapac/transformers.rs index 5125fafcee9c..0a8b816a92db 100644 --- a/crates/router/src/connector/bamboraapac/transformers.rs +++ b/crates/router/src/connector/bamboraapac/transformers.rs @@ -298,6 +298,7 @@ impl connector_response_reference_id: Some(connector_transaction_id), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -468,6 +469,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -614,6 +616,7 @@ impl connector_response_reference_id: Some(connector_transaction_id), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -913,6 +916,7 @@ impl connector_response_reference_id: Some(connector_transaction_id), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) diff --git a/crates/router/src/connector/bankofamerica/transformers.rs b/crates/router/src/connector/bankofamerica/transformers.rs index 34244bbb819b..47c10f7cb715 100644 --- a/crates/router/src/connector/bankofamerica/transformers.rs +++ b/crates/router/src/connector/bankofamerica/transformers.rs @@ -79,6 +79,8 @@ pub struct BankOfAmericaPaymentsRequest { consumer_authentication_information: Option, #[serde(skip_serializing_if = "Option::is_none")] merchant_defined_information: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + buyer_information: Option, } #[derive(Debug, Serialize)] @@ -143,6 +145,13 @@ pub struct MerchantDefinedInformation { value: String, } +#[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct BuyerInformation { + email: Option, + merchant_customer_id: Option, +} + #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct BankOfAmericaConsumerAuthInformation { @@ -166,6 +175,11 @@ pub struct BankOfAmericaPaymentInstrument { id: Secret, } +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct BankOfAmericaCustomer { + id: Secret, +} + #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct CardPaymentInformation { @@ -211,6 +225,7 @@ pub enum PaymentInformation { #[serde(rename_all = "camelCase")] pub struct MandatePaymentInformation { payment_instrument: BankOfAmericaPaymentInstrument, + customer: BankOfAmericaCustomer, } #[derive(Debug, Serialize)] @@ -369,6 +384,16 @@ impl let error_response = get_error_response_if_failure((&info_response, mandate_status, item.http_code)); + let connector_customer_id = + info_response + .token_information + .clone() + .and_then(|token_information| { + token_information + .customer + .map(|customer| customer.id.expose()) + }); + let connector_response = match item.data.payment_method { common_enums::PaymentMethod::Card => info_response .processor_information @@ -421,6 +446,7 @@ impl ), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id, }), }, connector_response, @@ -814,7 +840,17 @@ impl ), ) -> Result { let email = item.router_data.request.get_email()?; - let bill_to = build_bill_to(item.router_data.get_optional_billing(), email)?; + let bill_to = build_bill_to(item.router_data.get_optional_billing(), email.clone())?; + let merchant_customer_id = item + .router_data + .customer_id + .clone() + .map(|id| id.get_string_repr().to_string()); + + let buyer_information = Some(BuyerInformation { + email: Some(email), + merchant_customer_id, + }); let order_information = OrderInformationWithBill::from((item, Some(bill_to))); let payment_information = PaymentInformation::try_from(&ccard)?; let processing_information = ProcessingInformation::try_from((item, None, None))?; @@ -833,6 +869,7 @@ impl client_reference_information, merchant_defined_information, consumer_authentication_information: None, + buyer_information, }) } } @@ -853,7 +890,17 @@ impl ), ) -> Result { let email = item.router_data.request.get_email()?; - let bill_to = build_bill_to(item.router_data.get_optional_billing(), email)?; + let bill_to = build_bill_to(item.router_data.get_optional_billing(), email.clone())?; + let merchant_customer_id = item + .router_data + .customer_id + .clone() + .map(|id| id.get_string_repr().to_string()); + + let buyer_information = Some(BuyerInformation { + email: Some(email), + merchant_customer_id, + }); let order_information = OrderInformationWithBill::from((item, Some(bill_to))); let processing_information = ProcessingInformation::try_from(( item, @@ -891,6 +938,7 @@ impl directory_server_transaction_id: None, specification_version: None, }), + buyer_information, }) } } @@ -909,7 +957,17 @@ impl ), ) -> Result { let email = item.router_data.request.get_email()?; - let bill_to = build_bill_to(item.router_data.get_optional_billing(), email)?; + let bill_to = build_bill_to(item.router_data.get_optional_billing(), email.clone())?; + let merchant_customer_id = item + .router_data + .customer_id + .clone() + .map(|id| id.get_string_repr().to_string()); + + let buyer_information = Some(BuyerInformation { + email: Some(email), + merchant_customer_id, + }); let order_information = OrderInformationWithBill::from((item, Some(bill_to))); let payment_information = PaymentInformation::from(&google_pay_data); let processing_information = @@ -929,6 +987,7 @@ impl client_reference_information, merchant_defined_information, consumer_authentication_information: None, + buyer_information, }) } } @@ -964,8 +1023,18 @@ impl TryFrom<&BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>> let email = item.router_data.request.get_email()?; let bill_to = build_bill_to( item.router_data.get_optional_billing(), - email, + email.clone(), )?; + let merchant_customer_id = item + .router_data + .customer_id + .clone() + .map(|id| id.get_string_repr().to_string()); + + let buyer_information = Some(BuyerInformation { + email: Some(email), + merchant_customer_id, + }); let order_information: OrderInformationWithBill = OrderInformationWithBill::from((item, Some(bill_to))); let processing_information = @@ -1009,6 +1078,7 @@ impl TryFrom<&BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>> specification_version: None, }, ), + buyer_information, }) } } @@ -1104,14 +1174,27 @@ impl let payment_instrument = BankOfAmericaPaymentInstrument { id: connector_mandate_id.into(), }; + let customer = BankOfAmericaCustomer { + id: item + .router_data + .connector_customer + .clone() + .ok_or(errors::ConnectorError::RequestEncodingFailedWithReason( + "Missing Connector Customer".to_owned(), + ))? + .into(), + }; + let bill_to = item.router_data.request.get_email().ok().and_then(|email| { build_bill_to(item.router_data.get_optional_billing(), email).ok() }); + let order_information = OrderInformationWithBill::from((item, bill_to)); let payment_information = PaymentInformation::MandatePayment(Box::new(MandatePaymentInformation { payment_instrument, + customer, })); let client_reference_information = ClientReferenceInformation::from(item); let merchant_defined_information = item @@ -1127,6 +1210,7 @@ impl client_reference_information, merchant_defined_information, consumer_authentication_information: None, + buyer_information: None, }) } } @@ -1340,6 +1424,7 @@ pub struct MerchantInitiatedTransactionResponse { #[serde(rename_all = "camelCase")] pub struct BankOfAmericaTokenInformation { payment_instrument: Option, + customer: Option, } #[derive(Debug, Clone, Deserialize, Serialize)] @@ -1487,6 +1572,16 @@ fn get_payment_response( payment_method_id: None, }); + let connector_customer_id = + info_response + .token_information + .clone() + .and_then(|token_information| { + token_information + .customer + .map(|customer| customer.id.expose()) + }); + Ok(types::PaymentsResponseData::TransactionResponse { resource_id: types::ResponseId::ConnectorTransactionId(info_response.id.clone()), redirection_data: None, @@ -1502,6 +1597,7 @@ fn get_payment_response( ), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id, }) } } @@ -1813,6 +1909,7 @@ impl .unwrap_or(Some(item.response.id)), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), connector_response, ..item.data @@ -1832,6 +1929,7 @@ impl connector_response_reference_id: Some(item.response.id), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }), @@ -2268,6 +2366,16 @@ impl TryFrom<(&types::SetupMandateRouterData, domain::Card)> for BankOfAmericaPa fn try_from( (item, ccard): (&types::SetupMandateRouterData, domain::Card), ) -> Result { + let email = item.request.get_email().ok(); + let merchant_customer_id = item + .customer_id + .clone() + .map(|id| id.get_string_repr().to_string()); + + let buyer_information = Some(BuyerInformation { + email, + merchant_customer_id, + }); let order_information = OrderInformationWithBill::try_from(item)?; let client_reference_information = ClientReferenceInformation::from(item); let merchant_defined_information = item.request.metadata.clone().map(|metadata| { @@ -2282,6 +2390,7 @@ impl TryFrom<(&types::SetupMandateRouterData, domain::Card)> for BankOfAmericaPa client_reference_information, consumer_authentication_information: None, merchant_defined_information, + buyer_information, }) } } @@ -2293,6 +2402,16 @@ impl TryFrom<(&types::SetupMandateRouterData, domain::ApplePayWalletData)> fn try_from( (item, apple_pay_data): (&types::SetupMandateRouterData, domain::ApplePayWalletData), ) -> Result { + let email = item.request.get_email().ok(); + let merchant_customer_id = item + .customer_id + .clone() + .map(|id| id.get_string_repr().to_string()); + + let buyer_information = Some(BuyerInformation { + email, + merchant_customer_id, + }); let order_information = OrderInformationWithBill::try_from(item)?; let client_reference_information = ClientReferenceInformation::from(item); let merchant_defined_information = item.request.metadata.clone().map(|metadata| { @@ -2340,6 +2459,7 @@ impl TryFrom<(&types::SetupMandateRouterData, domain::ApplePayWalletData)> client_reference_information, merchant_defined_information, consumer_authentication_information, + buyer_information, }) } } @@ -2351,6 +2471,16 @@ impl TryFrom<(&types::SetupMandateRouterData, domain::GooglePayWalletData)> fn try_from( (item, google_pay_data): (&types::SetupMandateRouterData, domain::GooglePayWalletData), ) -> Result { + let email = item.request.get_email().ok(); + let merchant_customer_id = item + .customer_id + .clone() + .map(|id| id.get_string_repr().to_string()); + + let buyer_information = Some(BuyerInformation { + email, + merchant_customer_id, + }); let order_information = OrderInformationWithBill::try_from(item)?; let client_reference_information = ClientReferenceInformation::from(item); let merchant_defined_information = item.request.metadata.clone().map(|metadata| { @@ -2367,6 +2497,7 @@ impl TryFrom<(&types::SetupMandateRouterData, domain::GooglePayWalletData)> client_reference_information, merchant_defined_information, consumer_authentication_information: None, + buyer_information, }) } } @@ -2398,7 +2529,7 @@ impl TryFrom<&types::SetupMandateRouterData> for OrderInformationWithBill { fn try_from(item: &types::SetupMandateRouterData) -> Result { let email = item.request.get_email()?; - let bill_to = build_bill_to(item.get_optional_billing(), email)?; + let bill_to = build_bill_to(item.get_optional_billing(), email.clone())?; Ok(Self { amount_details: Amount { diff --git a/crates/router/src/connector/billwerk/transformers.rs b/crates/router/src/connector/billwerk/transformers.rs index e91184c878cb..bccfe8df0a45 100644 --- a/crates/router/src/connector/billwerk/transformers.rs +++ b/crates/router/src/connector/billwerk/transformers.rs @@ -281,6 +281,7 @@ impl connector_response_reference_id: Some(item.response.handle), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }; Ok(Self { status: enums::AttemptStatus::from(item.response.state), diff --git a/crates/router/src/connector/bluesnap.rs b/crates/router/src/connector/bluesnap.rs index e6f01700c6d7..26b80c734f93 100644 --- a/crates/router/src/connector/bluesnap.rs +++ b/crates/router/src/connector/bluesnap.rs @@ -750,6 +750,7 @@ impl ConnectorIntegration connector_response_reference_id: Some(item.response.transaction_id), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) diff --git a/crates/router/src/connector/boku/transformers.rs b/crates/router/src/connector/boku/transformers.rs index eeb914fd8469..c0f1b304bc1d 100644 --- a/crates/router/src/connector/boku/transformers.rs +++ b/crates/router/src/connector/boku/transformers.rs @@ -305,6 +305,7 @@ impl TryFrom connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }) }; Ok(Self { @@ -472,6 +473,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }), @@ -623,6 +625,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }) }; Ok(Self { @@ -646,6 +649,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }), @@ -704,6 +708,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }) }; Ok(Self { @@ -767,6 +772,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }) }; Ok(Self { @@ -1279,6 +1285,7 @@ impl TryFrom> connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }) }; Ok(Self { @@ -1389,6 +1396,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }) }; Ok(Self { @@ -1494,6 +1502,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }) }; Ok(Self { diff --git a/crates/router/src/connector/cashtocode/transformers.rs b/crates/router/src/connector/cashtocode/transformers.rs index e6f4b9e57cf8..e34fd0aeb60b 100644 --- a/crates/router/src/connector/cashtocode/transformers.rs +++ b/crates/router/src/connector/cashtocode/transformers.rs @@ -270,6 +270,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ) } @@ -315,6 +316,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) diff --git a/crates/router/src/connector/checkout/transformers.rs b/crates/router/src/connector/checkout/transformers.rs index be48d2a864f6..5c7567eb3faa 100644 --- a/crates/router/src/connector/checkout/transformers.rs +++ b/crates/router/src/connector/checkout/transformers.rs @@ -685,6 +685,7 @@ impl TryFrom> ), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }; Ok(Self { status, @@ -738,6 +739,7 @@ impl TryFrom> ), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }; Ok(Self { status, @@ -814,6 +816,7 @@ impl TryFrom> connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), status: response.into(), ..item.data @@ -915,6 +918,7 @@ impl TryFrom> connector_response_reference_id: item.response.reference, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), status, amount_captured, diff --git a/crates/router/src/connector/coinbase/transformers.rs b/crates/router/src/connector/coinbase/transformers.rs index 82a6add72ee8..11ad4a61bb8d 100644 --- a/crates/router/src/connector/coinbase/transformers.rs +++ b/crates/router/src/connector/coinbase/transformers.rs @@ -150,6 +150,7 @@ impl connector_response_reference_id: Some(item.response.data.id.clone()), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), |context| { Ok(types::PaymentsResponseData::TransactionUnresolvedResponse{ diff --git a/crates/router/src/connector/cryptopay/transformers.rs b/crates/router/src/connector/cryptopay/transformers.rs index c15afd7fd444..52c64e68798f 100644 --- a/crates/router/src/connector/cryptopay/transformers.rs +++ b/crates/router/src/connector/cryptopay/transformers.rs @@ -188,6 +188,7 @@ impl .or(Some(item.response.data.id)), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }) }; match amount_captured_in_minor_units { diff --git a/crates/router/src/connector/cybersource/transformers.rs b/crates/router/src/connector/cybersource/transformers.rs index c68f0e6069f6..15e4b0c02ba2 100644 --- a/crates/router/src/connector/cybersource/transformers.rs +++ b/crates/router/src/connector/cybersource/transformers.rs @@ -61,13 +61,24 @@ pub struct CybersourceZeroMandateRequest { payment_information: PaymentInformation, order_information: OrderInformationWithBill, client_reference_information: ClientReferenceInformation, + #[serde(skip_serializing_if = "Option::is_none")] + buyer_information: Option, } impl TryFrom<&types::SetupMandateRouterData> for CybersourceZeroMandateRequest { type Error = error_stack::Report; fn try_from(item: &types::SetupMandateRouterData) -> Result { let email = item.request.get_email()?; - let bill_to = build_bill_to(item.get_optional_billing(), email)?; + let bill_to = build_bill_to(item.get_optional_billing(), email.clone())?; + let merchant_customer_id = item + .customer_id + .clone() + .map(|id| id.get_string_repr().to_string()); + + let buyer_information = Some(BuyerInformation { + email: Some(email), + merchant_customer_id, + }); let order_information = OrderInformationWithBill { amount_details: Amount { @@ -236,6 +247,7 @@ impl TryFrom<&types::SetupMandateRouterData> for CybersourceZeroMandateRequest { payment_information, order_information, client_reference_information, + buyer_information, }) } } @@ -251,6 +263,15 @@ pub struct CybersourcePaymentsRequest { consumer_authentication_information: Option, #[serde(skip_serializing_if = "Option::is_none")] merchant_defined_information: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + buyer_information: Option, +} + +#[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct BuyerInformation { + email: Option, + merchant_customer_id: Option, } #[derive(Debug, Serialize)] @@ -381,7 +402,8 @@ pub struct ApplePayPaymentInformation { #[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct MandatePaymentInformation { - payment_instrument: CybersoucrePaymentInstrument, + payment_instrument: CybersourcePaymentInstrument, + customer: CybersourceCustomer, } #[derive(Debug, Serialize)] @@ -411,7 +433,12 @@ pub enum PaymentInformation { } #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct CybersoucrePaymentInstrument { +pub struct CybersourcePaymentInstrument { + id: Secret, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct CybersourceCustomer { id: Secret, } #[derive(Debug, Serialize)] @@ -985,8 +1012,17 @@ impl ), ) -> Result { let email = item.router_data.request.get_email()?; - let bill_to = build_bill_to(item.router_data.get_optional_billing(), email)?; + let bill_to = build_bill_to(item.router_data.get_optional_billing(), email.clone())?; let order_information = OrderInformationWithBill::from((item, Some(bill_to))); + let merchant_customer_id = item + .router_data + .customer_id + .clone() + .map(|id| id.get_string_repr().to_string()); + let buyer_information = Some(BuyerInformation { + email: Some(email), + merchant_customer_id, + }); let card_issuer = ccard.get_card_issuer(); let card_type = match card_issuer { @@ -1047,6 +1083,7 @@ impl client_reference_information, consumer_authentication_information, merchant_defined_information, + buyer_information, }) } } @@ -1065,8 +1102,17 @@ impl ), ) -> Result { let email = item.router_data.request.get_email()?; - let bill_to = build_bill_to(item.router_data.get_optional_billing(), email)?; + let bill_to = build_bill_to(item.router_data.get_optional_billing(), email.clone())?; let order_information = OrderInformationWithBill::from((item, bill_to)); + let merchant_customer_id = item + .router_data + .customer_id + .clone() + .map(|id| id.get_string_repr().to_string()); + let buyer_information = Some(BuyerInformation { + email: Some(email), + merchant_customer_id, + }); let card_issuer = ccard.get_card_issuer(); let card_type = match card_issuer { @@ -1128,6 +1174,7 @@ impl client_reference_information, consumer_authentication_information, merchant_defined_information, + buyer_information, }) } } @@ -1148,8 +1195,18 @@ impl ), ) -> Result { let email = item.router_data.request.get_email()?; - let bill_to = build_bill_to(item.router_data.get_optional_billing(), email)?; + let bill_to = build_bill_to(item.router_data.get_optional_billing(), email.clone())?; let order_information = OrderInformationWithBill::from((item, Some(bill_to))); + let merchant_customer_id = item + .router_data + .customer_id + .clone() + .map(|id| id.get_string_repr().to_string()); + let buyer_information = Some(BuyerInformation { + email: Some(email), + merchant_customer_id, + }); + let processing_information = ProcessingInformation::try_from(( item, Some(PaymentSolution::ApplePay), @@ -1199,6 +1256,7 @@ impl veres_enrolled: None, }), merchant_defined_information, + buyer_information, }) } } @@ -1217,8 +1275,17 @@ impl ), ) -> Result { let email = item.router_data.request.get_email()?; - let bill_to = build_bill_to(item.router_data.get_optional_billing(), email)?; + let bill_to = build_bill_to(item.router_data.get_optional_billing(), email.clone())?; let order_information = OrderInformationWithBill::from((item, Some(bill_to))); + let merchant_customer_id = item + .router_data + .customer_id + .clone() + .map(|id| id.get_string_repr().to_string()); + let buyer_information = Some(BuyerInformation { + email: Some(email), + merchant_customer_id, + }); let payment_information = PaymentInformation::GooglePay(Box::new(GooglePayPaymentInformation { @@ -1246,6 +1313,7 @@ impl client_reference_information, consumer_authentication_information: None, merchant_defined_information, + buyer_information, }) } } @@ -1281,10 +1349,19 @@ impl TryFrom<&CybersourceRouterData<&types::PaymentsAuthorizeRouterData>> let email = item.router_data.request.get_email()?; let bill_to = build_bill_to( item.router_data.get_optional_billing(), - email, + email.clone(), )?; let order_information = OrderInformationWithBill::from((item, Some(bill_to))); + let merchant_customer_id = item + .router_data + .customer_id + .clone() + .map(|id| id.get_string_repr().to_string()); + let buyer_information = Some(BuyerInformation { + email: Some(email), + merchant_customer_id, + }); let processing_information = ProcessingInformation::try_from(( item, @@ -1337,6 +1414,7 @@ impl TryFrom<&CybersourceRouterData<&types::PaymentsAuthorizeRouterData>> veres_enrolled: None, }, ), + buyer_information, }) } } @@ -1426,17 +1504,37 @@ impl ), ) -> Result { let processing_information = ProcessingInformation::try_from((item, None, None))?; - let payment_instrument = CybersoucrePaymentInstrument { + let payment_instrument = CybersourcePaymentInstrument { id: connector_mandate_id.into(), }; - let bill_to = - item.router_data.request.get_email().ok().and_then(|email| { - build_bill_to(item.router_data.get_optional_billing(), email).ok() - }); + let customer = CybersourceCustomer { + id: item + .router_data + .connector_customer + .clone() + .ok_or(errors::ConnectorError::RequestEncodingFailedWithReason( + "Missing Connector Customer".to_owned(), + ))? + .into(), + }; + let email = item.router_data.request.get_email().ok(); + let bill_to = email.clone().and_then(|email| { + build_bill_to(item.router_data.get_optional_billing(), email.clone()).ok() + }); + let merchant_customer_id = item + .router_data + .customer_id + .clone() + .map(|id| id.get_string_repr().to_string()); + let buyer_information = Some(BuyerInformation { + email, + merchant_customer_id, + }); let order_information = OrderInformationWithBill::from((item, bill_to)); let payment_information = PaymentInformation::MandatePayment(Box::new(MandatePaymentInformation { payment_instrument, + customer, })); let client_reference_information = ClientReferenceInformation::from(item); let merchant_defined_information = item @@ -1452,6 +1550,7 @@ impl client_reference_information, merchant_defined_information, consumer_authentication_information: None, + buyer_information, }) } } @@ -1862,7 +1961,8 @@ pub struct ClientRiskInformationRules { #[derive(Debug, Clone, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct CybersourceTokenInformation { - payment_instrument: Option, + payment_instrument: Option, + customer: Option, } #[derive(Debug, Clone, Deserialize, Serialize)] @@ -1975,6 +2075,16 @@ fn get_payment_response( payment_method_id: None, }); + let connector_customer_id = + info_response + .token_information + .clone() + .and_then(|token_information| { + token_information + .customer + .map(|customer| customer.id.expose()) + }); + Ok(types::PaymentsResponseData::TransactionResponse { resource_id: types::ResponseId::ConnectorTransactionId(info_response.id.clone()), redirection_data: None, @@ -1992,6 +2102,7 @@ fn get_payment_response( ), incremental_authorization_allowed, charge_id: None, + connector_customer_id, }) } } @@ -2087,6 +2198,7 @@ impl ), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }), @@ -2254,7 +2366,8 @@ impl TryFrom<&CybersourceRouterData<&types::PaymentsPreProcessingRouterData>> .1 .to_string(); let email = item.router_data.request.get_email()?; - let bill_to = build_bill_to(item.router_data.get_optional_billing(), email)?; + let bill_to = + build_bill_to(item.router_data.get_optional_billing(), email.clone())?; let order_information = OrderInformationWithBill { amount_details, bill_to: Some(bill_to), @@ -2483,6 +2596,7 @@ impl connector_response_reference_id, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -2696,6 +2810,16 @@ impl .unwrap_or(CybersourcePaymentStatus::StatusNotReceived), false, )); + let connector_customer_id = + item.response + .token_information + .clone() + .and_then(|token_information| { + token_information + .customer + .map(|customer| customer.id.expose()) + }); + if matches!(mandate_status, enums::AttemptStatus::Authorized) { //In case of zero auth mandates we want to make the payment reach the terminal status so we are converting the authorized status to charged as well. mandate_status = enums::AttemptStatus::Charged @@ -2738,6 +2862,7 @@ impl mandate_status == enums::AttemptStatus::Authorized, ), charge_id: None, + connector_customer_id, }), }, connector_response, @@ -2867,6 +2992,7 @@ impl .unwrap_or(Some(item.response.id)), incremental_authorization_allowed, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -2885,6 +3011,7 @@ impl connector_response_reference_id: Some(item.response.id), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }), diff --git a/crates/router/src/connector/datatrans/transformers.rs b/crates/router/src/connector/datatrans/transformers.rs index 96c7bcd8b2c0..95265ca1c598 100644 --- a/crates/router/src/connector/datatrans/transformers.rs +++ b/crates/router/src/connector/datatrans/transformers.rs @@ -298,6 +298,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }) } }; @@ -416,6 +417,7 @@ impl TryFrom> connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) diff --git a/crates/router/src/connector/dlocal/transformers.rs b/crates/router/src/connector/dlocal/transformers.rs index ca18d12a0883..0626fa650ba3 100644 --- a/crates/router/src/connector/dlocal/transformers.rs +++ b/crates/router/src/connector/dlocal/transformers.rs @@ -333,6 +333,7 @@ impl connector_response_reference_id: item.response.order_id.clone(), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }; Ok(Self { status: enums::AttemptStatus::from(item.response.status), @@ -374,6 +375,7 @@ impl connector_response_reference_id: item.response.order_id.clone(), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -412,6 +414,7 @@ impl connector_response_reference_id: item.response.order_id.clone(), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -450,6 +453,7 @@ impl connector_response_reference_id: Some(item.response.order_id.clone()), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) diff --git a/crates/router/src/connector/dummyconnector/transformers.rs b/crates/router/src/connector/dummyconnector/transformers.rs index 2cf5960bf753..896328bf55ed 100644 --- a/crates/router/src/connector/dummyconnector/transformers.rs +++ b/crates/router/src/connector/dummyconnector/transformers.rs @@ -260,6 +260,7 @@ impl TryFrom connector_response_reference_id: Some(transaction_id.to_string()), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -330,6 +331,7 @@ impl connector_response_reference_id: Some(transaction_id.to_string()), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -399,6 +401,7 @@ impl TryFrom> connector_response_reference_id: Some(item.response.transaction_id.to_string()), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), amount_captured: None, ..item.data @@ -468,6 +471,7 @@ impl connector_response_reference_id: Some(transaction_id.to_string()), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) diff --git a/crates/router/src/connector/globalpay/transformers.rs b/crates/router/src/connector/globalpay/transformers.rs index efc6661b447b..fd44c0cf99fb 100644 --- a/crates/router/src/connector/globalpay/transformers.rs +++ b/crates/router/src/connector/globalpay/transformers.rs @@ -280,6 +280,7 @@ fn get_payment_response( connector_response_reference_id: response.reference, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), } } diff --git a/crates/router/src/connector/globepay/transformers.rs b/crates/router/src/connector/globepay/transformers.rs index 8974c9f94b97..d7d0642044b7 100644 --- a/crates/router/src/connector/globepay/transformers.rs +++ b/crates/router/src/connector/globepay/transformers.rs @@ -198,6 +198,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -273,6 +274,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) diff --git a/crates/router/src/connector/gocardless/transformers.rs b/crates/router/src/connector/gocardless/transformers.rs index fb27f5138a9c..ead5c3c675fc 100644 --- a/crates/router/src/connector/gocardless/transformers.rs +++ b/crates/router/src/connector/gocardless/transformers.rs @@ -520,6 +520,7 @@ impl mandate_reference, network_txn_id: None, charge_id: None, + connector_customer_id: None, }), status: enums::AttemptStatus::Charged, ..item.data @@ -673,6 +674,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -709,6 +711,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) diff --git a/crates/router/src/connector/iatapay/transformers.rs b/crates/router/src/connector/iatapay/transformers.rs index 845e079e136c..c92fc95c6921 100644 --- a/crates/router/src/connector/iatapay/transformers.rs +++ b/crates/router/src/connector/iatapay/transformers.rs @@ -386,6 +386,7 @@ fn get_iatpay_response( connector_response_reference_id: connector_response_reference_id.clone(), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, } } None => types::PaymentsResponseData::TransactionResponse { @@ -397,6 +398,7 @@ fn get_iatpay_response( connector_response_reference_id: connector_response_reference_id.clone(), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }, }; diff --git a/crates/router/src/connector/itaubank/transformers.rs b/crates/router/src/connector/itaubank/transformers.rs index 5c53cfbf1602..23f3b1a6fb81 100644 --- a/crates/router/src/connector/itaubank/transformers.rs +++ b/crates/router/src/connector/itaubank/transformers.rs @@ -268,6 +268,7 @@ impl connector_response_reference_id: Some(item.response.txid), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -356,6 +357,7 @@ impl connector_response_reference_id: Some(item.response.txid), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) diff --git a/crates/router/src/connector/klarna/transformers.rs b/crates/router/src/connector/klarna/transformers.rs index e6f0bab9c2c8..50c936c0d7bf 100644 --- a/crates/router/src/connector/klarna/transformers.rs +++ b/crates/router/src/connector/klarna/transformers.rs @@ -279,6 +279,7 @@ impl TryFrom> connector_response_reference_id: Some(item.response.order_id.clone()), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), status: enums::AttemptStatus::foreign_from(( item.response.fraud_status, @@ -404,6 +405,7 @@ impl .or(Some(item.response.order_id)), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -481,6 +483,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), status, ..item.data diff --git a/crates/router/src/connector/mifinity/transformers.rs b/crates/router/src/connector/mifinity/transformers.rs index 7fd34b936988..f3848d8c9a30 100644 --- a/crates/router/src/connector/mifinity/transformers.rs +++ b/crates/router/src/connector/mifinity/transformers.rs @@ -265,6 +265,7 @@ impl connector_response_reference_id: Some(trace_id), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -280,6 +281,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }), @@ -349,6 +351,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -364,6 +367,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }), @@ -380,6 +384,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }), diff --git a/crates/router/src/connector/mollie/transformers.rs b/crates/router/src/connector/mollie/transformers.rs index f755ca6029bc..7b09ea711d0e 100644 --- a/crates/router/src/connector/mollie/transformers.rs +++ b/crates/router/src/connector/mollie/transformers.rs @@ -535,6 +535,7 @@ impl connector_response_reference_id: Some(item.response.id), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) diff --git a/crates/router/src/connector/multisafepay/transformers.rs b/crates/router/src/connector/multisafepay/transformers.rs index ac0a04de182d..f365c715ae22 100644 --- a/crates/router/src/connector/multisafepay/transformers.rs +++ b/crates/router/src/connector/multisafepay/transformers.rs @@ -988,6 +988,7 @@ impl ), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }) }, ..item.data diff --git a/crates/router/src/connector/nexinets/transformers.rs b/crates/router/src/connector/nexinets/transformers.rs index 7e32ae5ebedb..9ebe2186c315 100644 --- a/crates/router/src/connector/nexinets/transformers.rs +++ b/crates/router/src/connector/nexinets/transformers.rs @@ -373,6 +373,7 @@ impl connector_response_reference_id: Some(item.response.order_id), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -457,6 +458,7 @@ impl connector_response_reference_id: Some(item.response.order.order_id), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) diff --git a/crates/router/src/connector/nmi/transformers.rs b/crates/router/src/connector/nmi/transformers.rs index e0858e16a4a6..7079be017b50 100644 --- a/crates/router/src/connector/nmi/transformers.rs +++ b/crates/router/src/connector/nmi/transformers.rs @@ -213,6 +213,7 @@ impl connector_response_reference_id: Some(item.response.transactionid), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), enums::AttemptStatus::AuthenticationPending, ), @@ -367,6 +368,7 @@ impl connector_response_reference_id: Some(item.response.orderid), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), if let Some(diesel_models::enums::CaptureMethod::Automatic) = item.data.request.capture_method @@ -747,6 +749,7 @@ impl connector_response_reference_id: Some(item.response.orderid), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), enums::AttemptStatus::CaptureInitiated, ), @@ -842,6 +845,7 @@ impl connector_response_reference_id: Some(item.response.orderid), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), enums::AttemptStatus::Charged, ), @@ -899,6 +903,7 @@ impl TryFrom> connector_response_reference_id: Some(item.response.orderid), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), if let Some(diesel_models::enums::CaptureMethod::Automatic) = item.data.request.capture_method @@ -950,6 +955,7 @@ impl connector_response_reference_id: Some(item.response.orderid), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), enums::AttemptStatus::VoidInitiated, ), @@ -1001,6 +1007,7 @@ impl TryFrom connector_response_reference_id, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }) } }, diff --git a/crates/router/src/connector/nuvei/transformers.rs b/crates/router/src/connector/nuvei/transformers.rs index 1aa345173570..6e0268985707 100644 --- a/crates/router/src/connector/nuvei/transformers.rs +++ b/crates/router/src/connector/nuvei/transformers.rs @@ -1615,6 +1615,7 @@ where connector_response_reference_id: response.order_id, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }) }, ..item.data diff --git a/crates/router/src/connector/opayo/transformers.rs b/crates/router/src/connector/opayo/transformers.rs index 5771b45100bd..13e2458b8bf4 100644 --- a/crates/router/src/connector/opayo/transformers.rs +++ b/crates/router/src/connector/opayo/transformers.rs @@ -131,6 +131,7 @@ impl connector_response_reference_id: Some(item.response.transaction_id), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) diff --git a/crates/router/src/connector/opennode/transformers.rs b/crates/router/src/connector/opennode/transformers.rs index 8f1579ac1ff4..2f52e76a16bd 100644 --- a/crates/router/src/connector/opennode/transformers.rs +++ b/crates/router/src/connector/opennode/transformers.rs @@ -145,6 +145,7 @@ impl connector_response_reference_id: item.response.data.order_id, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }) } else { Ok(types::PaymentsResponseData::TransactionUnresolvedResponse { diff --git a/crates/router/src/connector/paybox/transformers.rs b/crates/router/src/connector/paybox/transformers.rs index d83c4261c19b..dbd5c1af5282 100644 --- a/crates/router/src/connector/paybox/transformers.rs +++ b/crates/router/src/connector/paybox/transformers.rs @@ -128,6 +128,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) diff --git a/crates/router/src/connector/payeezy/transformers.rs b/crates/router/src/connector/payeezy/transformers.rs index 8da3e7502bed..4166c42c840e 100644 --- a/crates/router/src/connector/payeezy/transformers.rs +++ b/crates/router/src/connector/payeezy/transformers.rs @@ -438,6 +438,7 @@ impl ), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) diff --git a/crates/router/src/connector/payme/transformers.rs b/crates/router/src/connector/payme/transformers.rs index 2ec35b7a7de0..5e5219aa0e74 100644 --- a/crates/router/src/connector/payme/transformers.rs +++ b/crates/router/src/connector/payme/transformers.rs @@ -256,6 +256,7 @@ impl TryFrom<&PaymePaySaleResponse> for types::PaymentsResponseData { connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }) } } @@ -323,6 +324,7 @@ impl From<&SaleQuery> for types::PaymentsResponseData { connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, } } } @@ -539,6 +541,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }), @@ -1102,6 +1105,7 @@ impl TryFrom> connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }) }; Ok(Self { diff --git a/crates/router/src/connector/paypal.rs b/crates/router/src/connector/paypal.rs index 5ea880c16b92..7a14c625055e 100644 --- a/crates/router/src/connector/paypal.rs +++ b/crates/router/src/connector/paypal.rs @@ -880,6 +880,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..data.clone() }) @@ -931,6 +932,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..data.clone() }) diff --git a/crates/router/src/connector/paypal/transformers.rs b/crates/router/src/connector/paypal/transformers.rs index fb70581cd972..840133e41963 100644 --- a/crates/router/src/connector/paypal/transformers.rs +++ b/crates/router/src/connector/paypal/transformers.rs @@ -1149,6 +1149,7 @@ impl .or(Some(item.response.id)), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -1273,6 +1274,7 @@ impl ), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -1331,6 +1333,7 @@ impl ), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -1369,6 +1372,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -1421,6 +1425,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -1490,6 +1495,7 @@ impl .or(Some(item.response.supplementary_data.related_ids.order_id)), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -1829,6 +1835,7 @@ impl TryFrom> .or(Some(item.response.id)), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), amount_captured: Some(amount_captured), ..item.data @@ -1881,6 +1888,7 @@ impl .or(Some(item.response.id)), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) diff --git a/crates/router/src/connector/payu/transformers.rs b/crates/router/src/connector/payu/transformers.rs index 5365fc74ef2e..5e789b65fea0 100644 --- a/crates/router/src/connector/payu/transformers.rs +++ b/crates/router/src/connector/payu/transformers.rs @@ -212,6 +212,7 @@ impl .or(Some(item.response.order_id)), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), amount_captured: None, ..item.data @@ -266,6 +267,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), amount_captured: None, ..item.data @@ -353,6 +355,7 @@ impl .or(Some(item.response.order_id)), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), amount_captured: None, ..item.data @@ -488,6 +491,7 @@ impl .or(Some(order.order_id.clone())), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), amount_captured: Some( order diff --git a/crates/router/src/connector/placetopay/transformers.rs b/crates/router/src/connector/placetopay/transformers.rs index 50c897653dac..f4b574870605 100644 --- a/crates/router/src/connector/placetopay/transformers.rs +++ b/crates/router/src/connector/placetopay/transformers.rs @@ -272,6 +272,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) diff --git a/crates/router/src/connector/plaid/transformers.rs b/crates/router/src/connector/plaid/transformers.rs index cf9c91afd0c1..3f568590149b 100644 --- a/crates/router/src/connector/plaid/transformers.rs +++ b/crates/router/src/connector/plaid/transformers.rs @@ -286,6 +286,7 @@ impl connector_response_reference_id: Some(item.response.payment_id), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }) }, ..item.data @@ -372,6 +373,7 @@ impl TryFrom connector_response_reference_id: Some(item.response.order_identifier), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), Err, ); diff --git a/crates/router/src/connector/prophetpay/transformers.rs b/crates/router/src/connector/prophetpay/transformers.rs index 6862c7c4c807..fd796625ec8e 100644 --- a/crates/router/src/connector/prophetpay/transformers.rs +++ b/crates/router/src/connector/prophetpay/transformers.rs @@ -208,6 +208,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -408,6 +409,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -459,6 +461,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -510,6 +513,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) diff --git a/crates/router/src/connector/rapyd/transformers.rs b/crates/router/src/connector/rapyd/transformers.rs index 044a64b413cf..b3906972131c 100644 --- a/crates/router/src/connector/rapyd/transformers.rs +++ b/crates/router/src/connector/rapyd/transformers.rs @@ -481,6 +481,7 @@ impl connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ) } diff --git a/crates/router/src/connector/razorpay/transformers.rs b/crates/router/src/connector/razorpay/transformers.rs index 8cf328918868..6d775fdcf2a5 100644 --- a/crates/router/src/connector/razorpay/transformers.rs +++ b/crates/router/src/connector/razorpay/transformers.rs @@ -794,6 +794,7 @@ impl connector_response_reference_id: Some(second_factor.txn_id), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }), @@ -1015,6 +1016,7 @@ impl connector_response_reference_id: Some(item.response.second_factor.txn_id), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) diff --git a/crates/router/src/connector/shift4/transformers.rs b/crates/router/src/connector/shift4/transformers.rs index f384d8d296d5..90944a4cf359 100644 --- a/crates/router/src/connector/shift4/transformers.rs +++ b/crates/router/src/connector/shift4/transformers.rs @@ -754,6 +754,7 @@ impl TryFrom connector_response_reference_id: Some(item.response.id), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) diff --git a/crates/router/src/connector/square/transformers.rs b/crates/router/src/connector/square/transformers.rs index 67be82bb2d91..081c2dab2d53 100644 --- a/crates/router/src/connector/square/transformers.rs +++ b/crates/router/src/connector/square/transformers.rs @@ -387,6 +387,7 @@ impl connector_response_reference_id: item.response.payment.reference_id, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), amount_captured, ..item.data diff --git a/crates/router/src/connector/stripe/transformers.rs b/crates/router/src/connector/stripe/transformers.rs index 90ddc9f0b903..b5378fe9d786 100644 --- a/crates/router/src/connector/stripe/transformers.rs +++ b/crates/router/src/connector/stripe/transformers.rs @@ -2431,6 +2431,7 @@ impl connector_response_reference_id: Some(item.response.id), incremental_authorization_allowed: None, charge_id, + connector_customer_id: None, }) }; @@ -2627,6 +2628,7 @@ impl connector_response_reference_id: Some(item.response.id.clone()), incremental_authorization_allowed: None, charge_id, + connector_customer_id: None, }) }; @@ -2705,6 +2707,7 @@ impl connector_response_reference_id: Some(item.response.id), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }) }; @@ -3406,6 +3409,7 @@ impl TryFrom types::PaymentsRes connector_response_reference_id: Some(connector_response.transaction_id), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, } } @@ -246,6 +247,7 @@ fn get_payments_sync_response( ), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, } } diff --git a/crates/router/src/connector/volt/transformers.rs b/crates/router/src/connector/volt/transformers.rs index fcc95cd0d4b4..8fa3e17ca351 100644 --- a/crates/router/src/connector/volt/transformers.rs +++ b/crates/router/src/connector/volt/transformers.rs @@ -277,6 +277,7 @@ impl connector_response_reference_id: Some(item.response.id), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -359,6 +360,7 @@ impl .or(Some(payment_response.id)), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }) }, ..item.data @@ -400,6 +402,7 @@ impl .or(Some(webhook_response.payment)), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }) }, ..item.data diff --git a/crates/router/src/connector/wellsfargo/transformers.rs b/crates/router/src/connector/wellsfargo/transformers.rs index 93ed04288afe..1b8e25f60994 100644 --- a/crates/router/src/connector/wellsfargo/transformers.rs +++ b/crates/router/src/connector/wellsfargo/transformers.rs @@ -1794,6 +1794,7 @@ fn get_payment_response( ), incremental_authorization_allowed, charge_id: None, + connector_customer_id: None, }) } } @@ -2010,6 +2011,7 @@ impl mandate_status == enums::AttemptStatus::Authorized, ), charge_id: None, + connector_customer_id: None, }), }, connector_response, @@ -2139,6 +2141,7 @@ impl .unwrap_or(Some(item.response.id)), incremental_authorization_allowed, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -2157,6 +2160,7 @@ impl connector_response_reference_id: Some(item.response.id), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }), diff --git a/crates/router/src/connector/worldline/transformers.rs b/crates/router/src/connector/worldline/transformers.rs index 11d9da7785a1..e846cb4e5d51 100644 --- a/crates/router/src/connector/worldline/transformers.rs +++ b/crates/router/src/connector/worldline/transformers.rs @@ -586,6 +586,7 @@ impl TryFrom TryFrom> connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) diff --git a/crates/router/src/connector/zen/transformers.rs b/crates/router/src/connector/zen/transformers.rs index 2562277ee9b4..eb8fbe91eb2d 100644 --- a/crates/router/src/connector/zen/transformers.rs +++ b/crates/router/src/connector/zen/transformers.rs @@ -951,6 +951,7 @@ fn get_zen_response( connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }; Ok((status, error, payment_response_data)) } @@ -995,6 +996,7 @@ impl TryFrom connector_response_reference_id: Some(item.response.mer_ref.clone()), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) @@ -456,6 +457,7 @@ impl connector_response_reference_id: Some(item.response.mer_ref.clone()), incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }), ..item.data }) diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs index 34a5c337ce43..4ea39e12d2fa 100644 --- a/crates/router/src/core/payments.rs +++ b/crates/router/src/core/payments.rs @@ -328,6 +328,19 @@ where ) .await?; + operation + .to_post_update_tracker()? + .update_connector_customer( + state, + &router_data, + &merchant_account, + &mca, + customer.clone(), + &key_store, + &mut payment_data, + ) + .await?; + let mut payment_data = operation .to_post_update_tracker()? .update_tracker( @@ -451,6 +464,19 @@ where ) .await?; + operation + .to_post_update_tracker()? + .update_connector_customer( + state, + &router_data, + &merchant_account, + &mca, + customer.clone(), + &key_store, + &mut payment_data, + ) + .await?; + let mut payment_data = operation .to_post_update_tracker()? .update_tracker( diff --git a/crates/router/src/core/payments/customers.rs b/crates/router/src/core/payments/customers.rs index 4b71c43aca66..e2aa70382673 100644 --- a/crates/router/src/core/payments/customers.rs +++ b/crates/router/src/core/payments/customers.rs @@ -98,14 +98,15 @@ pub fn should_call_connector_create_customer<'a>( .connector_list .contains(&connector.connector_name); + let connector_customer_details = customer + .as_ref() + .and_then(|customer| get_connector_customer_details_if_present(customer, connector_label)); + if connector_needs_customer { - let connector_customer_details = customer.as_ref().and_then(|customer| { - get_connector_customer_details_if_present(customer, connector_label) - }); let should_call_connector = connector_customer_details.is_none(); (should_call_connector, connector_customer_details) } else { - (false, None) + (false, connector_customer_details) } } diff --git a/crates/router/src/core/payments/operations.rs b/crates/router/src/core/payments/operations.rs index 336755c6e3da..1602ea1d0cc1 100644 --- a/crates/router/src/core/payments/operations.rs +++ b/crates/router/src/core/payments/operations.rs @@ -247,6 +247,23 @@ pub trait PostUpdateTracker: Send { { Ok(()) } + + #[allow(clippy::too_many_arguments)] + async fn update_connector_customer<'b>( + &self, + _state: &SessionState, + _router_data: &types::RouterData, + _merchant_account: &domain::MerchantAccount, + _merchant_connector_account: &helpers::MerchantConnectorAccountType, + _customer: Option, + _key_store: &domain::MerchantKeyStore, + _payment_data: &mut PaymentData, + ) -> CustomResult<(), errors::ApiErrorResponse> + where + F: 'b + Clone + Send + Sync, + { + Ok(()) + } } #[async_trait] diff --git a/crates/router/src/core/payments/operations/payment_response.rs b/crates/router/src/core/payments/operations/payment_response.rs index a9449e38d2e8..be827fab01cc 100644 --- a/crates/router/src/core/payments/operations/payment_response.rs +++ b/crates/router/src/core/payments/operations/payment_response.rs @@ -21,6 +21,7 @@ use crate::{ errors::{self, CustomResult, RouterResult, StorageErrorExt}, mandate, payment_methods, payments::{ + customers, helpers::{ self as payments_helpers, update_additional_payment_data_with_connector_response_pm_data, @@ -260,6 +261,36 @@ impl PostUpdateTracker, types::PaymentsAuthor Ok(()) } } + + async fn update_connector_customer<'b>( + &self, + state: &SessionState, + router_data: &types::RouterData< + F, + types::PaymentsAuthorizeData, + types::PaymentsResponseData, + >, + merchant_account: &domain::MerchantAccount, + merchant_connector_account: &payments_helpers::MerchantConnectorAccountType, + customer: Option, + key_store: &domain::MerchantKeyStore, + payment_data: &mut PaymentData, + ) -> CustomResult<(), errors::ApiErrorResponse> + where + F: 'b + Clone + Send + Sync, + { + update_connector_customer_from_router_data( + state, + router_data, + merchant_account, + merchant_connector_account, + customer, + key_store, + payment_data, + ) + .await?; + Ok(()) + } } #[async_trait] @@ -447,6 +478,32 @@ impl PostUpdateTracker, types::PaymentsSyncData> for .await?; Ok(()) } + + async fn update_connector_customer<'b>( + &self, + state: &SessionState, + router_data: &types::RouterData, + merchant_account: &domain::MerchantAccount, + merchant_connector_account: &payments_helpers::MerchantConnectorAccountType, + customer: Option, + key_store: &domain::MerchantKeyStore, + payment_data: &mut PaymentData, + ) -> CustomResult<(), errors::ApiErrorResponse> + where + F: 'b + Clone + Send + Sync, + { + update_connector_customer_from_router_data( + state, + router_data, + merchant_account, + merchant_connector_account, + customer, + key_store, + payment_data, + ) + .await?; + Ok(()) + } } #[async_trait] @@ -695,6 +752,36 @@ impl PostUpdateTracker, types::SetupMandateRequestDa payment_data.payment_attempt.mandate_id = mandate_id; Ok(()) } + + async fn update_connector_customer<'b>( + &self, + state: &SessionState, + router_data: &types::RouterData< + F, + types::SetupMandateRequestData, + types::PaymentsResponseData, + >, + merchant_account: &domain::MerchantAccount, + merchant_connector_account: &payments_helpers::MerchantConnectorAccountType, + customer: Option, + key_store: &domain::MerchantKeyStore, + payment_data: &mut PaymentData, + ) -> CustomResult<(), errors::ApiErrorResponse> + where + F: 'b + Clone + Send + Sync, + { + update_connector_customer_from_router_data( + state, + router_data, + merchant_account, + merchant_connector_account, + customer, + key_store, + payment_data, + ) + .await?; + Ok(()) + } } #[async_trait] @@ -747,6 +834,35 @@ impl PostUpdateTracker, types::CompleteAuthorizeData .await?; Ok(()) } + async fn update_connector_customer<'b>( + &self, + state: &SessionState, + router_data: &types::RouterData< + F, + types::CompleteAuthorizeData, + types::PaymentsResponseData, + >, + merchant_account: &domain::MerchantAccount, + merchant_connector_account: &payments_helpers::MerchantConnectorAccountType, + customer: Option, + key_store: &domain::MerchantKeyStore, + payment_data: &mut PaymentData, + ) -> CustomResult<(), errors::ApiErrorResponse> + where + F: 'b + Clone + Send + Sync, + { + update_connector_customer_from_router_data( + state, + router_data, + merchant_account, + merchant_connector_account, + customer, + key_store, + payment_data, + ) + .await?; + Ok(()) + } } #[instrument(skip_all)] @@ -1396,6 +1512,108 @@ async fn payment_response_update_tracker( } } +async fn update_connector_customer_from_router_data( + state: &SessionState, + router_data: &types::RouterData, + merchant_account: &domain::MerchantAccount, + merchant_connector_account: &payments_helpers::MerchantConnectorAccountType, + customer: Option, + key_store: &domain::MerchantKeyStore, + payment_data: &mut PaymentData, +) -> CustomResult<(), errors::ApiErrorResponse> +where + F: Clone + Send + Sync, +{ + let connector_name = payment_data.payment_attempt.connector.clone(); + + let updated_customer = match connector_name { + Some(connector_name) => { + let connector_label = core_utils::get_connector_label( + payment_data.payment_intent.business_country, + payment_data.payment_intent.business_label.as_ref(), + payment_data.payment_attempt.business_sub_label.as_ref(), + &connector_name, + ); + + let connector_label = if let Some(connector_label) = + merchant_connector_account.get_mca_id().or(connector_label) + { + connector_label + } else { + let profile_id = core_utils::get_profile_id_from_business_details( + payment_data.payment_intent.business_country, + payment_data.payment_intent.business_label.as_ref(), + merchant_account, + payment_data.payment_intent.profile_id.as_ref(), + &*state.store, + false, + ) + .await + .attach_printable("Could not find profile id from business details")?; + + format!("{connector_name}_{profile_id}") + }; + + let connector_customer_id = match router_data.response.clone() { + Ok(types::PaymentsResponseData::TransactionResponse { + connector_customer_id, + .. + }) => connector_customer_id, + _ => None, + }; + + let customer_update = customers::update_connector_customer_in_customers( + &connector_label, + customer.as_ref(), + &connector_customer_id, + ) + .await; + + payment_data.connector_customer_id = connector_customer_id; + customer_update + } + None => None, + }; + + let customer_fut = + if let (Some(updated_customer), Some(customer)) = (updated_customer, customer) { + let m_customer_customer_id = customer.customer_id.to_owned(); + let m_customer_merchant_id = customer.merchant_id.to_owned(); + let m_key_store = key_store.clone(); + let m_updated_customer = updated_customer.clone(); + let m_storage_scheme = merchant_account.storage_scheme; + let session_state = state.clone(); + let m_db = session_state.store.clone(); + let key_manager_state = state.into(); + tokio::spawn( + async move { + m_db.update_customer_by_customer_id_merchant_id( + &key_manager_state, + m_customer_customer_id, + m_customer_merchant_id, + customer, + m_updated_customer, + &m_key_store, + m_storage_scheme, + ) + .await + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Failed to update CustomerConnector in customer")?; + + Ok::<_, error_stack::Report>(()) + } + .in_current_span(), + ) + } else { + tokio::spawn( + async move { Ok::<_, error_stack::Report>(()) } + .in_current_span(), + ) + }; + utils::flatten_join_error(customer_fut).await?; + Ok(()) +} + async fn update_payment_method_status_and_ntid( state: &SessionState, payment_data: &mut PaymentData, diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index 404eb4bae760..e1f27530cc63 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -95,6 +95,7 @@ where connector_response_reference_id: None, incremental_authorization_allowed: None, charge_id: None, + connector_customer_id: None, }); let additional_data = PaymentAdditionalData { diff --git a/crates/router/tests/connectors/utils.rs b/crates/router/tests/connectors/utils.rs index 16e1d6a7c22c..9b7d62b11e97 100644 --- a/crates/router/tests/connectors/utils.rs +++ b/crates/router/tests/connectors/utils.rs @@ -1092,6 +1092,7 @@ pub fn get_connector_metadata( connector_response_reference_id: _, incremental_authorization_allowed: _, charge_id: _, + connector_customer_id: _, }) => connector_metadata, _ => None, }