feat(pm_list): add required fields for sofort (#3192)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
Co-authored-by: Prasunna Soppa <70575890+prasunna09@users.noreply.github.com>
This commit is contained in:
AkshayaFoiger
2024-01-30 14:26:55 +05:30
committed by GitHub
parent 87191d687c
commit 3d55e3ba45
11 changed files with 381 additions and 65 deletions

View File

@ -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

View File

@ -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 = []

View File

@ -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"

View File

@ -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

View File

@ -4750,14 +4750,303 @@ impl Default for super::settings::RequiredFields {
ConnectorFields {
fields: HashMap::from([
(
enums::Connector::Stripe,
enums::Connector::Aci,
RequiredFieldFinal {
mandate: HashMap::new(),
non_mandate: HashMap::from([
("payment_method_data.bank_redirect.sofort.country".to_string(),
RequiredFieldInfo {
required_field: "payment_method_data.bank_redirect.sofort.country".to_string(),
display_name: "country".to_string(),
field_type: enums::FieldType::UserCountry {
options: vec![
"ES".to_string(),
"GB".to_string(),
"SE".to_string(),
"AT".to_string(),
"NL".to_string(),
"DE".to_string(),
"CH".to_string(),
"BE".to_string(),
"FR".to_string(),
"FI".to_string(),
"IT".to_string(),
"PL".to_string(),
]
},
value: None,
}
)
]),
common: HashMap::new(),
}
),
(
enums::Connector::Adyen,
RequiredFieldFinal {
mandate: HashMap::new(),
non_mandate: HashMap::new(),
common: HashMap::new(),
}
),
]),
(
enums::Connector::Globalpay,
RequiredFieldFinal {
mandate: HashMap::new(),
non_mandate: HashMap::new(),
common: HashMap::from([
("billing.address.country".to_string(),
RequiredFieldInfo {
required_field: "billing.address.country".to_string(),
display_name: "country".to_string(),
field_type: enums::FieldType::UserAddressCountry {
options: vec![
"AT".to_string(),
"BE".to_string(),
"DE".to_string(),
"ES".to_string(),
"IT".to_string(),
"NL".to_string(),
]
},
value: None,
}
)
]),
}
),
(
enums::Connector::Mollie,
RequiredFieldFinal {
mandate: HashMap::new(),
non_mandate: HashMap::new(),
common: HashMap::new(),
}
),
(
enums::Connector::Nexinets,
RequiredFieldFinal {
mandate: HashMap::new(),
non_mandate: HashMap::new(),
common: HashMap::new(),
}
),
(
enums::Connector::Nuvei,
RequiredFieldFinal {
mandate: HashMap::new(),
non_mandate:HashMap::from([
(
"email".to_string(),
RequiredFieldInfo {
required_field: "email".to_string(),
display_name: "email".to_string(),
field_type: enums::FieldType::UserEmailAddress,
value: None,
}
),
(
"billing.address.first_name".to_string(),
RequiredFieldInfo {
required_field: "billing.address.first_name".to_string(),
display_name: "billing_first_name".to_string(),
field_type: enums::FieldType::UserBillingName,
value: None,
}
),
(
"billing.address.last_name".to_string(),
RequiredFieldInfo {
required_field: "billing.address.last_name".to_string(),
display_name: "billing_last_name".to_string(),
field_type: enums::FieldType::UserBillingName,
value: None,
}
),
(
"billing.address.country".to_string(),
RequiredFieldInfo {
required_field: "billing.address.country".to_string(),
display_name: "country".to_string(),
field_type: enums::FieldType::UserAddressCountry{
options: vec![
"ES".to_string(),
"GB".to_string(),
"IT".to_string(),
"DE".to_string(),
"FR".to_string(),
"AT".to_string(),
"BE".to_string(),
"NL".to_string(),
"BE".to_string(),
"SK".to_string(),
]
},
value: None,
}
)]
),
common: HashMap::new(),
}
),
(
enums::Connector::Paypal,
RequiredFieldFinal {
mandate: HashMap::new(),
non_mandate: HashMap::from([
("payment_method_data.bank_redirect.sofort.country".to_string(),
RequiredFieldInfo {
required_field: "payment_method_data.bank_redirect.sofort.country".to_string(),
display_name: "country".to_string(),
field_type: enums::FieldType::UserCountry {
options: vec![
"ES".to_string(),
"GB".to_string(),
"AT".to_string(),
"NL".to_string(),
"DE".to_string(),
"BE".to_string(),
]
},
value: None,
}
),
(
"payment_method_data.bank_redirect.sofort.billing_details.billing_name".to_string(),
RequiredFieldInfo {
required_field: "payment_method_data.bank_redirect.sofort.billing_details.billing_name".to_string(),
display_name: "billing_name".to_string(),
field_type: enums::FieldType::UserBillingName,
value: None,
}
)
]),
common: HashMap::new(),
}
),
(
enums::Connector::Shift4,
RequiredFieldFinal {
mandate: HashMap::new(),
non_mandate: HashMap::new(),
common: HashMap::new(),
}
),
(
enums::Connector::Stripe,
RequiredFieldFinal {
mandate: HashMap::from([
(
"payment_method_data.bank_redirect.sofort.billing_details.email".to_string(),
RequiredFieldInfo {
required_field: "payment_method_data.bank_redirect.sofort.billing_details.email".to_string(),
display_name: "email".to_string(),
field_type: enums::FieldType::UserEmailAddress,
value: None,
}
),
(
"payment_method_data.bank_redirect.sofort.billing_details.billing_name".to_string(),
RequiredFieldInfo {
required_field: "payment_method_data.bank_redirect.sofort.billing_details.billing_name".to_string(),
display_name: "billing_name".to_string(),
field_type: enums::FieldType::UserBillingName,
value: None,
}
)
]),
non_mandate : HashMap::from([
("payment_method_data.bank_redirect.sofort.country".to_string(),
RequiredFieldInfo {
required_field: "payment_method_data.bank_redirect.sofort.country".to_string(),
display_name: "country".to_string(),
field_type: enums::FieldType::UserCountry {
options: vec![
"ES".to_string(),
"AT".to_string(),
"NL".to_string(),
"DE".to_string(),
"BE".to_string(),
]
},
value: None,
}
)]),
common: HashMap::new(
),
}
),
(
enums::Connector::Trustpay,
RequiredFieldFinal {
mandate: HashMap::new(),
non_mandate: HashMap::from([
(
"billing.address.first_name".to_string(),
RequiredFieldInfo {
required_field: "billing.address.first_name".to_string(),
display_name: "billing_first_name".to_string(),
field_type: enums::FieldType::UserBillingName,
value: None,
}
),
(
"billing.address.line1".to_string(),
RequiredFieldInfo {
required_field: "billing.address.line1".to_string(),
display_name: "line1".to_string(),
field_type: enums::FieldType::UserAddressLine1,
value: None,
}
),
(
"billing.address.city".to_string(),
RequiredFieldInfo {
required_field: "billing.address.city".to_string(),
display_name: "city".to_string(),
field_type: enums::FieldType::UserAddressCity,
value: None,
}
),
(
"billing.address.zip".to_string(),
RequiredFieldInfo {
required_field: "billing.address.zip".to_string(),
display_name: "zip".to_string(),
field_type: enums::FieldType::UserAddressPincode,
value: None,
}
),
(
"billing.address.country".to_string(),
RequiredFieldInfo {
required_field: "billing.address.country".to_string(),
display_name: "country".to_string(),
field_type: enums::FieldType::UserAddressCountry {
options: vec![
"ES".to_string(),
"GB".to_string(),
"SE".to_string(),
"AT".to_string(),
"NL".to_string(),
"DE".to_string(),
"CH".to_string(),
"BE".to_string(),
"FR".to_string(),
"FI".to_string(),
"IT".to_string(),
"PL".to_string(),
]
},
value: None,
}
),
]),
common: HashMap::new(),
}
),
]),
},
),
(

View File

@ -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,

View File

@ -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",

View File

@ -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(),

View File

@ -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,
}
@ -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 {
@ -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 { .. }
@ -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 { .. } => {
@ -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> {

View File

@ -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"

View File

@ -5367,13 +5367,16 @@
"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"
@ -5381,7 +5384,8 @@
"preferred_language": {
"type": "string",
"description": "The preferred language",
"example": "en"
"example": "en",
"nullable": true
}
}
}