Skip to content

Commit

Permalink
feat(business_profile): feature add a config to use billing as `pay…
Browse files Browse the repository at this point in the history
…ment_method_billing` (#4557)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
  • Loading branch information
Narayanbhat166 and hyperswitch-bot[bot] committed May 8, 2024
1 parent 9e2d76b commit 3e1c7eb
Show file tree
Hide file tree
Showing 46 changed files with 108 additions and 20 deletions.
9 changes: 9 additions & 0 deletions crates/api_models/src/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -913,6 +913,9 @@ pub struct BusinessProfileCreate {

/// External 3DS authentication details
pub authentication_connector_details: Option<AuthenticationConnectorDetails>,

/// Whether to use the billing details passed when creating the intent as payment method billing
pub use_billing_as_payment_method_billing: Option<bool>,
}

#[derive(Clone, Debug, ToSchema, Serialize)]
Expand Down Expand Up @@ -982,6 +985,9 @@ pub struct BusinessProfileResponse {

/// External 3DS authentication details
pub authentication_connector_details: Option<AuthenticationConnectorDetails>,

// Whether to use the billing details passed when creating the intent as payment method billing
pub use_billing_as_payment_method_billing: Option<bool>,
}

#[derive(Clone, Debug, Deserialize, ToSchema, Serialize)]
Expand Down Expand Up @@ -1046,6 +1052,9 @@ pub struct BusinessProfileUpdate {

/// Merchant's config to support extended card info feature
pub extended_card_info_config: Option<ExtendedCardInfoConfig>,

// Whether to use the billing details passed when creating the intent as payment method billing
pub use_billing_as_payment_method_billing: Option<bool>,
}

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, PartialEq, ToSchema)]
Expand Down
9 changes: 9 additions & 0 deletions crates/diesel_models/src/business_profile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub struct BusinessProfile {
pub is_extended_card_info_enabled: Option<bool>,
pub extended_card_info_config: Option<pii::SecretSerdeValue>,
pub is_connector_agnostic_mit_enabled: Option<bool>,
pub use_billing_as_payment_method_billing: Option<bool>,
}

#[derive(Clone, Debug, Insertable, router_derive::DebugAsDisplay)]
Expand Down Expand Up @@ -67,6 +68,7 @@ pub struct BusinessProfileNew {
pub is_extended_card_info_enabled: Option<bool>,
pub extended_card_info_config: Option<pii::SecretSerdeValue>,
pub is_connector_agnostic_mit_enabled: Option<bool>,
pub use_billing_as_payment_method_billing: Option<bool>,
}

