Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions api-reference-v2/openapi_spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -3775,6 +3775,17 @@
},
"additionalProperties": false
},
"AdyenConnectorMetadata": {
"type": "object",
"required": [
"testing"
],
"properties": {
"testing": {
"$ref": "#/components/schemas/AdyenTestingData"
}
}
},
"AdyenSplitData": {
"type": "object",
"description": "Fee information for Split Payments to be charged on the payment being collected for Adyen",
Expand Down Expand Up @@ -3848,6 +3859,18 @@
"Vat"
]
},
"AdyenTestingData": {
"type": "object",
"required": [
"holder_name"
],
"properties": {
"holder_name": {
"type": "string",
"description": "Holder name to be sent to Adyen for a card payment(CIT) or a generic payment(MIT). This value overrides the values for card.card_holder_name and applies during both CIT and MIT payment transactions."
}
}
},
"AirwallexData": {
"type": "object",
"properties": {
Expand Down Expand Up @@ -7960,6 +7983,14 @@
}
],
"nullable": true
},
"adyen": {
"allOf": [
{
"$ref": "#/components/schemas/AdyenConnectorMetadata"
}
],
"nullable": true
}
}
},
Expand Down
31 changes: 31 additions & 0 deletions api-reference/openapi_spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -6069,6 +6069,17 @@
},
"additionalProperties": false
},
"AdyenConnectorMetadata": {
"type": "object",
"required": [
"testing"
],
"properties": {
"testing": {
"$ref": "#/components/schemas/AdyenTestingData"
}
}
},
"AdyenSplitData": {
"type": "object",
"description": "Fee information for Split Payments to be charged on the payment being collected for Adyen",
Expand Down Expand Up @@ -6142,6 +6153,18 @@
"Vat"
]
},
"AdyenTestingData": {
"type": "object",
"required": [
"holder_name"
],
"properties": {
"holder_name": {
"type": "string",
"description": "Holder name to be sent to Adyen for a card payment(CIT) or a generic payment(MIT). This value overrides the values for card.card_holder_name and applies during both CIT and MIT payment transactions."
}
}
},
"AirwallexData": {
"type": "object",
"properties": {
Expand Down Expand Up @@ -10010,6 +10033,14 @@
}
],
"nullable": true
},
"adyen": {
"allOf": [
{
"$ref": "#/components/schemas/AdyenConnectorMetadata"
}
],
"nullable": true
}
}
},
Expand Down
13 changes: 13 additions & 0 deletions crates/api_models/src/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6720,6 +6720,7 @@ pub struct ConnectorMetadata {
pub airwallex: Option<AirwallexData>,
pub noon: Option<NoonData>,
pub braintree: Option<BraintreeData>,
pub adyen: Option<AdyenConnectorMetadata>,
}

impl ConnectorMetadata {
Expand Down Expand Up @@ -6770,6 +6771,18 @@ pub struct BraintreeData {
pub merchant_config_currency: Option<api_enums::Currency>,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)]
pub struct AdyenConnectorMetadata {
pub testing: AdyenTestingData,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)]
pub struct AdyenTestingData {
/// Holder name to be sent to Adyen for a card payment(CIT) or a generic payment(MIT). This value overrides the values for card.card_holder_name and applies during both CIT and MIT payment transactions.
#[schema(value_type = String)]
pub holder_name: Option<Secret<String>>,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)]
pub struct ApplepayConnectorMetadataRequest {
pub session_token_data: Option<SessionTokenInfo>,
Expand Down
131 changes: 95 additions & 36 deletions crates/hyperswitch_connectors/src/connectors/adyen/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use common_enums::enums as storage_enums;
use common_utils::ext_traits::OptionExt;
use common_utils::{
errors::{CustomResult, ParsingError},
ext_traits::Encode,
ext_traits::{Encode, ValueExt},
pii::Email,
request::Method,
types::MinorUnit,
Expand Down Expand Up @@ -1222,6 +1222,7 @@ pub struct AdyenMandate {
#[serde(rename = "type")]
payment_type: PaymentType,
stored_payment_method_id: Secret<String>,
holder_name: Option<Secret<String>>,
}

#[serde_with::skip_serializing_none]
Expand Down Expand Up @@ -2008,13 +2009,21 @@ impl TryFrom<(&BankDebitData, &PaymentsAuthorizeRouterData)> for AdyenPaymentMet
account_number,
sort_code,
..
} => Ok(AdyenPaymentMethod::BacsDirectDebit(Box::new(
BacsDirectDebitData {
bank_account_number: account_number.clone(),
bank_location_id: sort_code.clone(),
holder_name: item.get_billing_full_name()?,
},
))),
} => {
let testing_data = item
.request
.get_connector_testing_data()
.map(AdyenTestingData::try_from)
.transpose()?;
let test_holder_name = testing_data.and_then(|test_data| test_data.holder_name);
Ok(AdyenPaymentMethod::BacsDirectDebit(Box::new(
BacsDirectDebitData {
bank_account_number: account_number.clone(),
bank_location_id: sort_code.clone(),
holder_name: test_holder_name.unwrap_or(item.get_billing_full_name()?),
},
)))
}

