Skip to content

Commit

Permalink
feat(pm_list): add required fields for sofort (#3192)
Browse files Browse the repository at this point in the history
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
Co-authored-by: Prasunna Soppa <[email protected]>
  • Loading branch information
3 people authored Jan 30, 2024
1 parent 87191d6 commit 3d55e3b
Show file tree
Hide file tree
Showing 11 changed files with 381 additions and 65 deletions.
15 changes: 8 additions & 7 deletions config/config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -374,13 +374,14 @@ slack_invite_url = "https://www.example.com/" # Slack invite url for hyperswit
discord_invite_url = "https://www.example.com/" # Discord invite url for hyperswitch

[mandates.supported_payment_methods]
card.credit = { connector_list = "stripe,adyen,cybersource" } # Mandate supported payment method type and connector for card
wallet.paypal = { connector_list = "adyen" } # Mandate supported payment method type and connector for wallets
pay_later.klarna = { connector_list = "adyen" } # Mandate supported payment method type and connector for pay_later
bank_debit.ach = { connector_list = "gocardless" } # Mandate supported payment method type and connector for bank_debit
bank_debit.becs = { connector_list = "gocardless" } # Mandate supported payment method type and connector for bank_debit
bank_debit.sepa = { connector_list = "gocardless" } # Mandate supported payment method type and connector for bank_debit
bank_redirect.ideal = { connector_list = "stripe,adyen" } # Mandate supported payment method type and connector for bank_redirect
card.credit = { connector_list = "stripe,adyen,cybersource" } # Mandate supported payment method type and connector for card
wallet.paypal = { connector_list = "adyen" } # Mandate supported payment method type and connector for wallets
pay_later.klarna = { connector_list = "adyen" } # Mandate supported payment method type and connector for pay_later
bank_debit.ach = { connector_list = "gocardless" } # Mandate supported payment method type and connector for bank_debit
bank_debit.becs = { connector_list = "gocardless" } # Mandate supported payment method type and connector for bank_debit
bank_debit.sepa = { connector_list = "gocardless" } # Mandate supported payment method type and connector for bank_debit
bank_redirect.ideal = {connector_list = "stripe,adyen,globalpay"} # Mandate supported payment method type and connector for bank_redirect
bank_redirect.sofort = {connector_list = "stripe,adyen,globalpay"}


# Required fields info used while listing the payment_method_data
Expand Down
3 changes: 2 additions & 1 deletion config/development.toml
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,8 @@ card.debit = { connector_list = "stripe,adyen,authorizedotnet,cybersource,global
bank_debit.ach = { connector_list = "gocardless"}
bank_debit.becs = { connector_list = "gocardless"}
bank_debit.sepa = { connector_list = "gocardless"}
bank_redirect.ideal = {connector_list = "stripe,adyen"}
bank_redirect.ideal = {connector_list = "stripe,adyen,globalpay"}
bank_redirect.sofort = {connector_list = "stripe,adyen,globalpay"}

[connector_request_reference_id_config]
merchant_ids_send_payment_id_as_connector_request_id = []
Expand Down
3 changes: 2 additions & 1 deletion config/docker_compose.toml
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,8 @@ card.debit = {connector_list = "stripe,adyen,authorizedotnet,cybersource,globalp
bank_debit.ach = { connector_list = "gocardless"}
bank_debit.becs = { connector_list = "gocardless"}
bank_debit.sepa = { connector_list = "gocardless"}
bank_redirect.ideal = {connector_list = "stripe,adyen"}
bank_redirect.ideal = {connector_list = "stripe,adyen,globalpay"}
bank_redirect.sofort = {connector_list = "stripe,adyen,globalpay"}

[connector_customer]
connector_list = "gocardless,stax,stripe"
Expand Down
6 changes: 3 additions & 3 deletions crates/api_models/src/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1336,15 +1336,15 @@ pub enum BankRedirectData {
},
Sofort {
/// The billing details for bank redirection
billing_details: BankRedirectBilling,
billing_details: Option<BankRedirectBilling>,

/// The country for bank payment
#[schema(value_type = CountryAlpha2, example = "US")]
country: api_enums::CountryAlpha2,
country: Option<api_enums::CountryAlpha2>,

/// The preferred language
#[schema(example = "en")]
preferred_language: String,
preferred_language: Option<String>,
},
Trustly {
/// The country for bank payment
Expand Down
293 changes: 291 additions & 2 deletions crates/router/src/configs/defaults.rs

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion crates/router/src/connector/aci/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,11 @@ impl
api_models::payments::BankRedirectData::Sofort { country, .. } => {
Self::BankRedirect(Box::new(BankRedirectionPMData {
payment_brand: PaymentBrand::Sofortueberweisung,
bank_account_country: Some(country.to_owned()),
bank_account_country: Some(country.to_owned().ok_or(
errors::ConnectorError::MissingRequiredField {
field_name: "sofort.country",
},
)?),
bank_account_bank_name: None,
bank_account_bic: None,
bank_account_iban: None,
Expand Down
5 changes: 1 addition & 4 deletions crates/router/src/connector/adyen/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2715,10 +2715,7 @@ fn get_redirect_extra_details(
country,
preferred_language,
..
} => Ok((
Some(preferred_language.to_string()),
Some(country.to_owned()),
)),
} => Ok((preferred_language.clone(), *country)),
api_models::payments::BankRedirectData::OpenBankingUk { country, .. } => {
let country = country.ok_or(errors::ConnectorError::MissingRequiredField {
field_name: "country",
Expand Down
11 changes: 9 additions & 2 deletions crates/router/src/connector/paypal/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -360,8 +360,15 @@ fn get_payment_source(
preferred_language: _,
billing_details,
} => Ok(PaymentSourceItem::Sofort(RedirectRequest {
name: billing_details.get_billing_name()?,
country_code: *country,
name: billing_details
.clone()
.ok_or(errors::ConnectorError::MissingRequiredField {
field_name: "sofort.billing_details",
})?
.get_billing_name()?,
country_code: country.ok_or(errors::ConnectorError::MissingRequiredField {
field_name: "sofort.country",
})?,
experience_context: ContextStruct {
return_url: item.request.complete_authorize_url.clone(),
cancel_url: item.request.complete_authorize_url.clone(),
Expand Down
87 changes: 49 additions & 38 deletions crates/router/src/connector/stripe/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ pub struct StripeSofort {
#[serde(rename = "payment_method_data[type]")]
pub payment_method_data_type: StripePaymentMethodType,
#[serde(rename = "payment_method_options[sofort][preferred_language]")]
preferred_language: String,
preferred_language: Option<String>,
#[serde(rename = "payment_method_data[sofort][country]")]
country: api_enums::CountryAlpha2,
}
Expand Down Expand Up @@ -1115,36 +1115,10 @@ impl TryFrom<(&payments::BankRedirectData, Option<bool>)> for StripeBillingAddre
}),
payments::BankRedirectData::Ideal {
billing_details, ..
} => {
let billing_name = billing_details
.clone()
.and_then(|billing_data| billing_data.billing_name.clone());

let billing_email = billing_details
.clone()
.and_then(|billing_data| billing_data.email.clone());
match is_customer_initiated_mandate_payment {
Some(true) => Ok(Self {
name: Some(billing_name.ok_or(
errors::ConnectorError::MissingRequiredField {
field_name: "billing_name",
},
)?),

email: Some(billing_email.ok_or(
errors::ConnectorError::MissingRequiredField {
field_name: "billing_email",
},
)?),
..Self::default()
}),
Some(false) | None => Ok(Self {
name: billing_name,
email: billing_email,
..Self::default()
}),
}
}
} => Ok(get_stripe_sepa_dd_mandate_billing_details(
billing_details,
is_customer_initiated_mandate_payment,
)?),
payments::BankRedirectData::Przelewy24 {
billing_details, ..
} => Ok(Self {
Expand Down Expand Up @@ -1183,11 +1157,11 @@ impl TryFrom<(&payments::BankRedirectData, Option<bool>)> for StripeBillingAddre
}
payments::BankRedirectData::Sofort {
billing_details, ..
} => Ok(Self {
name: billing_details.billing_name.clone(),
email: billing_details.email.clone(),
..Self::default()
}),
} => Ok(get_stripe_sepa_dd_mandate_billing_details(
billing_details,
is_customer_initiated_mandate_payment,
)?),

payments::BankRedirectData::Bizum {}
| payments::BankRedirectData::Blik { .. }
| payments::BankRedirectData::Interac { .. }
Expand Down Expand Up @@ -1674,8 +1648,10 @@ impl TryFrom<&payments::BankRedirectData> for StripePaymentMethodData {
} => Ok(Self::BankRedirect(StripeBankRedirectData::StripeSofort(
Box::new(StripeSofort {
payment_method_data_type,
country: country.to_owned(),
preferred_language: preferred_language.to_owned(),
country: country.ok_or(errors::ConnectorError::MissingRequiredField {
field_name: "sofort.country",
})?,
preferred_language: preferred_language.clone(),
}),
))),
payments::BankRedirectData::OnlineBankingFpx { .. } => {
Expand Down Expand Up @@ -3593,6 +3569,41 @@ pub struct Evidence {
pub submit: bool,
}

// Mandates for bank redirects - ideal and sofort happens through sepa direct debit in stripe
fn get_stripe_sepa_dd_mandate_billing_details(
billing_details: &Option<payments::BankRedirectBilling>,
is_customer_initiated_mandate_payment: Option<bool>,
) -> Result<StripeBillingAddress, errors::ConnectorError> {
let billing_name = billing_details
.clone()
.and_then(|billing_data| billing_data.billing_name.clone());

let billing_email = billing_details
.clone()
.and_then(|billing_data| billing_data.email.clone());
match is_customer_initiated_mandate_payment {
Some(true) => Ok(StripeBillingAddress {
name: Some(
billing_name.ok_or(errors::ConnectorError::MissingRequiredField {
field_name: "billing_name",
})?,
),

email: Some(
billing_email.ok_or(errors::ConnectorError::MissingRequiredField {
field_name: "billing_email",
})?,
),
..StripeBillingAddress::default()
}),
Some(false) | None => Ok(StripeBillingAddress {
name: billing_name,
email: billing_email,
..StripeBillingAddress::default()
}),
}
}

impl TryFrom<&types::SubmitEvidenceRouterData> for Evidence {
type Error = error_stack::Report<errors::ConnectorError>;
fn try_from(item: &types::SubmitEvidenceRouterData) -> Result<Self, Self::Error> {
Expand Down
3 changes: 2 additions & 1 deletion loadtest/config/development.toml
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,8 @@ card.debit = {connector_list = "stripe,adyen,authorizedotnet,cybersource,globalp
bank_debit.ach = { connector_list = "gocardless"}
bank_debit.becs = { connector_list = "gocardless"}
bank_debit.sepa = { connector_list = "gocardless"}
bank_redirect.ideal = {connector_list = "stripe,adyen"}
bank_redirect.ideal = {connector_list = "stripe,adyen,globalpay"}
bank_redirect.sofort = {connector_list = "stripe,adyen,globalpay"}

[analytics]
source = "sqlx"
Expand Down
14 changes: 9 additions & 5 deletions openapi/openapi_spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -5367,21 +5367,25 @@
"sofort": {
"type": "object",
"required": [
"billing_details",
"country",
"preferred_language"
"country"
],
"properties": {
"billing_details": {
"$ref": "#/components/schemas/BankRedirectBilling"
"allOf": [
{
"$ref": "#/components/schemas/BankRedirectBilling"
}
],
"nullable": true
},
"country": {
"$ref": "#/components/schemas/CountryAlpha2"
},
"preferred_language": {
"type": "string",
"description": "The preferred language",
"example": "en"
"example": "en",
"nullable": true
}
}
}
Expand Down

0 comments on commit 3d55e3b

Please sign in to comment.