#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)]
Expand All @@ -93,6 +95,7 @@ pub struct BusinessProfileUpdateInternal {
pub is_extended_card_info_enabled: Option<bool>,
pub extended_card_info_config: Option<pii::SecretSerdeValue>,
pub is_connector_agnostic_mit_enabled: Option<bool>,
pub use_billing_as_payment_method_billing: Option<bool>,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
Expand All @@ -116,6 +119,7 @@ pub enum BusinessProfileUpdate {
session_expiry: Option<i64>,
authentication_connector_details: Option<serde_json::Value>,
extended_card_info_config: Option<pii::SecretSerdeValue>,
use_billing_as_payment_method_billing: Option<bool>,
},
ExtendedCardInfoUpdate {
is_extended_card_info_enabled: Option<bool>,
Expand Down Expand Up @@ -147,6 +151,7 @@ impl From<BusinessProfileUpdate> for BusinessProfileUpdateInternal {
session_expiry,
authentication_connector_details,
extended_card_info_config,
use_billing_as_payment_method_billing,
} => Self {
profile_name,
modified_at,
Expand All @@ -166,6 +171,7 @@ impl From<BusinessProfileUpdate> for BusinessProfileUpdateInternal {
session_expiry,
authentication_connector_details,
extended_card_info_config,
use_billing_as_payment_method_billing,
..Default::default()
},
BusinessProfileUpdate::ExtendedCardInfoUpdate {
Expand Down Expand Up @@ -210,6 +216,7 @@ impl From<BusinessProfileNew> for BusinessProfile {
is_connector_agnostic_mit_enabled: new.is_connector_agnostic_mit_enabled,
is_extended_card_info_enabled: new.is_extended_card_info_enabled,
extended_card_info_config: new.extended_card_info_config,
use_billing_as_payment_method_billing: new.use_billing_as_payment_method_billing,
}
}
}
Expand Down Expand Up @@ -237,6 +244,7 @@ impl BusinessProfileUpdate {
is_extended_card_info_enabled,
extended_card_info_config,
is_connector_agnostic_mit_enabled,
use_billing_as_payment_method_billing,
} = self.into();
BusinessProfile {
profile_name: profile_name.unwrap_or(source.profile_name),
Expand All @@ -261,6 +269,7 @@ impl BusinessProfileUpdate {
is_extended_card_info_enabled,
is_connector_agnostic_mit_enabled,
extended_card_info_config,
use_billing_as_payment_method_billing,
..source
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/diesel_models/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ diesel::table! {
is_extended_card_info_enabled -> Nullable<Bool>,
extended_card_info_config -> Nullable<Jsonb>,
is_connector_agnostic_mit_enabled -> Nullable<Bool>,
use_billing_as_payment_method_billing -> Nullable<Bool>,
}
}

Expand Down
2 changes: 2 additions & 0 deletions crates/router/src/core/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,7 @@ pub async fn update_business_profile_cascade(
session_expiry: None,
authentication_connector_details: None,
extended_card_info_config: None,
use_billing_as_payment_method_billing: None,
};

let update_futures = business_profiles.iter().map(|business_profile| async {
Expand Down Expand Up @@ -1691,6 +1692,7 @@ pub async fn update_business_profile(
field_name: "authentication_connector_details",
})?,
extended_card_info_config,
use_billing_as_payment_method_billing: request.use_billing_as_payment_method_billing,
};

let updated_business_profile = db
Expand Down
11 changes: 10 additions & 1 deletion crates/router/src/core/payment_methods/cards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2135,10 +2135,19 @@ pub async fn list_payment_methods(
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
}

// Check for `use_billing_as_payment_method_billing` config under business_profile
// If this is disabled, then the billing details in required fields will be empty and have to be collected by the customer
let billing_address_for_calculating_required_fields = business_profile
.as_ref()
.and_then(|business_profile| business_profile.use_billing_as_payment_method_billing)
.unwrap_or(true)
.then_some(billing_address.as_ref())
.flatten();

let req = api_models::payments::PaymentsRequest::foreign_from((
payment_attempt.as_ref(),
shipping_address.as_ref(),
billing_address.as_ref(),
billing_address_for_calculating_required_fields,
customer.as_ref(),
));
let req_val = serde_json::to_value(req).ok();
Expand Down
35 changes: 20 additions & 15 deletions crates/router/src/core/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2426,23 +2426,28 @@ pub mod payment_address {
shipping: Option<api::Address>,
billing: Option<api::Address>,
payment_method_billing: Option<api::Address>,
should_unify_address: Option<bool>,
) -> Self {
// billing -> .billing, this is the billing details passed in the root of payments request
// payment_method_billing -> .payment_method_data.billing

// Merge the billing details field from both `payment.billing` and `payment.payment_method_data.billing`
// The unified payment_method_billing will be used as billing address and passed to the connector module
// This unification is required in order to provide backwards compatibility
// so that if `payment.billing` is passed it should be sent to the connector module
// Unify the billing details with `payment_method_data.billing`
let unified_payment_method_billing = payment_method_billing
.as_ref()
.map(|payment_method_billing| {
payment_method_billing
.clone()
.unify_address(billing.as_ref())
})
.or(billing.clone());
// payment_method_billing -> payment_method_data.billing

let unified_payment_method_billing = if should_unify_address.unwrap_or(true) {
// Merge the billing details field from both `payment.billing` and `payment.payment_method_data.billing`
// The unified payment_method_billing will be used as billing address and passed to the connector module
// This unification is required in order to provide backwards compatibility
// so that if `payment.billing` is passed it should be sent to the connector module
// Unify the billing details with `payment_method_data.billing`
payment_method_billing
.as_ref()
.map(|payment_method_billing| {
payment_method_billing
.clone()
.unify_address(billing.as_ref())
})
.or(billing.clone())
} else {
payment_method_billing.clone()
};

Self {
shipping,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
shipping_address.as_ref().map(From::from),
billing_address.as_ref().map(From::from),
payment_method_billing.as_ref().map(From::from),
business_profile.use_billing_as_payment_method_billing,
),
confirm: None,
payment_method_data: None,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
shipping_address.as_ref().map(From::from),
billing_address.as_ref().map(From::from),
payment_method_billing.as_ref().map(From::from),
business_profile.use_billing_as_payment_method_billing,
),
confirm: None,
payment_method_data: None,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
shipping_address.as_ref().map(From::from),
billing_address.as_ref().map(From::from),
payment_method_billing.as_ref().map(From::from),
business_profile.use_billing_as_payment_method_billing,
),
confirm: None,
payment_method_data: None,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
shipping_address.as_ref().map(From::from),
billing_address.as_ref().map(From::from),
payment_method_billing.as_ref().map(From::from),
business_profile.use_billing_as_payment_method_billing,
),
confirm: request.confirm,
payment_method_data: request
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
shipping_address.as_ref().map(From::from),
billing_address.as_ref().map(From::from),
payment_method_billing.as_ref().map(From::from),
business_profile.use_billing_as_payment_method_billing,
),
token_data,
confirm: request.confirm,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
shipping_address.as_ref().map(From::from),
billing_address.as_ref().map(From::from),
payment_method_billing_address.as_ref().map(From::from),
business_profile.use_billing_as_payment_method_billing,
),
token_data: None,
confirm: request.confirm,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
shipping_address.as_ref().map(From::from),
billing_address.as_ref().map(From::from),
payment_method_billing.as_ref().map(From::from),
business_profile.use_billing_as_payment_method_billing,
),
token_data: None,
confirm: None,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
shipping_address.as_ref().map(From::from),
billing_address.as_ref().map(From::from),
payment_method_billing.as_ref().map(From::from),
business_profile.use_billing_as_payment_method_billing,
),
confirm: None,
payment_method_data: None,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
shipping_address.as_ref().map(From::from),
billing_address.as_ref().map(From::from),
payment_method_billing.as_ref().map(From::from),
business_profile.use_billing_as_payment_method_billing,
),
token_data,
confirm: Some(payment_attempt.confirm),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,7 @@ async fn get_tracker_for_sync<
shipping_address.as_ref().map(From::from),
billing_address.as_ref().map(From::from),
payment_method_billing.as_ref().map(From::from),
business_profile.use_billing_as_payment_method_billing,
),
token_data: None,
confirm: Some(request.force_sync),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
shipping_address.as_ref().map(From::from),
billing_address.as_ref().map(From::from),
payment_method_billing.as_ref().map(From::from),
business_profile.use_billing_as_payment_method_billing,
),
confirm: request.confirm,
payment_method_data: request
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve>
customer_acceptance: None,
token: None,
token_data: None,
address: PaymentAddress::new(None, None, None),
address: PaymentAddress::new(None, None, None, None),
confirm: None,
payment_method_data: None,
payment_method_info: None,
Expand Down
2 changes: 2 additions & 0 deletions crates/router/src/core/routing/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,9 @@ pub async fn update_business_profile_active_algorithm_ref(
session_expiry: None,
authentication_connector_details: None,
extended_card_info_config: None,
use_billing_as_payment_method_billing: None,
};