BankDebitData::BecsBankDebit { .. } => Err(errors::ConnectorError::NotImplemented(
utils::get_unimplemented_payment_method_error_message("Adyen"),
Expand Down Expand Up @@ -2396,30 +2405,38 @@ impl TryFrom<(&BankRedirectData, &PaymentsAuthorizeRouterData)> for AdyenPayment
card_exp_month,
card_exp_year,
..
} => Ok(AdyenPaymentMethod::BancontactCard(Box::new(AdyenCard {
brand: Some(CardBrand::Bcmc),
number: card_number
.as_ref()
.ok_or(errors::ConnectorError::MissingRequiredField {
field_name: "bancontact_card.card_number",
})?
.clone(),
expiry_month: card_exp_month
.as_ref()
.ok_or(errors::ConnectorError::MissingRequiredField {
field_name: "bancontact_card.card_exp_month",
})?
.clone(),
expiry_year: card_exp_year
.as_ref()
.ok_or(errors::ConnectorError::MissingRequiredField {
field_name: "bancontact_card.card_exp_year",
})?
.clone(),
holder_name: Some(item.get_billing_full_name()?),
cvc: None,
network_payment_reference: None,
}))),
} => {
let testing_data = item
.request
.get_connector_testing_data()
.map(AdyenTestingData::try_from)
.transpose()?;
let test_holder_name = testing_data.and_then(|test_data| test_data.holder_name);
Ok(AdyenPaymentMethod::BancontactCard(Box::new(AdyenCard {
brand: Some(CardBrand::Bcmc),
number: card_number
.as_ref()
.ok_or(errors::ConnectorError::MissingRequiredField {
field_name: "bancontact_card.card_number",
})?
.clone(),
expiry_month: card_exp_month
.as_ref()
.ok_or(errors::ConnectorError::MissingRequiredField {
field_name: "bancontact_card.card_exp_month",
})?
.clone(),
expiry_year: card_exp_year
.as_ref()
.ok_or(errors::ConnectorError::MissingRequiredField {
field_name: "bancontact_card.card_exp_year",
})?
.clone(),
holder_name: test_holder_name.or(Some(item.get_billing_full_name()?)),
cvc: None,
network_payment_reference: None,
})))
}
BankRedirectData::Bizum { .. } => Ok(AdyenPaymentMethod::Bizum),
BankRedirectData::Blik { blik_code } => {
Ok(AdyenPaymentMethod::Blik(Box::new(BlikRedirectionData {
Expand Down Expand Up @@ -2684,6 +2701,13 @@ impl
let additional_data = get_additional_data(item.router_data);
let return_url = item.router_data.request.get_router_return_url()?;
let payment_method_type = item.router_data.request.payment_method_type;
let testing_data = item
.router_data
.request
.get_connector_testing_data()
.map(AdyenTestingData::try_from)
.transpose()?;
let test_holder_name = testing_data.and_then(|test_data| test_data.holder_name);
let payment_method = match mandate_ref_id {
payments::MandateReferenceId::ConnectorMandateId(connector_mandate_ids) => {
let adyen_mandate = AdyenMandate {
Expand All @@ -2696,6 +2720,7 @@ impl
.get_connector_mandate_id()
.ok_or_else(missing_field_err("mandate_id"))?,
),
holder_name: test_holder_name,
};
Ok::<PaymentMethod<'_>, Self::Error>(PaymentMethod::AdyenMandatePaymentMethod(
Box::new(adyen_mandate),
Expand Down Expand Up @@ -2727,7 +2752,7 @@ impl
.get_expiry_year_4_digit()
.clone(),
cvc: None,
holder_name: card_holder_name,
holder_name: test_holder_name.or(card_holder_name),
brand: Some(brand),
network_payment_reference: Some(Secret::new(network_mandate_id)),
};
Expand Down Expand Up @@ -2768,7 +2793,7 @@ impl
number: token_data.get_network_token(),
expiry_month: token_data.get_network_token_expiry_month(),
expiry_year: token_data.get_expiry_year_4_digit(),
holder_name: card_holder_name,
holder_name: test_holder_name.or(card_holder_name),
brand: Some(brand), // FIXME: Remove hardcoding
network_payment_reference: Some(Secret::new(
network_mandate_id.network_transaction_id,
Expand Down Expand Up @@ -2879,7 +2904,15 @@ impl TryFrom<(&AdyenRouterData<&PaymentsAuthorizeRouterData>, &Card)> for AdyenP
let country_code = get_country_code(item.router_data.get_optional_billing());
let additional_data = get_additional_data(item.router_data);
let return_url = item.router_data.request.get_router_return_url()?;
let card_holder_name = item.router_data.get_optional_billing_full_name();
let testing_data = item
.router_data
.request
.get_connector_testing_data()
.map(AdyenTestingData::try_from)
.transpose()?;
let test_holder_name = testing_data.and_then(|test_data| test_data.holder_name);
let card_holder_name =
test_holder_name.or(item.router_data.get_optional_billing_full_name());
let payment_method = PaymentMethod::AdyenPaymentMethod(Box::new(
AdyenPaymentMethod::try_from((card_data, card_holder_name))?,
));
Expand Down Expand Up @@ -5505,6 +5538,24 @@ pub struct DefenseDocuments {
defense_document_type_code: String,
}

#[derive(Debug, Deserialize)]
pub struct AdyenTestingData {
holder_name: Option<Secret<String>>,
}

impl TryFrom<common_utils::pii::SecretSerdeValue> for AdyenTestingData {
type Error = error_stack::Report<errors::ConnectorError>;
fn try_from(testing_data: common_utils::pii::SecretSerdeValue) -> Result<Self, Self::Error> {
let testing_data = testing_data
.expose()
.parse_value::<Self>("AdyenTestingData")
.change_context(errors::ConnectorError::InvalidDataFormat {
field_name: "connector_metadata.adyen.testing",
})?;
Ok(testing_data)
}
}

impl TryFrom<&SubmitEvidenceRouterData> for Evidence {
type Error = error_stack::Report<errors::ConnectorError>;
fn try_from(item: &SubmitEvidenceRouterData) -> Result<Self, Self::Error> {
Expand Down Expand Up @@ -5782,7 +5833,15 @@ impl
let country_code = get_country_code(item.router_data.get_optional_billing());
let additional_data = get_additional_data(item.router_data);
let return_url = item.router_data.request.get_router_return_url()?;
let card_holder_name = item.router_data.get_optional_billing_full_name();
let testing_data = item
.router_data
.request
.get_connector_testing_data()
.map(AdyenTestingData::try_from)
.transpose()?;
let test_holder_name = testing_data.and_then(|test_data| test_data.holder_name);
let card_holder_name =
test_holder_name.or(item.router_data.get_optional_billing_full_name());
let payment_method = PaymentMethod::AdyenPaymentMethod(Box::new(
AdyenPaymentMethod::try_from((token_data, card_holder_name))?,
));
Expand Down
5 changes: 5 additions & 0 deletions crates/hyperswitch_connectors/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1685,6 +1685,7 @@ pub trait PaymentsAuthorizeRequestData {
fn get_card_network_from_additional_payment_method_data(
&self,
) -> Result<enums::CardNetwork, Error>;
fn get_connector_testing_data(&self) -> Option<pii::SecretSerdeValue>;
}

impl PaymentsAuthorizeRequestData for PaymentsAuthorizeData {
Expand Down Expand Up @@ -1905,6 +1906,9 @@ impl PaymentsAuthorizeRequestData for PaymentsAuthorizeData {
.into()),
}
}
fn get_connector_testing_data(&self) -> Option<pii::SecretSerdeValue> {
self.connector_testing_data.clone()
}
}

pub trait PaymentsCaptureRequestData {
Expand Down Expand Up @@ -5998,6 +6002,7 @@ pub(crate) fn convert_setup_mandate_router_data_to_authorize_router_data(
shipping_cost: data.request.shipping_cost,
merchant_account_id: None,
merchant_config_currency: None,
connector_testing_data: data.request.connector_testing_data.clone(),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ pub struct PaymentsAuthorizeData {
pub additional_payment_method_data: Option<AdditionalPaymentData>,
pub merchant_account_id: Option<Secret<String>>,
pub merchant_config_currency: Option<storage_enums::Currency>,
pub connector_testing_data: Option<pii::SecretSerdeValue>,
}
#[derive(Debug, Clone)]
pub struct PaymentsPostSessionTokensData {
Expand Down Expand Up @@ -935,4 +936,5 @@ pub struct SetupMandateRequestData {
// MinorUnit for amount framework
pub minor_amount: Option<MinorUnit>,
pub shipping_cost: Option<MinorUnit>,
pub connector_testing_data: Option<pii::SecretSerdeValue>,
}
2 changes: 2 additions & 0 deletions crates/openapi/src/openapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,8 @@ Never share your secret api keys. Keep them guarded and secure.
api_models::payments::PaymentsUpdateMetadataRequest,
api_models::payments::PaymentsUpdateMetadataResponse,
api_models::payments::CtpServiceDetails,
api_models::payments::AdyenConnectorMetadata,
api_models::payments::AdyenTestingData,
api_models::feature_matrix::FeatureMatrixListResponse,
api_models::feature_matrix::FeatureMatrixRequest,
api_models::feature_matrix::ConnectorFeatureMatrixResponse,
Expand Down
2 changes: 2 additions & 0 deletions crates/openapi/src/openapi_v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,8 @@ Never share your secret api keys. Keep them guarded and secure.
api_models::payments::DisplayAmountOnSdk,
api_models::payments::ErrorDetails,
api_models::payments::CtpServiceDetails,
api_models::payments::AdyenConnectorMetadata,
api_models::payments::AdyenTestingData,
api_models::feature_matrix::FeatureMatrixListResponse,
api_models::feature_matrix::FeatureMatrixRequest,
api_models::feature_matrix::ConnectorFeatureMatrixResponse,
Expand Down
Loading
Loading