mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-28 04:04:55 +08:00
refactor(pm_list): modify pm list to support new api contract (#657)
Co-authored-by: Sangamesh <sangamesh.kulkarni@juspay.in>
This commit is contained in:
@ -5,7 +5,7 @@ use url;
|
|||||||
use utoipa::ToSchema;
|
use utoipa::ToSchema;
|
||||||
|
|
||||||
use super::payments::AddressDetails;
|
use super::payments::AddressDetails;
|
||||||
use crate::enums as api_enums;
|
use crate::{enums as api_enums, payment_methods};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, ToSchema)]
|
#[derive(Clone, Debug, Deserialize, ToSchema)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
@ -284,59 +284,23 @@ pub struct PaymentConnectorCreate {
|
|||||||
"installment_payment_enabled": true
|
"installment_payment_enabled": true
|
||||||
}
|
}
|
||||||
]))]
|
]))]
|
||||||
pub payment_methods_enabled: Option<Vec<PaymentMethods>>,
|
pub payment_methods_enabled: Option<Vec<PaymentMethodsEnabled>>,
|
||||||
/// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object.
|
/// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object.
|
||||||
#[schema(value_type = Option<Object>,max_length = 255,example = json!({ "city": "NY", "unit": "245" }))]
|
#[schema(value_type = Option<Object>,max_length = 255,example = json!({ "city": "NY", "unit": "245" }))]
|
||||||
pub metadata: Option<serde_json::Value>,
|
pub metadata: Option<serde_json::Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Details of all the payment methods enabled for the connector for the given merchant account
|
/// Details of all the payment methods enabled for the connector for the given merchant account
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct PaymentMethods {
|
pub struct PaymentMethodsEnabled {
|
||||||
/// Type of payment method.
|
/// Type of payment method.
|
||||||
#[schema(value_type = PaymentMethodType,example = "card")]
|
#[schema(value_type = PaymentMethod,example = "card")]
|
||||||
pub payment_method: api_enums::PaymentMethod,
|
pub payment_method: api_enums::PaymentMethod,
|
||||||
|
|
||||||
/// Subtype of payment method
|
/// Subtype of payment method
|
||||||
#[schema(value_type = Option<Vec<PaymentMethodSubType>>,example = json!(["credit"]))]
|
#[schema(value_type = Option<Vec<PaymentMethodType>>,example = json!(["credit"]))]
|
||||||
pub payment_method_types: Option<Vec<api_enums::PaymentMethodType>>,
|
pub payment_method_types: Option<Vec<payment_methods::RequestPaymentMethodTypes>>,
|
||||||
/// List of payment method issuers to be enabled for this payment method
|
|
||||||
#[schema(example = json!(["HDFC"]))]
|
|
||||||
pub payment_method_issuers: Option<Vec<String>>,
|
|
||||||
/// List of payment schemes accepted or has the processing capabilities of the processor
|
|
||||||
#[schema(example = json!(["MASTER","VISA","DINERS"]))]
|
|
||||||
pub payment_schemes: Option<Vec<String>>,
|
|
||||||
/// List of currencies accepted or has the processing capabilities of the processor
|
|
||||||
#[schema(example = json!(
|
|
||||||
{
|
|
||||||
"type": "enable_only",
|
|
||||||
"list": ["USD", "EUR"]
|
|
||||||
}
|
|
||||||
))]
|
|
||||||
pub accepted_currencies: Option<AcceptedCurrencies>,
|
|
||||||
/// List of Countries accepted or has the processing capabilities of the processor
|
|
||||||
#[schema(example = json!(
|
|
||||||
{
|
|
||||||
"type": "disable_only",
|
|
||||||
"list": ["FR", "DE","IN"]
|
|
||||||
}
|
|
||||||
))]
|
|
||||||
pub accepted_countries: Option<AcceptedCountries>,
|
|
||||||
/// Minimum amount supported by the processor. To be represented in the lowest denomination of the target currency (For example, for USD it should be in cents)
|
|
||||||
#[schema(example = 1)]
|
|
||||||
pub minimum_amount: Option<i32>,
|
|
||||||
/// Maximum amount supported by the processor. To be represented in the lowest denomination of
|
|
||||||
/// the target currency (For example, for USD it should be in cents)
|
|
||||||
#[schema(example = 1313)]
|
|
||||||
pub maximum_amount: Option<i32>,
|
|
||||||
/// Boolean to enable recurring payments / mandates. Default is true.
|
|
||||||
#[schema(default = true, example = false)]
|
|
||||||
pub recurring_enabled: bool,
|
|
||||||
/// Boolean to enable installment / EMI / BNPL payments. Default is true.
|
|
||||||
#[schema(default = true, example = false)]
|
|
||||||
pub installment_payment_enabled: bool,
|
|
||||||
/// Type of payment experience enabled with the connector
|
|
||||||
#[schema(value_type = Option<Vec<PaymentExperience>>,example = json!(["redirect_to_url"]))]
|
|
||||||
pub payment_experience: Option<Vec<api_enums::PaymentExperience>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List of enabled and disabled currencies, empty in case all currencies are enabled
|
/// List of enabled and disabled currencies, empty in case all currencies are enabled
|
||||||
|
|||||||
@ -344,36 +344,6 @@ pub enum PaymentMethodIssuerCode {
|
|||||||
JpBacs,
|
JpBacs,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(
|
|
||||||
Clone,
|
|
||||||
Copy,
|
|
||||||
Debug,
|
|
||||||
Eq,
|
|
||||||
Hash,
|
|
||||||
PartialEq,
|
|
||||||
serde::Deserialize,
|
|
||||||
serde::Serialize,
|
|
||||||
frunk::LabelledGeneric,
|
|
||||||
ToSchema,
|
|
||||||
)]
|
|
||||||
#[serde(rename_all = "snake_case")]
|
|
||||||
pub enum PaymentIssuer {
|
|
||||||
Klarna,
|
|
||||||
Affirm,
|
|
||||||
AfterpayClearpay,
|
|
||||||
AmericanExpress,
|
|
||||||
BankOfAmerica,
|
|
||||||
Barclays,
|
|
||||||
CapitalOne,
|
|
||||||
Chase,
|
|
||||||
Citi,
|
|
||||||
Discover,
|
|
||||||
NavyFederalCreditUnion,
|
|
||||||
PentagonFederalCreditUnion,
|
|
||||||
SynchronyBank,
|
|
||||||
WellsFargo,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Eq,
|
Eq,
|
||||||
PartialEq,
|
PartialEq,
|
||||||
@ -718,6 +688,25 @@ pub enum BankNames {
|
|||||||
VrBankBraunau,
|
VrBankBraunau,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Debug,
|
||||||
|
Eq,
|
||||||
|
Hash,
|
||||||
|
PartialEq,
|
||||||
|
serde::Deserialize,
|
||||||
|
serde::Serialize,
|
||||||
|
strum::Display,
|
||||||
|
strum::EnumString,
|
||||||
|
frunk::LabelledGeneric,
|
||||||
|
)]
|
||||||
|
#[strum(serialize_all = "snake_case")]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
pub enum CardNetwork {
|
||||||
|
Visa,
|
||||||
|
Mastercard,
|
||||||
|
}
|
||||||
|
|
||||||
impl From<AttemptStatus> for IntentStatus {
|
impl From<AttemptStatus> for IntentStatus {
|
||||||
fn from(s: AttemptStatus) -> Self {
|
fn from(s: AttemptStatus) -> Self {
|
||||||
match s {
|
match s {
|
||||||
|
|||||||
@ -100,14 +100,6 @@ pub struct PaymentMethodResponse {
|
|||||||
#[schema(value_type = Option<PaymentMethodType>,example = "credit")]
|
#[schema(value_type = Option<PaymentMethodType>,example = "credit")]
|
||||||
pub payment_method_type: Option<api_enums::PaymentMethodType>,
|
pub payment_method_type: Option<api_enums::PaymentMethodType>,
|
||||||
|
|
||||||
/// The name of the bank/ provider issuing the payment method to the end user
|
|
||||||
#[schema(example = "Citibank")]
|
|
||||||
pub payment_method_issuer: Option<String>,
|
|
||||||
|
|
||||||
/// A standard code representing the issuer of payment method
|
|
||||||
#[schema(value_type = Option<PaymentMethodIssuerCode>,example = "jp_applepay")]
|
|
||||||
pub payment_method_issuer_code: Option<api_enums::PaymentMethodIssuerCode>,
|
|
||||||
|
|
||||||
/// Card details from card locker
|
/// Card details from card locker
|
||||||
#[schema(example = json!({"last4": "1142","exp_month": "03","exp_year": "2030"}))]
|
#[schema(example = json!({"last4": "1142","exp_month": "03","exp_year": "2030"}))]
|
||||||
pub card: Option<CardDetailFromLocker>,
|
pub card: Option<CardDetailFromLocker>,
|
||||||
@ -159,6 +151,99 @@ pub struct CardDetailFromLocker {
|
|||||||
pub card_fingerprint: Option<masking::Secret<String>>,
|
pub card_fingerprint: Option<masking::Secret<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema, PartialEq, Eq)]
|
||||||
|
pub struct PaymentExperienceTypes {
|
||||||
|
pub payment_experience_type: api_enums::PaymentExperience,
|
||||||
|
pub eligible_connectors: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema, PartialEq, Eq)]
|
||||||
|
pub struct CardNetworkTypes {
|
||||||
|
pub card_network: api_enums::CardNetwork,
|
||||||
|
pub eligible_connectors: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema, PartialEq, Eq)]
|
||||||
|
pub struct ResponsePaymentMethodTypes {
|
||||||
|
pub payment_method_type: api_enums::PaymentMethodType,
|
||||||
|
pub payment_experience: Option<Vec<PaymentExperienceTypes>>,
|
||||||
|
pub card_networks: Option<Vec<CardNetworkTypes>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||||
|
pub struct ResponsePaymentMethodsEnabled {
|
||||||
|
pub payment_method: api_enums::PaymentMethod,
|
||||||
|
pub payment_method_types: Vec<ResponsePaymentMethodTypes>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ResponsePaymentMethodIntermediate {
|
||||||
|
pub payment_method_type: api_enums::PaymentMethodType,
|
||||||
|
pub payment_experience: Option<api_enums::PaymentExperience>,
|
||||||
|
pub card_networks: Option<Vec<api_enums::CardNetwork>>,
|
||||||
|
pub payment_method: api_enums::PaymentMethod,
|
||||||
|
pub connector: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ResponsePaymentMethodIntermediate {
|
||||||
|
pub fn new(
|
||||||
|
pm_type: RequestPaymentMethodTypes,
|
||||||
|
connector: String,
|
||||||
|
pm: api_enums::PaymentMethod,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
payment_method_type: pm_type.payment_method_type,
|
||||||
|
payment_experience: pm_type.payment_experience,
|
||||||
|
card_networks: pm_type.card_networks,
|
||||||
|
payment_method: pm,
|
||||||
|
connector,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema, PartialEq, Eq, Hash)]
|
||||||
|
pub struct RequestPaymentMethodTypes {
|
||||||
|
pub payment_method_type: api_enums::PaymentMethodType,
|
||||||
|
pub payment_experience: Option<api_enums::PaymentExperience>,
|
||||||
|
pub card_networks: Option<Vec<api_enums::CardNetwork>>,
|
||||||
|
/// List of currencies accepted or has the processing capabilities of the processor
|
||||||
|
#[schema(example = json!(
|
||||||
|
{
|
||||||
|
"enable_all":false,
|
||||||
|
"disable_only": ["INR", "CAD", "AED","JPY"],
|
||||||
|
"enable_only": ["EUR","USD"]
|
||||||
|
}
|
||||||
|
))]
|
||||||
|
pub accepted_currencies: Option<admin::AcceptedCurrencies>,
|
||||||
|
|
||||||
|
/// List of Countries accepted or has the processing capabilities of the processor
|
||||||
|
#[schema(example = json!(
|
||||||
|
{
|
||||||
|
"enable_all":false,
|
||||||
|
"disable_only": ["FR", "DE","IN"],
|
||||||
|
"enable_only": ["UK","AU"]
|
||||||
|
}
|
||||||
|
))]
|
||||||
|
pub accepted_countries: Option<admin::AcceptedCountries>,
|
||||||
|
|
||||||
|
/// Minimum amount supported by the processor. To be represented in the lowest denomination of the target currency (For example, for USD it should be in cents)
|
||||||
|
#[schema(example = 1)]
|
||||||
|
pub minimum_amount: Option<i32>,
|
||||||
|
|
||||||
|
/// Maximum amount supported by the processor. To be represented in the lowest denomination of
|
||||||
|
/// the target currency (For example, for USD it should be in cents)
|
||||||
|
#[schema(example = 1313)]
|
||||||
|
pub maximum_amount: Option<i32>,
|
||||||
|
|
||||||
|
/// Boolean to enable recurring payments / mandates. Default is true.
|
||||||
|
#[schema(default = true, example = false)]
|
||||||
|
pub recurring_enabled: bool,
|
||||||
|
|
||||||
|
/// Boolean to enable installment / EMI / BNPL payments. Default is true.
|
||||||
|
#[schema(default = true, example = false)]
|
||||||
|
pub installment_payment_enabled: bool,
|
||||||
|
}
|
||||||
|
|
||||||
//List Payment Method
|
//List Payment Method
|
||||||
#[derive(Debug, serde::Serialize, Default, ToSchema)]
|
#[derive(Debug, serde::Serialize, Default, ToSchema)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
@ -186,6 +271,10 @@ pub struct ListPaymentMethodRequest {
|
|||||||
/// Indicates whether the payment method is eligible for installment payments
|
/// Indicates whether the payment method is eligible for installment payments
|
||||||
#[schema(example = true)]
|
#[schema(example = true)]
|
||||||
pub installment_payment_enabled: Option<bool>,
|
pub installment_payment_enabled: Option<bool>,
|
||||||
|
|
||||||
|
/// Indicates whether the payment method is eligible for card netwotks
|
||||||
|
#[schema(value_type = Option<Vec<CardNetwork>>, example = json!(["visa", "mastercard"]))]
|
||||||
|
pub card_networks: Option<Vec<api_enums::CardNetwork>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de> serde::Deserialize<'de> for ListPaymentMethodRequest {
|
impl<'de> serde::Deserialize<'de> for ListPaymentMethodRequest {
|
||||||
@ -296,74 +385,34 @@ pub struct ListPaymentMethodResponse {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
))]
|
))]
|
||||||
pub payment_methods: Vec<ListPaymentMethod>,
|
pub payment_methods: Vec<ResponsePaymentMethodsEnabled>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// impl ResponsePaymentMethodTypes {
|
||||||
|
// pub fn new(
|
||||||
|
// pm_type: RequestPaymentMethodTypes,
|
||||||
|
// connector: String,
|
||||||
|
// payment_method: api_enums::PaymentMethod,
|
||||||
|
// ) -> Self {
|
||||||
|
// Self {
|
||||||
|
// payment_method_type: pm_type.payment_method_type,
|
||||||
|
// payment_experience: pm_type.payment_experience,
|
||||||
|
// connector,
|
||||||
|
// card_networks: pm_type.card_networks,
|
||||||
|
// payment_method,
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Hash, Debug, serde::Deserialize, ToSchema)]
|
#[derive(Eq, PartialEq, Hash, Debug, serde::Deserialize, ToSchema)]
|
||||||
pub struct ListPaymentMethod {
|
pub struct ListPaymentMethod {
|
||||||
/// The type of payment method use for the payment.
|
/// The type of payment method use for the payment.
|
||||||
#[schema(value_type = PaymentMethodType,example = "card")]
|
#[schema(value_type = PaymentMethod,example = "card")]
|
||||||
pub payment_method: api_enums::PaymentMethod,
|
pub payment_method: api_enums::PaymentMethod,
|
||||||
|
|
||||||
/// This is a sub-category of payment method.
|
/// This is a sub-category of payment method.
|
||||||
#[schema(value_type = Option<Vec<PaymentMethodSubType>>,example = json!(["credit_card"]))]
|
#[schema(value_type = Option<Vec<PaymentMethodType>>,example = json!(["credit"]))]
|
||||||
pub payment_method_types: Option<Vec<api_enums::PaymentMethodType>>,
|
pub payment_method_types: Option<Vec<RequestPaymentMethodTypes>>,
|
||||||
|
|
||||||
/// The name of the bank/ provider issuing the payment method to the end user
|
|
||||||
#[schema(example = json!(["Citibank"]))]
|
|
||||||
pub payment_method_issuers: Option<Vec<String>>,
|
|
||||||
|
|
||||||
/// A standard code representing the issuer of payment method
|
|
||||||
#[schema(value_type = Option<Vec<PaymentMethodIssuerCode>>,example = json!(["jp_applepay"]))]
|
|
||||||
pub payment_method_issuer_code: Option<Vec<api_enums::PaymentMethodIssuerCode>>,
|
|
||||||
|
|
||||||
/// List of payment schemes accepted or has the processing capabilities of the processor
|
|
||||||
#[schema(example = json!(["MASTER", "VISA", "DINERS"]))]
|
|
||||||
pub payment_schemes: Option<Vec<String>>,
|
|
||||||
|
|
||||||
/// List of Countries accepted or has the processing capabilities of the processor
|
|
||||||
#[schema(example = json!(
|
|
||||||
{
|
|
||||||
"type": "disable_only",
|
|
||||||
"list": ["FR", "DE","IN"]
|
|
||||||
}
|
|
||||||
))]
|
|
||||||
pub accepted_countries: Option<admin::AcceptedCountries>,
|
|
||||||
|
|
||||||
/// List of currencies accepted or has the processing capabilities of the processor
|
|
||||||
#[schema(example = json!(
|
|
||||||
{
|
|
||||||
"type": "enable_only",
|
|
||||||
"list": ["USD", "EUR"]
|
|
||||||
}
|
|
||||||
))]
|
|
||||||
pub accepted_currencies: Option<admin::AcceptedCurrencies>,
|
|
||||||
|
|
||||||
/// Minimum amount supported by the processor. To be represented in the lowest denomination of
|
|
||||||
/// the target currency (For example, for USD it should be in cents)
|
|
||||||
#[schema(example = 60000)]
|
|
||||||
pub minimum_amount: Option<i64>,
|
|
||||||
|
|
||||||
/// Maximum amount supported by the processor. To be represented in the lowest denomination of
|
|
||||||
/// the target currency (For example, for USD it should be in cents)
|
|
||||||
#[schema(example = 1)]
|
|
||||||
pub maximum_amount: Option<i64>,
|
|
||||||
|
|
||||||
/// Boolean to enable recurring payments / mandates. Default is true.
|
|
||||||
#[schema(example = true)]
|
|
||||||
pub recurring_enabled: bool,
|
|
||||||
|
|
||||||
/// Boolean to enable installment / EMI / BNPL payments. Default is true.
|
|
||||||
#[schema(example = true)]
|
|
||||||
pub installment_payment_enabled: bool,
|
|
||||||
|
|
||||||
/// Type of payment experience enabled with the connector
|
|
||||||
#[schema(value_type = Option<Vec<PaymentExperience>>, example = json!(["redirect_to_url"]))]
|
|
||||||
pub payment_experience: Option<Vec<api_enums::PaymentExperience>>,
|
|
||||||
|
|
||||||
/// Eligible connectors for this payment method
|
|
||||||
#[schema(example = json!(["stripe", "adyen"]))]
|
|
||||||
pub eligible_connectors: Option<Vec<String>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Currently if the payment method is Wallet or Paylater the relevant fields are `payment_method`
|
/// Currently if the payment method is Wallet or Paylater the relevant fields are `payment_method`
|
||||||
@ -377,18 +426,9 @@ impl serde::Serialize for ListPaymentMethod {
|
|||||||
use serde::ser::SerializeStruct;
|
use serde::ser::SerializeStruct;
|
||||||
let mut state = serializer.serialize_struct("ListPaymentMethod", 4)?;
|
let mut state = serializer.serialize_struct("ListPaymentMethod", 4)?;
|
||||||
state.serialize_field("payment_method", &self.payment_method)?;
|
state.serialize_field("payment_method", &self.payment_method)?;
|
||||||
state.serialize_field("payment_experience", &self.payment_experience)?;
|
|
||||||
state.serialize_field("eligible_connectors", &self.eligible_connectors)?;
|
state.serialize_field("payment_method_types", &self.payment_method_types)?;
|
||||||
match self.payment_method {
|
|
||||||
api_enums::PaymentMethod::Wallet | api_enums::PaymentMethod::PayLater => {
|
|
||||||
state.serialize_field("payment_method_issuers", &self.payment_method_issuers)?;
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
state.serialize_field("payment_method_issuers", &self.payment_method_issuers)?;
|
|
||||||
state.serialize_field("payment_method_types", &self.payment_method_types)?;
|
|
||||||
state.serialize_field("payment_schemes", &self.payment_schemes)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
state.end()
|
state.end()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -260,7 +260,7 @@ pub async fn create_payment_connector(
|
|||||||
let payment_methods_enabled = match req.payment_methods_enabled {
|
let payment_methods_enabled = match req.payment_methods_enabled {
|
||||||
Some(val) => {
|
Some(val) => {
|
||||||
for pm in val.into_iter() {
|
for pm in val.into_iter() {
|
||||||
let pm_value = utils::Encode::<api::PaymentMethods>::encode_to_value(&pm)
|
let pm_value = utils::Encode::<api::PaymentMethodsEnabled>::encode_to_value(&pm)
|
||||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||||
.attach_printable(
|
.attach_printable(
|
||||||
"Failed while encoding to serde_json::Value, PaymentMethod",
|
"Failed while encoding to serde_json::Value, PaymentMethod",
|
||||||
@ -345,7 +345,7 @@ pub async fn list_payment_connectors(
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
let merchant_connector_accounts = store
|
let merchant_connector_accounts = store
|
||||||
.find_merchant_connector_account_by_merchant_id_list(&merchant_id)
|
.find_merchant_connector_account_by_merchant_id_and_disabled_list(&merchant_id, true)
|
||||||
.await
|
.await
|
||||||
.map_err(|error| {
|
.map_err(|error| {
|
||||||
error.to_not_found_response(errors::ApiErrorResponse::MerchantConnectorAccountNotFound)
|
error.to_not_found_response(errors::ApiErrorResponse::MerchantConnectorAccountNotFound)
|
||||||
@ -387,7 +387,7 @@ pub async fn update_payment_connector(
|
|||||||
pm_enabled
|
pm_enabled
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|payment_method| {
|
.flat_map(|payment_method| {
|
||||||
utils::Encode::<api::PaymentMethods>::encode_to_value(payment_method)
|
utils::Encode::<api::PaymentMethodsEnabled>::encode_to_value(payment_method)
|
||||||
})
|
})
|
||||||
.collect::<Vec<serde_json::Value>>()
|
.collect::<Vec<serde_json::Value>>()
|
||||||
});
|
});
|
||||||
@ -415,12 +415,12 @@ pub async fn update_payment_connector(
|
|||||||
let updated_pm_enabled = updated_mca.payment_methods_enabled.map(|pm| {
|
let updated_pm_enabled = updated_mca.payment_methods_enabled.map(|pm| {
|
||||||
pm.into_iter()
|
pm.into_iter()
|
||||||
.flat_map(|pm_value| {
|
.flat_map(|pm_value| {
|
||||||
ValueExt::<api_models::admin::PaymentMethods>::parse_value(
|
ValueExt::<api_models::admin::PaymentMethodsEnabled>::parse_value(
|
||||||
pm_value,
|
pm_value,
|
||||||
"PaymentMethods",
|
"PaymentMethods",
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect::<Vec<api_models::admin::PaymentMethods>>()
|
.collect::<Vec<api_models::admin::PaymentMethodsEnabled>>()
|
||||||
});
|
});
|
||||||
|
|
||||||
let response = api::PaymentConnectorCreate {
|
let response = api::PaymentConnectorCreate {
|
||||||
|
|||||||
@ -1,6 +1,14 @@
|
|||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
use api_models::{admin, enums as api_enums};
|
use api_models::{
|
||||||
|
admin::{self, PaymentMethodsEnabled},
|
||||||
|
enums as api_enums,
|
||||||
|
payment_methods::{
|
||||||
|
CardNetworkTypes, PaymentExperienceTypes, RequestPaymentMethodTypes,
|
||||||
|
ResponsePaymentMethodIntermediate, ResponsePaymentMethodTypes,
|
||||||
|
ResponsePaymentMethodsEnabled,
|
||||||
|
},
|
||||||
|
};
|
||||||
use common_utils::{consts, ext_traits::AsyncExt, generate_id};
|
use common_utils::{consts, ext_traits::AsyncExt, generate_id};
|
||||||
use error_stack::{report, ResultExt};
|
use error_stack::{report, ResultExt};
|
||||||
use router_env::{instrument, tracing};
|
use router_env::{instrument, tracing};
|
||||||
@ -79,11 +87,9 @@ pub async fn add_payment_method(
|
|||||||
payment_method_id: payment_method_id.to_string(),
|
payment_method_id: payment_method_id.to_string(),
|
||||||
payment_method: req.payment_method,
|
payment_method: req.payment_method,
|
||||||
payment_method_type: req.payment_method_type,
|
payment_method_type: req.payment_method_type,
|
||||||
payment_method_issuer: req.payment_method_issuer,
|
|
||||||
card: None,
|
card: None,
|
||||||
metadata: req.metadata,
|
metadata: req.metadata,
|
||||||
created: Some(common_utils::date_time::now()),
|
created: Some(common_utils::date_time::now()),
|
||||||
payment_method_issuer_code: req.payment_method_issuer_code,
|
|
||||||
recurring_enabled: false, //[#219]
|
recurring_enabled: false, //[#219]
|
||||||
installment_payment_enabled: false, //[#219]
|
installment_payment_enabled: false, //[#219]
|
||||||
payment_experience: Some(vec![api_models::enums::PaymentExperience::RedirectToUrl]), //[#219]
|
payment_experience: Some(vec![api_models::enums::PaymentExperience::RedirectToUrl]), //[#219]
|
||||||
@ -150,6 +156,7 @@ pub async fn add_card(
|
|||||||
&locker_id,
|
&locker_id,
|
||||||
merchant_id,
|
merchant_id,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let response = if !locker.mock_locker {
|
let response = if !locker.mock_locker {
|
||||||
let response = services::call_connector_api(state, request)
|
let response = services::call_connector_api(state, request)
|
||||||
.await
|
.await
|
||||||
@ -355,7 +362,7 @@ pub async fn list_payment_methods(
|
|||||||
let address = payment_intent
|
let address = payment_intent
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.async_map(|pi| async {
|
.async_map(|pi| async {
|
||||||
helpers::get_address_by_id(db, pi.billing_address_id.clone()).await
|
helpers::get_address_by_id(db, pi.shipping_address_id.clone()).await
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.transpose()?
|
.transpose()?
|
||||||
@ -376,13 +383,16 @@ pub async fn list_payment_methods(
|
|||||||
.transpose()?;
|
.transpose()?;
|
||||||
|
|
||||||
let all_mcas = db
|
let all_mcas = db
|
||||||
.find_merchant_connector_account_by_merchant_id_list(&merchant_account.merchant_id)
|
.find_merchant_connector_account_by_merchant_id_and_disabled_list(
|
||||||
|
&merchant_account.merchant_id,
|
||||||
|
false,
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|error| {
|
.map_err(|error| {
|
||||||
error.to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)
|
error.to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let mut response: HashMap<api::ListPaymentMethod, Vec<String>> = HashMap::new();
|
let mut response: Vec<ResponsePaymentMethodIntermediate> = vec![];
|
||||||
for mca in all_mcas {
|
for mca in all_mcas {
|
||||||
let payment_methods = match mca.payment_methods_enabled {
|
let payment_methods = match mca.payment_methods_enabled {
|
||||||
Some(pm) => pm,
|
Some(pm) => pm,
|
||||||
@ -401,19 +411,125 @@ pub async fn list_payment_methods(
|
|||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut payment_experiences_consolidated_hm: HashMap<
|
||||||
|
api_enums::PaymentMethod,
|
||||||
|
HashMap<api_enums::PaymentMethodType, HashMap<api_enums::PaymentExperience, Vec<String>>>,
|
||||||
|
> = HashMap::new();
|
||||||
|
|
||||||
|
let mut card_networks_consolidated_hm: HashMap<
|
||||||
|
api_enums::PaymentMethod,
|
||||||
|
HashMap<api_enums::PaymentMethodType, HashMap<api_enums::CardNetwork, Vec<String>>>,
|
||||||
|
> = HashMap::new();
|
||||||
|
|
||||||
|
for element in response.clone() {
|
||||||
|
let payment_method = element.payment_method;
|
||||||
|
let payment_method_type = element.payment_method_type;
|
||||||
|
let connector = element.connector.clone();
|
||||||
|
|
||||||
|
if let Some(payment_experience) = element.payment_experience {
|
||||||
|
if let Some(payment_method_hm) =
|
||||||
|
payment_experiences_consolidated_hm.get_mut(&payment_method)
|
||||||
|
{
|
||||||
|
if let Some(payment_method_type_hm) =
|
||||||
|
payment_method_hm.get_mut(&payment_method_type)
|
||||||
|
{
|
||||||
|
if let Some(vector_of_connectors) =
|
||||||
|
payment_method_type_hm.get_mut(&payment_experience)
|
||||||
|
{
|
||||||
|
vector_of_connectors.push(connector);
|
||||||
|
} else {
|
||||||
|
payment_method_type_hm.insert(payment_experience, vec![connector]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
payment_method_hm.insert(payment_method_type, HashMap::new());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
payment_experiences_consolidated_hm.insert(payment_method, HashMap::new());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(card_networks) = element.card_networks {
|
||||||
|
if let Some(payment_method_hm) = card_networks_consolidated_hm.get_mut(&payment_method)
|
||||||
|
{
|
||||||
|
if let Some(payment_method_type_hm) =
|
||||||
|
payment_method_hm.get_mut(&payment_method_type)
|
||||||
|
{
|
||||||
|
for card_network in card_networks {
|
||||||
|
if let Some(vector_of_connectors) =
|
||||||
|
payment_method_type_hm.get_mut(&card_network)
|
||||||
|
{
|
||||||
|
let connector = element.connector.clone(); //FIXME: remove clone
|
||||||
|
vector_of_connectors.push(connector);
|
||||||
|
} else {
|
||||||
|
let connector = element.connector.clone(); //FIXME: remove clone
|
||||||
|
payment_method_type_hm.insert(card_network, vec![connector]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
payment_method_hm.insert(payment_method_type, HashMap::new());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
card_networks_consolidated_hm.insert(payment_method, HashMap::new());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut payment_method_responses: Vec<ResponsePaymentMethodsEnabled> = vec![];
|
||||||
|
for key in payment_experiences_consolidated_hm.iter() {
|
||||||
|
let mut payment_method_types = vec![];
|
||||||
|
for payment_method_types_hm in key.1 {
|
||||||
|
let mut payment_experience_types = vec![];
|
||||||
|
for payment_experience_type in payment_method_types_hm.1 {
|
||||||
|
payment_experience_types.push(PaymentExperienceTypes {
|
||||||
|
payment_experience_type: *payment_experience_type.0,
|
||||||
|
eligible_connectors: payment_experience_type.1.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
payment_method_types.push(ResponsePaymentMethodTypes {
|
||||||
|
payment_method_type: *payment_method_types_hm.0,
|
||||||
|
payment_experience: Some(payment_experience_types),
|
||||||
|
card_networks: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
payment_method_responses.push(ResponsePaymentMethodsEnabled {
|
||||||
|
payment_method: *key.0,
|
||||||
|
payment_method_types,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
for key in card_networks_consolidated_hm.iter() {
|
||||||
|
let mut payment_method_types = vec![];
|
||||||
|
for payment_method_types_hm in key.1 {
|
||||||
|
let mut card_network_types = vec![];
|
||||||
|
for card_network_type in payment_method_types_hm.1 {
|
||||||
|
card_network_types.push(CardNetworkTypes {
|
||||||
|
card_network: card_network_type.0.clone(),
|
||||||
|
eligible_connectors: card_network_type.1.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
payment_method_types.push(ResponsePaymentMethodTypes {
|
||||||
|
payment_method_type: *payment_method_types_hm.0,
|
||||||
|
card_networks: Some(card_network_types),
|
||||||
|
payment_experience: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
payment_method_responses.push(ResponsePaymentMethodsEnabled {
|
||||||
|
payment_method: *key.0,
|
||||||
|
payment_method_types,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
response
|
response
|
||||||
.is_empty()
|
.is_empty()
|
||||||
.then(|| Err(report!(errors::ApiErrorResponse::PaymentMethodNotFound)))
|
.then(|| Err(report!(errors::ApiErrorResponse::PaymentMethodNotFound)))
|
||||||
.unwrap_or(Ok(services::ApplicationResponse::Json(
|
.unwrap_or(Ok(services::ApplicationResponse::Json(
|
||||||
api::ListPaymentMethodResponse {
|
api::ListPaymentMethodResponse {
|
||||||
redirect_url: merchant_account.return_url,
|
redirect_url: merchant_account.return_url,
|
||||||
payment_methods: response
|
payment_methods: payment_method_responses,
|
||||||
.into_iter()
|
|
||||||
.map(|(mut key, val)| {
|
|
||||||
key.eligible_connectors = Some(val);
|
|
||||||
key
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
},
|
},
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
@ -421,54 +537,74 @@ pub async fn list_payment_methods(
|
|||||||
async fn filter_payment_methods(
|
async fn filter_payment_methods(
|
||||||
payment_methods: Vec<serde_json::Value>,
|
payment_methods: Vec<serde_json::Value>,
|
||||||
req: &mut api::ListPaymentMethodRequest,
|
req: &mut api::ListPaymentMethodRequest,
|
||||||
resp: &mut HashMap<api::ListPaymentMethod, Vec<String>>,
|
resp: &mut Vec<ResponsePaymentMethodIntermediate>,
|
||||||
payment_intent: Option<&storage::PaymentIntent>,
|
payment_intent: Option<&storage::PaymentIntent>,
|
||||||
payment_attempt: Option<&storage::PaymentAttempt>,
|
payment_attempt: Option<&storage::PaymentAttempt>,
|
||||||
address: Option<&storage::Address>,
|
address: Option<&storage::Address>,
|
||||||
connector_name: String,
|
connector: String,
|
||||||
) -> errors::CustomResult<(), errors::ApiErrorResponse> {
|
) -> errors::CustomResult<(), errors::ApiErrorResponse> {
|
||||||
for payment_method in payment_methods.into_iter() {
|
for payment_method in payment_methods.into_iter() {
|
||||||
if let Ok(payment_method_object) =
|
let parse_result = serde_json::from_value::<PaymentMethodsEnabled>(payment_method);
|
||||||
serde_json::from_value::<api::ListPaymentMethod>(payment_method)
|
if let Ok(payment_methods_enabled) = parse_result {
|
||||||
{
|
let payment_method = payment_methods_enabled.payment_method;
|
||||||
if filter_recurring_based(&payment_method_object, req.recurring_enabled)
|
for payment_method_type_info in payment_methods_enabled
|
||||||
&& filter_installment_based(&payment_method_object, req.installment_payment_enabled)
|
.payment_method_types
|
||||||
&& filter_amount_based(&payment_method_object, req.amount)
|
.unwrap_or_default()
|
||||||
{
|
{
|
||||||
let mut payment_method_object = payment_method_object;
|
if filter_recurring_based(&payment_method_type_info, req.recurring_enabled)
|
||||||
|
&& filter_installment_based(
|
||||||
|
&payment_method_type_info,
|
||||||
|
req.installment_payment_enabled,
|
||||||
|
)
|
||||||
|
&& filter_amount_based(&payment_method_type_info, req.amount)
|
||||||
|
{
|
||||||
|
let mut payment_method_object = payment_method_type_info;
|
||||||
|
|
||||||
let filter;
|
let filter;
|
||||||
(
|
(
|
||||||
payment_method_object.accepted_countries,
|
payment_method_object.accepted_countries,
|
||||||
req.accepted_countries,
|
req.accepted_countries,
|
||||||
filter,
|
filter,
|
||||||
) = filter_pm_country_based(
|
) = filter_pm_country_based(
|
||||||
&payment_method_object.accepted_countries,
|
&payment_method_object.accepted_countries,
|
||||||
&req.accepted_countries,
|
&req.accepted_countries,
|
||||||
);
|
);
|
||||||
let filter2;
|
let filter2;
|
||||||
(
|
(
|
||||||
payment_method_object.accepted_currencies,
|
payment_method_object.accepted_currencies,
|
||||||
req.accepted_currencies,
|
req.accepted_currencies,
|
||||||
filter2,
|
filter2,
|
||||||
) = filter_pm_currencies_based(
|
) = filter_pm_currencies_based(
|
||||||
&payment_method_object.accepted_currencies,
|
&payment_method_object.accepted_currencies,
|
||||||
&req.accepted_currencies,
|
&req.accepted_currencies,
|
||||||
);
|
);
|
||||||
let filter3 = if let Some(payment_intent) = payment_intent {
|
|
||||||
filter_payment_country_based(&payment_method_object, address).await?
|
|
||||||
&& filter_payment_currency_based(payment_intent, &payment_method_object)
|
|
||||||
&& filter_payment_amount_based(payment_intent, &payment_method_object)
|
|
||||||
&& filter_payment_mandate_based(payment_attempt, &payment_method_object)
|
|
||||||
.await?
|
|
||||||
} else {
|
|
||||||
true
|
|
||||||
};
|
|
||||||
|
|
||||||
if filter && filter2 && filter3 {
|
let filter4 = filter_pm_card_network_based(
|
||||||
resp.entry(payment_method_object)
|
payment_method_object.card_networks.as_ref(),
|
||||||
.or_insert_with(Vec::new)
|
req.card_networks.as_ref(),
|
||||||
.push(connector_name.clone());
|
);
|
||||||
|
|
||||||
|
let filter3 = if let Some(payment_intent) = payment_intent {
|
||||||
|
filter_payment_country_based(&payment_method_object, address).await?
|
||||||
|
&& filter_payment_currency_based(payment_intent, &payment_method_object)
|
||||||
|
&& filter_payment_amount_based(payment_intent, &payment_method_object)
|
||||||
|
&& filter_payment_mandate_based(payment_attempt, &payment_method_object)
|
||||||
|
.await?
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
};
|
||||||
|
|
||||||
|
let connector = connector.clone();
|
||||||
|
|
||||||
|
let response_pm_type = ResponsePaymentMethodIntermediate::new(
|
||||||
|
payment_method_object,
|
||||||
|
connector,
|
||||||
|
payment_method,
|
||||||
|
);
|
||||||
|
|
||||||
|
if filter && filter2 && filter3 && filter4 {
|
||||||
|
resp.push(response_pm_type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -476,6 +612,18 @@ async fn filter_payment_methods(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn filter_pm_card_network_based(
|
||||||
|
pm_card_networks: Option<&Vec<api_enums::CardNetwork>>,
|
||||||
|
request_card_networks: Option<&Vec<api_enums::CardNetwork>>,
|
||||||
|
) -> bool {
|
||||||
|
match (pm_card_networks, request_card_networks) {
|
||||||
|
(Some(pm_card_networks), Some(request_card_networks)) => pm_card_networks
|
||||||
|
.iter()
|
||||||
|
.all(|card_network| request_card_networks.contains(card_network)),
|
||||||
|
(None, Some(_)) => false,
|
||||||
|
_ => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
fn filter_pm_country_based(
|
fn filter_pm_country_based(
|
||||||
accepted_countries: &Option<admin::AcceptedCountries>,
|
accepted_countries: &Option<admin::AcceptedCountries>,
|
||||||
req_country_list: &Option<Vec<String>>,
|
req_country_list: &Option<Vec<String>>,
|
||||||
@ -582,12 +730,20 @@ fn filter_disabled_enum_based<T: Eq + std::hash::Hash + Clone>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter_amount_based(payment_method: &api::ListPaymentMethod, amount: Option<i64>) -> bool {
|
fn filter_amount_based(payment_method: &RequestPaymentMethodTypes, amount: Option<i64>) -> bool {
|
||||||
let min_check = amount
|
let min_check = amount
|
||||||
.and_then(|amt| payment_method.minimum_amount.map(|min_amt| amt >= min_amt))
|
.and_then(|amt| {
|
||||||
|
payment_method
|
||||||
|
.minimum_amount
|
||||||
|
.map(|min_amt| amt >= min_amt.into())
|
||||||
|
})
|
||||||
.unwrap_or(true);
|
.unwrap_or(true);
|
||||||
let max_check = amount
|
let max_check = amount
|
||||||
.and_then(|amt| payment_method.maximum_amount.map(|max_amt| amt <= max_amt))
|
.and_then(|amt| {
|
||||||
|
payment_method
|
||||||
|
.maximum_amount
|
||||||
|
.map(|max_amt| amt <= max_amt.into())
|
||||||
|
})
|
||||||
.unwrap_or(true);
|
.unwrap_or(true);
|
||||||
// let min_check = match (amount, payment_method.minimum_amount) {
|
// let min_check = match (amount, payment_method.minimum_amount) {
|
||||||
// (Some(amt), Some(min_amt)) => amt >= min_amt,
|
// (Some(amt), Some(min_amt)) => amt >= min_amt,
|
||||||
@ -601,14 +757,14 @@ fn filter_amount_based(payment_method: &api::ListPaymentMethod, amount: Option<i
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn filter_recurring_based(
|
fn filter_recurring_based(
|
||||||
payment_method: &api::ListPaymentMethod,
|
payment_method: &RequestPaymentMethodTypes,
|
||||||
recurring_enabled: Option<bool>,
|
recurring_enabled: Option<bool>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
recurring_enabled.map_or(true, |enabled| payment_method.recurring_enabled == enabled)
|
recurring_enabled.map_or(true, |enabled| payment_method.recurring_enabled == enabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter_installment_based(
|
fn filter_installment_based(
|
||||||
payment_method: &api::ListPaymentMethod,
|
payment_method: &RequestPaymentMethodTypes,
|
||||||
installment_payment_enabled: Option<bool>,
|
installment_payment_enabled: Option<bool>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
installment_payment_enabled.map_or(true, |enabled| {
|
installment_payment_enabled.map_or(true, |enabled| {
|
||||||
@ -617,7 +773,7 @@ fn filter_installment_based(
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn filter_payment_country_based(
|
async fn filter_payment_country_based(
|
||||||
pm: &api::ListPaymentMethod,
|
pm: &RequestPaymentMethodTypes,
|
||||||
address: Option<&storage::Address>,
|
address: Option<&storage::Address>,
|
||||||
) -> errors::CustomResult<bool, errors::ApiErrorResponse> {
|
) -> errors::CustomResult<bool, errors::ApiErrorResponse> {
|
||||||
Ok(address.map_or(true, |address| {
|
Ok(address.map_or(true, |address| {
|
||||||
@ -639,7 +795,7 @@ async fn filter_payment_country_based(
|
|||||||
|
|
||||||
fn filter_payment_currency_based(
|
fn filter_payment_currency_based(
|
||||||
payment_intent: &storage::PaymentIntent,
|
payment_intent: &storage::PaymentIntent,
|
||||||
pm: &api::ListPaymentMethod,
|
pm: &RequestPaymentMethodTypes,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
payment_intent.currency.map_or(true, |currency| {
|
payment_intent.currency.map_or(true, |currency| {
|
||||||
pm.accepted_currencies.as_ref().map_or(true, |ac| {
|
pm.accepted_currencies.as_ref().map_or(true, |ac| {
|
||||||
@ -658,16 +814,16 @@ fn filter_payment_currency_based(
|
|||||||
|
|
||||||
fn filter_payment_amount_based(
|
fn filter_payment_amount_based(
|
||||||
payment_intent: &storage::PaymentIntent,
|
payment_intent: &storage::PaymentIntent,
|
||||||
pm: &api::ListPaymentMethod,
|
pm: &RequestPaymentMethodTypes,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let amount = payment_intent.amount;
|
let amount = payment_intent.amount;
|
||||||
pm.maximum_amount.map_or(true, |amt| amount < amt)
|
pm.maximum_amount.map_or(true, |amt| amount < amt.into())
|
||||||
&& pm.minimum_amount.map_or(true, |amt| amount > amt)
|
&& pm.minimum_amount.map_or(true, |amt| amount > amt.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn filter_payment_mandate_based(
|
async fn filter_payment_mandate_based(
|
||||||
payment_attempt: Option<&storage::PaymentAttempt>,
|
payment_attempt: Option<&storage::PaymentAttempt>,
|
||||||
pm: &api::ListPaymentMethod,
|
pm: &RequestPaymentMethodTypes,
|
||||||
) -> errors::CustomResult<bool, errors::ApiErrorResponse> {
|
) -> errors::CustomResult<bool, errors::ApiErrorResponse> {
|
||||||
let recurring_filter = if !pm.recurring_enabled {
|
let recurring_filter = if !pm.recurring_enabled {
|
||||||
payment_attempt.map_or(true, |pa| pa.mandate_id.is_none())
|
payment_attempt.map_or(true, |pa| pa.mandate_id.is_none())
|
||||||
@ -684,7 +840,10 @@ pub async fn list_customer_payment_method(
|
|||||||
) -> errors::RouterResponse<api::ListCustomerPaymentMethodsResponse> {
|
) -> errors::RouterResponse<api::ListCustomerPaymentMethodsResponse> {
|
||||||
let db = &*state.store;
|
let db = &*state.store;
|
||||||
let all_mcas = db
|
let all_mcas = db
|
||||||
.find_merchant_connector_account_by_merchant_id_list(&merchant_account.merchant_id)
|
.find_merchant_connector_account_by_merchant_id_and_disabled_list(
|
||||||
|
&merchant_account.merchant_id,
|
||||||
|
false,
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|error| {
|
.map_err(|error| {
|
||||||
error.to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)
|
error.to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)
|
||||||
@ -981,13 +1140,9 @@ pub async fn retrieve_payment_method(
|
|||||||
payment_method_id: pm.payment_method_id,
|
payment_method_id: pm.payment_method_id,
|
||||||
payment_method: pm.payment_method.foreign_into(),
|
payment_method: pm.payment_method.foreign_into(),
|
||||||
payment_method_type: pm.payment_method_type.map(ForeignInto::foreign_into),
|
payment_method_type: pm.payment_method_type.map(ForeignInto::foreign_into),
|
||||||
payment_method_issuer: pm.payment_method_issuer,
|
|
||||||
card,
|
card,
|
||||||
metadata: pm.metadata,
|
metadata: pm.metadata,
|
||||||
created: Some(pm.created_at),
|
created: Some(pm.created_at),
|
||||||
payment_method_issuer_code: pm
|
|
||||||
.payment_method_issuer_code
|
|
||||||
.map(ForeignInto::foreign_into),
|
|
||||||
recurring_enabled: false, //[#219]
|
recurring_enabled: false, //[#219]
|
||||||
installment_payment_enabled: false, //[#219]
|
installment_payment_enabled: false, //[#219]
|
||||||
payment_experience: Some(vec![api_models::enums::PaymentExperience::RedirectToUrl]), //[#219],
|
payment_experience: Some(vec![api_models::enums::PaymentExperience::RedirectToUrl]), //[#219],
|
||||||
|
|||||||
@ -120,11 +120,9 @@ pub fn mk_add_card_response(
|
|||||||
payment_method_id: response.card_id,
|
payment_method_id: response.card_id,
|
||||||
payment_method: req.payment_method,
|
payment_method: req.payment_method,
|
||||||
payment_method_type: req.payment_method_type,
|
payment_method_type: req.payment_method_type,
|
||||||
payment_method_issuer: req.payment_method_issuer,
|
|
||||||
card: Some(card),
|
card: Some(card),
|
||||||
metadata: req.metadata,
|
metadata: req.metadata,
|
||||||
created: Some(common_utils::date_time::now()),
|
created: Some(common_utils::date_time::now()),
|
||||||
payment_method_issuer_code: req.payment_method_issuer_code,
|
|
||||||
recurring_enabled: false, // [#256]
|
recurring_enabled: false, // [#256]
|
||||||
installment_payment_enabled: false, // #[#256]
|
installment_payment_enabled: false, // #[#256]
|
||||||
payment_experience: Some(vec![api_models::enums::PaymentExperience::RedirectToUrl]), // [#256]
|
payment_experience: Some(vec![api_models::enums::PaymentExperience::RedirectToUrl]), // [#256]
|
||||||
|
|||||||
@ -286,7 +286,10 @@ where
|
|||||||
let supported_connectors: &Vec<String> = state.conf.connectors.supported.wallets.as_ref();
|
let supported_connectors: &Vec<String> = state.conf.connectors.supported.wallets.as_ref();
|
||||||
|
|
||||||
let connector_accounts = db
|
let connector_accounts = db
|
||||||
.find_merchant_connector_account_by_merchant_id_list(&merchant_account.merchant_id)
|
.find_merchant_connector_account_by_merchant_id_and_disabled_list(
|
||||||
|
&merchant_account.merchant_id,
|
||||||
|
false,
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||||
.attach_printable("Database error when querying for merchant connector accounts")?;
|
.attach_printable("Database error when querying for merchant connector accounts")?;
|
||||||
|
|||||||
@ -115,9 +115,10 @@ pub trait MerchantConnectorAccountInterface {
|
|||||||
merchant_connector_id: &str,
|
merchant_connector_id: &str,
|
||||||
) -> CustomResult<storage::MerchantConnectorAccount, errors::StorageError>;
|
) -> CustomResult<storage::MerchantConnectorAccount, errors::StorageError>;
|
||||||
|
|
||||||
async fn find_merchant_connector_account_by_merchant_id_list(
|
async fn find_merchant_connector_account_by_merchant_id_and_disabled_list(
|
||||||
&self,
|
&self,
|
||||||
merchant_id: &str,
|
merchant_id: &str,
|
||||||
|
get_disabled: bool,
|
||||||
) -> CustomResult<Vec<storage::MerchantConnectorAccount>, errors::StorageError>;
|
) -> CustomResult<Vec<storage::MerchantConnectorAccount>, errors::StorageError>;
|
||||||
|
|
||||||
async fn update_merchant_connector_account(
|
async fn update_merchant_connector_account(
|
||||||
@ -186,12 +187,13 @@ impl MerchantConnectorAccountInterface for Store {
|
|||||||
t.insert(&conn).await.map_err(Into::into).into_report()
|
t.insert(&conn).await.map_err(Into::into).into_report()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn find_merchant_connector_account_by_merchant_id_list(
|
async fn find_merchant_connector_account_by_merchant_id_and_disabled_list(
|
||||||
&self,
|
&self,
|
||||||
merchant_id: &str,
|
merchant_id: &str,
|
||||||
|
get_disabled: bool,
|
||||||
) -> CustomResult<Vec<storage::MerchantConnectorAccount>, errors::StorageError> {
|
) -> CustomResult<Vec<storage::MerchantConnectorAccount>, errors::StorageError> {
|
||||||
let conn = pg_connection(&self.master_pool).await?;
|
let conn = pg_connection(&self.master_pool).await?;
|
||||||
storage::MerchantConnectorAccount::find_by_merchant_id(&conn, merchant_id)
|
storage::MerchantConnectorAccount::find_by_merchant_id(&conn, merchant_id, get_disabled)
|
||||||
.await
|
.await
|
||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
.into_report()
|
.into_report()
|
||||||
@ -293,9 +295,10 @@ impl MerchantConnectorAccountInterface for MockDb {
|
|||||||
Ok(account)
|
Ok(account)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn find_merchant_connector_account_by_merchant_id_list(
|
async fn find_merchant_connector_account_by_merchant_id_and_disabled_list(
|
||||||
&self,
|
&self,
|
||||||
_merchant_id: &str,
|
_merchant_id: &str,
|
||||||
|
_get_disabled: bool,
|
||||||
) -> CustomResult<Vec<storage::MerchantConnectorAccount>, errors::StorageError> {
|
) -> CustomResult<Vec<storage::MerchantConnectorAccount>, errors::StorageError> {
|
||||||
// [#172]: Implement function for `MockDb`
|
// [#172]: Implement function for `MockDb`
|
||||||
Err(errors::StorageError::MockDbError)?
|
Err(errors::StorageError::MockDbError)?
|
||||||
|
|||||||
@ -141,7 +141,7 @@ Never share your secret api keys. Keep them guarded and secure.
|
|||||||
api_models::enums::MandateStatus,
|
api_models::enums::MandateStatus,
|
||||||
api_models::enums::PaymentExperience,
|
api_models::enums::PaymentExperience,
|
||||||
api_models::admin::PaymentConnectorCreate,
|
api_models::admin::PaymentConnectorCreate,
|
||||||
api_models::admin::PaymentMethods,
|
api_models::admin::PaymentMethodsEnabled,
|
||||||
api_models::payments::AddressDetails,
|
api_models::payments::AddressDetails,
|
||||||
api_models::payments::Address,
|
api_models::payments::Address,
|
||||||
api_models::payments::OrderDetails,
|
api_models::payments::OrderDetails,
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
pub use api_models::admin::{
|
pub use api_models::admin::{
|
||||||
CreateMerchantAccount, DeleteMcaResponse, DeleteMerchantAccountResponse,
|
CreateMerchantAccount, DeleteMcaResponse, DeleteMerchantAccountResponse,
|
||||||
MerchantAccountResponse, MerchantConnectorId, MerchantDetails, MerchantId,
|
MerchantAccountResponse, MerchantConnectorId, MerchantDetails, MerchantId,
|
||||||
PaymentConnectorCreate, PaymentMethods, RoutingAlgorithm, ToggleKVRequest, ToggleKVResponse,
|
PaymentConnectorCreate, PaymentMethodsEnabled, RoutingAlgorithm, ToggleKVRequest,
|
||||||
WebhookDetails,
|
ToggleKVResponse, WebhookDetails,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::types::{storage, transformers::Foreign};
|
use crate::types::{storage, transformers::Foreign};
|
||||||
|
|||||||
@ -409,7 +409,6 @@ pub enum PaymentMethodIssuerCode {
|
|||||||
JpSepa,
|
JpSepa,
|
||||||
JpBacs,
|
JpBacs,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone,
|
Clone,
|
||||||
Copy,
|
Copy,
|
||||||
|
|||||||
@ -89,19 +89,38 @@ impl MerchantConnectorAccount {
|
|||||||
pub async fn find_by_merchant_id(
|
pub async fn find_by_merchant_id(
|
||||||
conn: &PgPooledConn,
|
conn: &PgPooledConn,
|
||||||
merchant_id: &str,
|
merchant_id: &str,
|
||||||
|
get_disabled: bool,
|
||||||
) -> StorageResult<Vec<Self>> {
|
) -> StorageResult<Vec<Self>> {
|
||||||
generics::generic_filter::<
|
if get_disabled {
|
||||||
<Self as HasTable>::Table,
|
generics::generic_filter::<
|
||||||
_,
|
<Self as HasTable>::Table,
|
||||||
<<Self as HasTable>::Table as Table>::PrimaryKey,
|
_,
|
||||||
_,
|
<<Self as HasTable>::Table as Table>::PrimaryKey,
|
||||||
>(
|
_,
|
||||||
conn,
|
>(
|
||||||
dsl::merchant_id.eq(merchant_id.to_owned()),
|
conn,
|
||||||
None,
|
dsl::merchant_id.eq(merchant_id.to_owned()),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
)
|
None,
|
||||||
.await
|
)
|
||||||
|
.await
|
||||||
|
} else {
|
||||||
|
generics::generic_filter::<
|
||||||
|
<Self as HasTable>::Table,
|
||||||
|
_,
|
||||||
|
<<Self as HasTable>::Table as Table>::PrimaryKey,
|
||||||
|
_,
|
||||||
|
>(
|
||||||
|
conn,
|
||||||
|
dsl::merchant_id
|
||||||
|
.eq(merchant_id.to_owned())
|
||||||
|
.and(dsl::disabled.eq(false)),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user