db.update_business_profile_by_profile_id(current_business_profile, business_profile_update)
.await
.change_context(errors::ApiErrorResponse::InternalServerError)
Expand Down
2 changes: 1 addition & 1 deletion crates/router/src/core/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ pub async fn construct_payout_router_data<'a, F>(
}
});

let address = PaymentAddress::new(None, billing_address, None);
let address = PaymentAddress::new(None, billing_address, None, None);

let test_mode: Option<bool> = merchant_connector_account.is_test_mode_on();
let payouts = &payout_data.payouts;
Expand Down
4 changes: 4 additions & 0 deletions crates/router/src/types/api/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ impl ForeignTryFrom<storage::business_profile::BusinessProfile> for BusinessProf
authentication_connector_details.parse_value("AuthenticationDetails")
})
.transpose()?,
use_billing_as_payment_method_billing: item.use_billing_as_payment_method_billing,
})
}
}
Expand Down Expand Up @@ -178,6 +179,9 @@ impl ForeignTryFrom<(domain::MerchantAccount, BusinessProfileCreate)>
is_connector_agnostic_mit_enabled: None,
is_extended_card_info_enabled: None,
extended_card_info_config: None,
use_billing_as_payment_method_billing: request
.use_billing_as_payment_method_billing
.or(Some(true)),
})
}
}
2 changes: 1 addition & 1 deletion crates/router/src/types/api/verify_connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ impl VerifyConnectorData {
recurring_mandate_payment_data: None,
payment_method_status: None,
connector_request_reference_id: attempt_id,
address: types::PaymentAddress::new(None, None, None),
address: types::PaymentAddress::new(None, None, None, None),
payment_id: common_utils::generate_id_with_default_len(
consts::VERIFY_CONNECTOR_ID_PREFIX,
),
Expand Down
1 change: 1 addition & 0 deletions crates/router/tests/connectors/aci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ fn construct_payment_router_data() -> types::PaymentsAuthorizeRouterData {
}),
email: None,
}),
None,
),
connector_meta_data: None,
amount_captured: None,
Expand Down
2 changes: 2 additions & 0 deletions crates/router/tests/connectors/adyen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ impl AdyenTest {
email: None,
}),
None,
None,
)),
..Default::default()
})
Expand Down Expand Up @@ -100,6 +101,7 @@ impl AdyenTest {
email: None,
}),
None,
None,
)),
payout_method_data: match payout_type {
enums::PayoutType::Card => Some(types::api::PayoutMethodData::Card(
Expand Down
1 change: 1 addition & 0 deletions crates/router/tests/connectors/airwallex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ fn get_default_payment_info() -> Option<utils::PaymentInfo> {
phone: None,
email: None,
}),
None,
)),
..Default::default()
})
Expand Down
1 change: 1 addition & 0 deletions crates/router/tests/connectors/bitpay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ fn get_default_payment_info() -> Option<utils::PaymentInfo> {
email: None,
}),
None,
None,
)),
..Default::default()
})
Expand Down
1 change: 1 addition & 0 deletions crates/router/tests/connectors/bluesnap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ fn get_payment_info() -> Option<PaymentInfo> {
email: None,
}),
None,
None,
)),
..Default::default()
})
Expand Down
1 change: 1 addition & 0 deletions crates/router/tests/connectors/cashtocode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ impl CashtocodeTest {
email: None,
}),
None,
None,
)),
return_url: Some("https://google.com".to_owned()),
..Default::default()
Expand Down
1 change: 1 addition & 0 deletions crates/router/tests/connectors/coinbase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ fn get_default_payment_info() -> Option<utils::PaymentInfo> {
email: None,
}),
None,
None,
)),
connector_meta_data: Some(json!({"pricing_type": "fixed_price"})),
..Default::default()
Expand Down

0 comments on commit 3e1c7eb

Please sign in to comment.