From b9ff05360df5c20d0aca3afb53b9811ffc054de1 Mon Sep 17 00:00:00 2001 From: Narayan Bhat Date: Mon, 2 Dec 2024 21:30:33 +0530 Subject: [PATCH 01/12] feat(payments_v2): implement payments capture v2 --- crates/api_models/src/events/payment.rs | 10 + crates/api_models/src/payments.rs | 31 +- crates/diesel_models/src/payment_attempt.rs | 4 +- crates/diesel_models/src/payment_intent.rs | 15 +- .../hyperswitch_domain_models/src/payments.rs | 15 +- .../src/payments/payment_attempt.rs | 143 +++++- .../src/payments/payment_intent.rs | 57 ++- .../src/router_data.rs | 448 +++++++++++++++++- crates/openapi/src/openapi_v2.rs | 2 +- crates/router/src/core/payments.rs | 242 +++++++++- .../src/core/payments/flows/capture_flow.rs | 38 +- crates/router/src/core/payments/operations.rs | 5 +- .../payments/operations/payment_capture_v2.rs | 321 +++++++++++++ .../core/payments/operations/payment_get.rs | 65 +-- .../payments/operations/payment_response.rs | 94 +++- .../router/src/core/payments/transformers.rs | 385 ++++++++++++--- .../router/src/core/webhooks/incoming_v2.rs | 13 +- crates/router/src/routes/app.rs | 3 + crates/router/src/routes/payments.rs | 72 +++ crates/router/src/types.rs | 2 +- 20 files changed, 1799 insertions(+), 166 deletions(-) create mode 100644 crates/router/src/core/payments/operations/payment_capture_v2.rs diff --git a/crates/api_models/src/events/payment.rs b/crates/api_models/src/events/payment.rs index 6fdb7d59b0f8..9309c76f19f0 100644 --- a/crates/api_models/src/events/payment.rs +++ b/crates/api_models/src/events/payment.rs @@ -13,6 +13,7 @@ use crate::payment_methods::CustomerPaymentMethodsListResponse; #[cfg(all(feature = "v2", feature = "payment_methods_v2"))] use crate::payment_methods::CustomerPaymentMethodsListResponse; use crate::{ + events, payment_methods::{ CustomerDefaultPaymentMethodResponse, DefaultPaymentMethod, ListCountriesCurrenciesRequest, ListCountriesCurrenciesResponse, PaymentMethodCollectLinkRenderRequest, @@ -419,3 +420,12 @@ impl ApiEventMetric for PaymentStartRedirectionRequest { }) } } + +#[cfg(feature = "v2")] +impl ApiEventMetric for events::PaymentsCaptureResponse { + fn get_api_event_type(&self) -> Option { + Some(ApiEventsType::Payment { + payment_id: self.id.clone(), + }) + } +} diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index 98bc7b754a46..9e3d29638b94 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -488,7 +488,7 @@ pub struct AmountDetailsResponse { #[cfg(feature = "v2")] #[derive(Clone, Debug, PartialEq, serde::Serialize, ToSchema)] -pub struct ConfirmIntentAmountDetailsResponse { +pub struct PaymentAmountDetailsResponse { /// The payment amount. Amount for the payment in the lowest denomination of the currency, (i.e) in cents for USD denomination, in yen for JPY denomination etc. E.g., Pass 100 to charge $1.00 and 1 for 1¥ since ¥ is a zero-decimal currency. Read more about [the Decimal and Non-Decimal Currencies](https://github.com/juspay/hyperswitch/wiki/Decimal-and-Non%E2%80%90Decimal-Currencies) #[schema(value_type = u64, example = 6540)] #[serde(default, deserialize_with = "amount::deserialize")] @@ -3890,6 +3890,7 @@ pub struct PhoneDetails { pub country_code: Option, } +#[cfg(feature = "v1")] #[derive(Debug, Clone, Default, Eq, PartialEq, serde::Deserialize, serde::Serialize, ToSchema)] pub struct PaymentsCaptureRequest { /// The unique identifier for the payment @@ -3898,7 +3899,7 @@ pub struct PaymentsCaptureRequest { /// The unique identifier for the merchant #[schema(value_type = Option)] pub merchant_id: Option, - /// The Amount to be captured/ debited from the user's payment method. + /// The Amount to be captured/ debited from the user's payment method. If not passed the full amount will be captured. #[schema(value_type = i64, example = 6540)] pub amount_to_capture: Option, /// Decider to refund the uncaptured amount @@ -3912,6 +3913,28 @@ pub struct PaymentsCaptureRequest { pub merchant_connector_details: Option, } +#[cfg(feature = "v2")] +#[derive(Debug, Clone, Default, Eq, PartialEq, serde::Deserialize, serde::Serialize, ToSchema)] +pub struct PaymentsCaptureRequest { + /// The Amount to be captured/ debited from the user's payment method. If not passed the full amount will be captured. + #[schema(value_type = Option, example = 6540)] + pub amount_to_capture: Option, +} + +#[cfg(feature = "v2")] +#[derive(Debug, Clone, serde::Serialize, ToSchema)] +pub struct PaymentsCaptureResponse { + /// The unique identifier for the payment + pub id: id_type::GlobalPaymentId, + + /// Amount details related to the payment + pub amount: PaymentAmountDetailsResponse, + + /// Status of the payment + #[schema(value_type = IntentStatus, example = "succeeded")] + pub status: common_enums::IntentStatus, +} + #[derive(Default, Clone, Debug, Eq, PartialEq, serde::Serialize)] pub struct UrlDetails { pub url: String, @@ -4615,7 +4638,7 @@ pub struct PaymentsConfirmIntentResponse { pub status: api_enums::IntentStatus, /// Amount related information for this payment and attempt - pub amount: ConfirmIntentAmountDetailsResponse, + pub amount: PaymentAmountDetailsResponse, /// The connector used for the payment #[schema(example = "stripe")] @@ -4684,7 +4707,7 @@ pub struct PaymentsRetrieveResponse { pub status: api_enums::IntentStatus, /// Amount related information for this payment and attempt - pub amount: ConfirmIntentAmountDetailsResponse, + pub amount: PaymentAmountDetailsResponse, /// The connector used for the payment #[schema(example = "stripe")] diff --git a/crates/diesel_models/src/payment_attempt.rs b/crates/diesel_models/src/payment_attempt.rs index 7760ea76c500..466489a7a63d 100644 --- a/crates/diesel_models/src/payment_attempt.rs +++ b/crates/diesel_models/src/payment_attempt.rs @@ -754,7 +754,6 @@ pub enum PaymentAttemptUpdate { #[derive(Clone, Debug, AsChangeset, router_derive::DebugAsDisplay)] #[diesel(table_name = payment_attempt)] pub struct PaymentAttemptUpdateInternal { - // net_amount: Option, pub status: Option, // authentication_type: Option, pub error_message: Option, @@ -774,7 +773,8 @@ pub struct PaymentAttemptUpdateInternal { // multiple_capture_count: Option, // pub surcharge_amount: Option, // tax_on_surcharge: Option, - // amount_capturable: Option, + pub amount_capturable: Option, + pub amount_to_capture: Option, pub updated_by: String, pub merchant_connector_id: Option, pub connector: Option, diff --git a/crates/diesel_models/src/payment_intent.rs b/crates/diesel_models/src/payment_intent.rs index 26cb0b8c8a84..177619e81249 100644 --- a/crates/diesel_models/src/payment_intent.rs +++ b/crates/diesel_models/src/payment_intent.rs @@ -366,6 +366,7 @@ pub enum PaymentIntentUpdate { /// Update the payment intent details on payment intent confirmation, after calling the connector ConfirmIntentPostUpdate { status: storage_enums::IntentStatus, + amount_captured: Option, updated_by: String, }, } @@ -517,7 +518,7 @@ pub struct PaymentIntentUpdateInternal { // pub amount: Option, // pub currency: Option, pub status: Option, - // pub amount_captured: Option, + pub amount_captured: Option, // pub customer_id: Option, // pub return_url: Option<>, // pub setup_future_usage: Option, @@ -591,7 +592,7 @@ impl PaymentIntentUpdate { // amount, // currency, status, - // amount_captured, + amount_captured, // customer_id, // return_url, // setup_future_usage, @@ -617,7 +618,7 @@ impl PaymentIntentUpdate { // amount: amount.unwrap_or(source.amount), // currency: currency.unwrap_or(source.currency), status: status.unwrap_or(source.status), - // amount_captured: amount_captured.or(source.amount_captured), + amount_captured: amount_captured.or(source.amount_captured), // customer_id: customer_id.or(source.customer_id), // return_url: return_url.or(source.return_url), // setup_future_usage: setup_future_usage.or(source.setup_future_usage), @@ -747,9 +748,15 @@ impl From for PaymentIntentUpdateInternal { active_attempt_id: Some(active_attempt_id), modified_at: common_utils::date_time::now(), updated_by, + amount_captured: None, }, - PaymentIntentUpdate::ConfirmIntentPostUpdate { status, updated_by } => Self { + PaymentIntentUpdate::ConfirmIntentPostUpdate { + status, + amount_captured, + updated_by, + } => Self { status: Some(status), + amount_captured, active_attempt_id: None, modified_at: common_utils::date_time::now(), updated_by, diff --git a/crates/hyperswitch_domain_models/src/payments.rs b/crates/hyperswitch_domain_models/src/payments.rs index 1bab8ae3b76c..0b821595f4da 100644 --- a/crates/hyperswitch_domain_models/src/payments.rs +++ b/crates/hyperswitch_domain_models/src/payments.rs @@ -261,7 +261,7 @@ impl AmountDetails { TaxCalculationOverride::Calculate => None, }; - payment_attempt::AttemptAmountDetails { + payment_attempt::AttemptAmountDetails::from(payment_attempt::AttemptAmountDetailsSetter { net_amount, amount_to_capture: None, surcharge_amount, @@ -270,7 +270,7 @@ impl AmountDetails { amount_capturable: MinorUnit::zero(), shipping_cost: self.shipping_cost, order_tax_amount, - } + }) } } @@ -575,6 +575,17 @@ where pub should_sync_with_connector: bool, } +#[cfg(feature = "v2")] +#[derive(Clone)] +pub struct PaymentCaptureData +where + F: Clone, +{ + pub flow: PhantomData, + pub payment_intent: PaymentIntent, + pub payment_attempt: PaymentAttempt, +} + #[cfg(feature = "v2")] impl PaymentStatusData where diff --git a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs index ec1463d1b7b5..f53fbad24640 100644 --- a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs +++ b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs @@ -180,6 +180,27 @@ pub trait PaymentAttemptInterface { #[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)] pub struct AttemptAmountDetails { + /// The total amount for this payment attempt. This includes all the surcharge and tax amounts. + net_amount: MinorUnit, + /// The amount that has to be captured, + amount_to_capture: Option, + /// Surcharge amount for the payment attempt. + /// This is either derived by surcharge rules, or sent by the merchant + surcharge_amount: Option, + /// Tax amount for the payment attempt + /// This is either derived by surcharge rules, or sent by the merchant + tax_on_surcharge: Option, + /// The total amount that can be captured for this payment attempt. + amount_capturable: MinorUnit, + /// Shipping cost for the payment attempt. + shipping_cost: Option, + /// Tax amount for the order. + /// This is either derived by calling an external tax processor, or sent by the merchant + order_tax_amount: Option, +} + +#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)] +pub struct AttemptAmountDetailsSetter { /// The total amount for this payment attempt. This includes all the surcharge and tax amounts. pub net_amount: MinorUnit, /// The amount that has to be captured, @@ -199,6 +220,55 @@ pub struct AttemptAmountDetails { pub order_tax_amount: Option, } +/// Set the fields of amount details, since the fields are not public +impl From for AttemptAmountDetails { + fn from(setter: AttemptAmountDetailsSetter) -> Self { + Self { + net_amount: setter.net_amount, + amount_to_capture: setter.amount_to_capture, + surcharge_amount: setter.surcharge_amount, + tax_on_surcharge: setter.tax_on_surcharge, + amount_capturable: setter.amount_capturable, + shipping_cost: setter.shipping_cost, + order_tax_amount: setter.order_tax_amount, + } + } +} + +impl AttemptAmountDetails { + pub fn get_net_amount(&self) -> MinorUnit { + self.net_amount + } + + pub fn get_amount_to_capture(&self) -> Option { + self.amount_to_capture + } + + pub fn get_surcharge_amount(&self) -> Option { + self.surcharge_amount + } + + pub fn get_tax_on_surcharge(&self) -> Option { + self.tax_on_surcharge + } + + pub fn get_amount_capturable(&self) -> MinorUnit { + self.amount_capturable + } + + pub fn get_shipping_cost(&self) -> Option { + self.shipping_cost + } + + pub fn get_order_tax_amount(&self) -> Option { + self.order_tax_amount + } + + pub fn set_amount_to_capture(&mut self, amount_to_capture: MinorUnit) { + self.amount_to_capture = Some(amount_to_capture); + } +} + #[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)] pub struct ErrorDetails { /// The error code that was returned by the connector. @@ -638,6 +708,7 @@ impl NetAmount { #[cfg(feature = "v2")] impl PaymentAttempt { + #[track_caller] pub fn get_total_amount(&self) -> MinorUnit { todo!(); } @@ -1320,15 +1391,28 @@ pub enum PaymentAttemptUpdate { updated_by: String, redirection_data: Option, connector_metadata: Option, + amount_capturable: Option, }, /// Update the payment attempt after force syncing with the connector SyncUpdate { status: storage_enums::AttemptStatus, + amount_capturable: Option, + updated_by: String, + }, + PreCaptureUpdate { + amount_to_capture: Option, + updated_by: String, + }, + /// Update the payment after attempting capture with the connector + CaptureUpdate { + status: storage_enums::AttemptStatus, + amount_capturable: Option, updated_by: String, }, /// Update the payment attempt on confirming the intent, after calling the connector on error response ErrorUpdate { status: storage_enums::AttemptStatus, + amount_capturable: Option, error: ErrorDetails, updated_by: String, connector_payment_id: Option, @@ -1955,11 +2039,14 @@ impl From for diesel_models::PaymentAttemptUpdateInternal connector: Some(connector), redirection_data: None, connector_metadata: None, + amount_capturable: None, + amount_to_capture: None, }, PaymentAttemptUpdate::ErrorUpdate { status, error, connector_payment_id, + amount_capturable, updated_by, } => Self { status: Some(status), @@ -1976,6 +2063,8 @@ impl From for diesel_models::PaymentAttemptUpdateInternal connector: None, redirection_data: None, connector_metadata: None, + amount_capturable, + amount_to_capture: None, }, PaymentAttemptUpdate::ConfirmIntentResponse { status, @@ -1983,8 +2072,10 @@ impl From for diesel_models::PaymentAttemptUpdateInternal updated_by, redirection_data, connector_metadata, + amount_capturable, } => Self { status: Some(status), + amount_capturable, error_message: None, error_code: None, modified_at: common_utils::date_time::now(), @@ -1999,9 +2090,38 @@ impl From for diesel_models::PaymentAttemptUpdateInternal redirection_data: redirection_data .map(diesel_models::payment_attempt::RedirectForm::from), connector_metadata, + amount_to_capture: None, + }, + PaymentAttemptUpdate::SyncUpdate { + status, + amount_capturable, + updated_by, + } => Self { + status: Some(status), + amount_capturable, + error_message: None, + error_code: None, + modified_at: common_utils::date_time::now(), + browser_info: None, + error_reason: None, + updated_by, + merchant_connector_id: None, + unified_code: None, + unified_message: None, + connector_payment_id: None, + connector: None, + redirection_data: None, + connector_metadata: None, + amount_to_capture: None, }, - PaymentAttemptUpdate::SyncUpdate { status, updated_by } => Self { + PaymentAttemptUpdate::CaptureUpdate { + status, + amount_capturable, + updated_by, + } => Self { status: Some(status), + amount_capturable, + amount_to_capture: None, error_message: None, error_code: None, modified_at: common_utils::date_time::now(), @@ -2016,6 +2136,27 @@ impl From for diesel_models::PaymentAttemptUpdateInternal redirection_data: None, connector_metadata: None, }, + PaymentAttemptUpdate::PreCaptureUpdate { + amount_to_capture, + updated_by, + } => Self { + amount_to_capture, + error_message: None, + modified_at: common_utils::date_time::now(), + browser_info: None, + error_code: None, + error_reason: None, + updated_by, + merchant_connector_id: None, + unified_code: None, + unified_message: None, + connector_payment_id: None, + connector: None, + redirection_data: None, + status: None, + connector_metadata: None, + amount_capturable: None, + }, } } } diff --git a/crates/hyperswitch_domain_models/src/payments/payment_intent.rs b/crates/hyperswitch_domain_models/src/payments/payment_intent.rs index 4f2053ec6f99..0a53d57998ff 100644 --- a/crates/hyperswitch_domain_models/src/payments/payment_intent.rs +++ b/crates/hyperswitch_domain_models/src/payments/payment_intent.rs @@ -280,11 +280,18 @@ pub enum PaymentIntentUpdate { /// PostUpdate tracker of ConfirmIntent ConfirmIntentPostUpdate { status: storage_enums::IntentStatus, + amount_captured: Option, updated_by: String, }, /// SyncUpdate of ConfirmIntent in PostUpdateTrackers SyncUpdate { status: storage_enums::IntentStatus, + amount_captured: Option, + updated_by: String, + }, + CaptureUpdate { + status: storage_enums::IntentStatus, + amount_captured: Option, updated_by: String, }, } @@ -379,17 +386,39 @@ impl From for diesel_models::PaymentIntentUpdateInternal { status: Some(status), active_attempt_id: Some(active_attempt_id), modified_at: common_utils::date_time::now(), + amount_captured: None, updated_by, }, - PaymentIntentUpdate::ConfirmIntentPostUpdate { status, updated_by } => Self { + PaymentIntentUpdate::ConfirmIntentPostUpdate { + status, + amount_captured, + updated_by, + } => Self { status: Some(status), + amount_captured, active_attempt_id: None, modified_at: common_utils::date_time::now(), updated_by, }, - PaymentIntentUpdate::SyncUpdate { status, updated_by } => Self { + PaymentIntentUpdate::SyncUpdate { + status, + amount_captured, + updated_by, + } => Self { status: Some(status), active_attempt_id: None, + amount_captured, + modified_at: common_utils::date_time::now(), + updated_by, + }, + PaymentIntentUpdate::CaptureUpdate { + status, + amount_captured, + updated_by, + } => Self { + status: Some(status), + active_attempt_id: None, + amount_captured, modified_at: common_utils::date_time::now(), updated_by, }, @@ -412,13 +441,33 @@ impl From for PaymentIntentUpdateInternal { updated_by, ..Default::default() }, - PaymentIntentUpdate::ConfirmIntentPostUpdate { status, updated_by } => Self { + PaymentIntentUpdate::ConfirmIntentPostUpdate { + status, + amount_captured, + updated_by, + } => Self { + status: Some(status), + amount_captured, + updated_by, + ..Default::default() + }, + PaymentIntentUpdate::SyncUpdate { + status, + amount_captured, + updated_by, + } => Self { status: Some(status), + amount_captured, updated_by, ..Default::default() }, - PaymentIntentUpdate::SyncUpdate { status, updated_by } => Self { + PaymentIntentUpdate::CaptureUpdate { + status, + amount_captured, + updated_by, + } => Self { status: Some(status), + amount_captured, updated_by, ..Default::default() }, diff --git a/crates/hyperswitch_domain_models/src/router_data.rs b/crates/hyperswitch_domain_models/src/router_data.rs index 0863ab59b45f..5b6d4f2c79e0 100644 --- a/crates/hyperswitch_domain_models/src/router_data.rs +++ b/crates/hyperswitch_domain_models/src/router_data.rs @@ -401,15 +401,30 @@ use crate::{ /// Get updatable trakcer objects of payment intent and payment attempt #[cfg(feature = "v2")] -pub trait TrackerPostUpdateObjects { +pub trait TrackerPostUpdateObjects { fn get_payment_intent_update( &self, + payment_data: &D, storage_scheme: common_enums::MerchantStorageScheme, ) -> PaymentIntentUpdate; + fn get_payment_attempt_update( &self, + payment_data: &D, storage_scheme: common_enums::MerchantStorageScheme, ) -> PaymentAttemptUpdate; + + /// Get the amount that can be captured for the payment + fn get_amount_capturable(&self, payment_data: &D) -> Option; + + /// Get the amount that has been captured for the payment + fn get_captured_amount(&self, payment_data: &D) -> Option; + + /// Get the attempt status based on parameters like captured amount and amount capturable + fn get_attempt_status_for_db_update( + &self, + payment_data: &D, + ) -> common_enums::enums::AttemptStatus; } #[cfg(feature = "v2")] @@ -417,6 +432,7 @@ impl TrackerPostUpdateObjects< router_flow_types::Authorize, router_request_types::PaymentsAuthorizeData, + payments::PaymentConfirmData, > for RouterData< router_flow_types::Authorize, @@ -426,11 +442,16 @@ impl { fn get_payment_intent_update( &self, + payment_data: &payments::PaymentConfirmData, storage_scheme: common_enums::MerchantStorageScheme, ) -> PaymentIntentUpdate { + let amount_captured = self.get_captured_amount(payment_data); match self.response { Ok(ref _response) => PaymentIntentUpdate::ConfirmIntentPostUpdate { - status: common_enums::IntentStatus::from(self.status), + status: common_enums::IntentStatus::from( + self.get_attempt_status_for_db_update(payment_data), + ), + amount_captured, updated_by: storage_scheme.to_string(), }, Err(ref error) => PaymentIntentUpdate::ConfirmIntentPostUpdate { @@ -438,6 +459,7 @@ impl .attempt_status .map(common_enums::IntentStatus::from) .unwrap_or(common_enums::IntentStatus::Failed), + amount_captured, updated_by: storage_scheme.to_string(), }, } @@ -445,8 +467,11 @@ impl fn get_payment_attempt_update( &self, + payment_data: &payments::PaymentConfirmData, storage_scheme: common_enums::MerchantStorageScheme, ) -> PaymentAttemptUpdate { + let amount_capturable = self.get_amount_capturable(payment_data); + match self.response { Ok(ref response_router_data) => match response_router_data { router_response_types::PaymentsResponseData::TransactionResponse { @@ -459,7 +484,8 @@ impl incremental_authorization_allowed, charge_id, } => { - let attempt_status = self.status; + let attempt_status = self.get_attempt_status_for_db_update(payment_data); + let connector_payment_id = match resource_id { router_request_types::ResponseId::NoResponseId => None, router_request_types::ResponseId::ConnectorTransactionId(id) @@ -471,6 +497,7 @@ impl connector_payment_id, updated_by: storage_scheme.to_string(), redirection_data: *redirection_data.clone(), + amount_capturable, connector_metadata: connector_metadata.clone().map(Secret::new), } } @@ -524,16 +551,310 @@ impl PaymentAttemptUpdate::ErrorUpdate { status: attempt_status, error: error_details, + amount_capturable, connector_payment_id: connector_transaction_id, updated_by: storage_scheme.to_string(), } } } } + + fn get_attempt_status_for_db_update( + &self, + _payment_data: &payments::PaymentConfirmData, + ) -> common_enums::AttemptStatus { + // For this step, consider whatever status was given by the connector moudle + // We do not need to check for amount captured or amount capturable here because we are authorizing the whole amount + self.status + } + + fn get_amount_capturable( + &self, + payment_data: &payments::PaymentConfirmData, + ) -> Option { + // Based on the status of the response, we can determine the amount capturable + let intent_status = common_enums::IntentStatus::from(self.status); + match intent_status { + // If the status is already succeeded / failed we cannot capture any more amount + // So set the amount capturable to zero + common_enums::IntentStatus::Succeeded + | common_enums::IntentStatus::Failed + | common_enums::IntentStatus::Cancelled => Some(MinorUnit::zero()), + // For these statuses, update the capturable amount when it reaches terminal / capturable state + common_enums::IntentStatus::RequiresCustomerAction + | common_enums::IntentStatus::RequiresMerchantAction + | common_enums::IntentStatus::Processing => None, + // Invalid states for this flow + common_enums::IntentStatus::RequiresPaymentMethod + | common_enums::IntentStatus::RequiresConfirmation => None, + // If status is requires capture, get the total amount that can be captured + // This is in cases where the capture method will be `manual` or `manual_multiple` + // We do not need to handle the case where amount_to_capture is provided here as it cannot be passed in authroize flow + common_enums::IntentStatus::RequiresCapture => { + let total_amount = payment_data.payment_attempt.amount_details.get_net_amount(); + Some(total_amount) + } + // Invalid statues for this flow, after doing authorization this state is invalid + common_enums::IntentStatus::PartiallyCaptured + | common_enums::IntentStatus::PartiallyCapturedAndCapturable => None, + } + } + + fn get_captured_amount( + &self, + payment_data: &payments::PaymentConfirmData, + ) -> Option { + // Based on the status of the response, we can determine the amount that was captured + let intent_status = common_enums::IntentStatus::from(self.status); + match intent_status { + // If the status is succeeded then we have captured the whole amount + // we need not check for `amount_to_capture` here because passing `amount_to_capture` when authorizing is not supported + common_enums::IntentStatus::Succeeded => { + let total_amount = payment_data.payment_attempt.amount_details.get_net_amount(); + Some(total_amount) + } + // No amount is captured + common_enums::IntentStatus::Cancelled | common_enums::IntentStatus::Failed => { + Some(MinorUnit::zero()) + } + // For these statuses, update the amount captured when it reaches terminal state + common_enums::IntentStatus::RequiresCustomerAction + | common_enums::IntentStatus::RequiresMerchantAction + | common_enums::IntentStatus::Processing => None, + // Invalid states for this flow + common_enums::IntentStatus::RequiresPaymentMethod + | common_enums::IntentStatus::RequiresConfirmation => None, + // No amount has been captured yet + common_enums::IntentStatus::RequiresCapture => Some(MinorUnit::zero()), + // Invalid statues for this flow + common_enums::IntentStatus::PartiallyCaptured + | common_enums::IntentStatus::PartiallyCapturedAndCapturable => None, + } + } } #[cfg(feature = "v2")] -impl TrackerPostUpdateObjects +impl + TrackerPostUpdateObjects< + router_flow_types::Capture, + router_request_types::PaymentsCaptureData, + payments::PaymentCaptureData, + > + for RouterData< + router_flow_types::Capture, + router_request_types::PaymentsCaptureData, + router_response_types::PaymentsResponseData, + > +{ + fn get_payment_intent_update( + &self, + payment_data: &payments::PaymentCaptureData, + storage_scheme: common_enums::MerchantStorageScheme, + ) -> PaymentIntentUpdate { + let amount_captured = self.get_captured_amount(payment_data); + match self.response { + Ok(ref _response) => PaymentIntentUpdate::CaptureUpdate { + status: common_enums::IntentStatus::from( + self.get_attempt_status_for_db_update(payment_data), + ), + amount_captured, + updated_by: storage_scheme.to_string(), + }, + Err(ref error) => PaymentIntentUpdate::CaptureUpdate { + status: error + .attempt_status + .map(common_enums::IntentStatus::from) + .unwrap_or(common_enums::IntentStatus::Failed), + amount_captured, + updated_by: storage_scheme.to_string(), + }, + } + } + + fn get_payment_attempt_update( + &self, + payment_data: &payments::PaymentCaptureData, + storage_scheme: common_enums::MerchantStorageScheme, + ) -> PaymentAttemptUpdate { + let amount_capturable = self.get_amount_capturable(payment_data); + + match self.response { + Ok(ref response_router_data) => match response_router_data { + router_response_types::PaymentsResponseData::TransactionResponse { + resource_id, + redirection_data, + mandate_reference, + connector_metadata, + network_txn_id, + connector_response_reference_id, + incremental_authorization_allowed, + charge_id, + } => { + let attempt_status = self.status; + + PaymentAttemptUpdate::CaptureUpdate { + status: attempt_status, + amount_capturable, + updated_by: storage_scheme.to_string(), + } + } + router_response_types::PaymentsResponseData::MultipleCaptureResponse { .. } => { + todo!() + } + router_response_types::PaymentsResponseData::SessionResponse { .. } => todo!(), + router_response_types::PaymentsResponseData::SessionTokenResponse { .. } => todo!(), + router_response_types::PaymentsResponseData::TransactionUnresolvedResponse { + .. + } => todo!(), + router_response_types::PaymentsResponseData::TokenizationResponse { .. } => todo!(), + router_response_types::PaymentsResponseData::ConnectorCustomerResponse { + .. + } => todo!(), + router_response_types::PaymentsResponseData::ThreeDSEnrollmentResponse { + .. + } => todo!(), + router_response_types::PaymentsResponseData::PreProcessingResponse { .. } => { + todo!() + } + router_response_types::PaymentsResponseData::IncrementalAuthorizationResponse { + .. + } => todo!(), + router_response_types::PaymentsResponseData::PostProcessingResponse { .. } => { + todo!() + } + router_response_types::PaymentsResponseData::SessionUpdateResponse { .. } => { + todo!() + } + }, + Err(ref error_response) => { + let ErrorResponse { + code, + message, + reason, + status_code: _, + attempt_status, + connector_transaction_id, + } = error_response.clone(); + let attempt_status = attempt_status.unwrap_or(self.status); + + let error_details = ErrorDetails { + code, + message, + reason, + unified_code: None, + unified_message: None, + }; + + PaymentAttemptUpdate::ErrorUpdate { + status: attempt_status, + error: error_details, + amount_capturable, + connector_payment_id: connector_transaction_id, + updated_by: storage_scheme.to_string(), + } + } + } + } + + fn get_attempt_status_for_db_update( + &self, + payment_data: &payments::PaymentCaptureData, + ) -> common_enums::AttemptStatus { + match self.status { + common_enums::AttemptStatus::Charged => { + let amount_captured = self + .get_captured_amount(payment_data) + .unwrap_or(MinorUnit::zero()); + let total_amount = payment_data.payment_attempt.amount_details.get_net_amount(); + + if amount_captured == total_amount { + common_enums::AttemptStatus::Charged + } else { + common_enums::AttemptStatus::PartialCharged + } + } + _ => self.status, + } + } + + fn get_amount_capturable( + &self, + payment_data: &payments::PaymentCaptureData, + ) -> Option { + // Based on the status of the response, we can determine the amount capturable + let intent_status = common_enums::IntentStatus::from(self.status); + match intent_status { + // If the status is already succeeded / failed we cannot capture any more amount + common_enums::IntentStatus::Succeeded + | common_enums::IntentStatus::Failed + | common_enums::IntentStatus::Cancelled => Some(MinorUnit::zero()), + // For these statuses, update the capturable amount when it reaches terminal / capturable state + common_enums::IntentStatus::RequiresCustomerAction + | common_enums::IntentStatus::RequiresMerchantAction + | common_enums::IntentStatus::Processing => None, + // Invalid states for this flow + common_enums::IntentStatus::RequiresPaymentMethod + | common_enums::IntentStatus::RequiresConfirmation => None, + common_enums::IntentStatus::RequiresCapture => { + let total_amount = payment_data.payment_attempt.amount_details.get_net_amount(); + Some(total_amount) + } + // Invalid statues for this flow + common_enums::IntentStatus::PartiallyCaptured + | common_enums::IntentStatus::PartiallyCapturedAndCapturable => None, + } + } + + fn get_captured_amount( + &self, + payment_data: &payments::PaymentCaptureData, + ) -> Option { + // Based on the status of the response, we can determine the amount capturable + let intent_status = common_enums::IntentStatus::from(self.status); + match intent_status { + // If the status is succeeded then we have captured the whole amount + common_enums::IntentStatus::Succeeded => { + let amount_to_capture = payment_data + .payment_attempt + .amount_details + .get_amount_to_capture(); + + let amount_captured = amount_to_capture + .unwrap_or(payment_data.payment_attempt.amount_details.get_net_amount()); + + Some(amount_captured) + } + // No amount is captured + common_enums::IntentStatus::Cancelled | common_enums::IntentStatus::Failed => { + Some(MinorUnit::zero()) + } + common_enums::IntentStatus::RequiresCapture => { + let total_amount = payment_data.payment_attempt.amount_details.get_net_amount(); + Some(total_amount) + } + // For these statuses, update the amount captured when it reaches terminal state + common_enums::IntentStatus::RequiresCustomerAction + | common_enums::IntentStatus::RequiresMerchantAction + | common_enums::IntentStatus::Processing => None, + // Invalid states for this flow + common_enums::IntentStatus::RequiresPaymentMethod + | common_enums::IntentStatus::RequiresConfirmation => None, + // Invalid statues for this flow + common_enums::IntentStatus::PartiallyCaptured + | common_enums::IntentStatus::PartiallyCapturedAndCapturable => { + todo!() + } + } + } +} + +#[cfg(feature = "v2")] +impl + TrackerPostUpdateObjects< + router_flow_types::PSync, + router_request_types::PaymentsSyncData, + payments::PaymentStatusData, + > for RouterData< router_flow_types::PSync, router_request_types::PaymentsSyncData, @@ -542,11 +863,16 @@ impl TrackerPostUpdateObjects, storage_scheme: common_enums::MerchantStorageScheme, ) -> PaymentIntentUpdate { + let amount_captured = self.get_captured_amount(payment_data); match self.response { Ok(ref _response) => PaymentIntentUpdate::SyncUpdate { - status: common_enums::IntentStatus::from(self.status), + status: common_enums::IntentStatus::from( + self.get_attempt_status_for_db_update(payment_data), + ), + amount_captured, updated_by: storage_scheme.to_string(), }, Err(ref error) => PaymentIntentUpdate::SyncUpdate { @@ -554,6 +880,7 @@ impl TrackerPostUpdateObjects, storage_scheme: common_enums::MerchantStorageScheme, ) -> PaymentAttemptUpdate { + let amount_capturable = self.get_amount_capturable(payment_data); + match self.response { Ok(ref response_router_data) => match response_router_data { router_response_types::PaymentsResponseData::TransactionResponse { @@ -575,15 +905,11 @@ impl TrackerPostUpdateObjects { - let attempt_status = self.status; - let connector_payment_id = match resource_id { - router_request_types::ResponseId::NoResponseId => None, - router_request_types::ResponseId::ConnectorTransactionId(id) - | router_request_types::ResponseId::EncodedData(id) => Some(id.to_owned()), - }; + let attempt_status = self.get_attempt_status_for_db_update(payment_data); PaymentAttemptUpdate::SyncUpdate { status: attempt_status, + amount_capturable, updated_by: storage_scheme.to_string(), } } @@ -637,10 +963,110 @@ impl TrackerPostUpdateObjects, + ) -> common_enums::AttemptStatus { + match self.status { + common_enums::AttemptStatus::Charged => { + let amount_captured = self + .get_captured_amount(payment_data) + .unwrap_or(MinorUnit::zero()); + + let total_amount = payment_data + .payment_attempt + .as_ref() + .map(|attempt| attempt.amount_details.get_net_amount()) + .unwrap_or(MinorUnit::zero()); + + if amount_captured == total_amount { + common_enums::AttemptStatus::Charged + } else { + common_enums::AttemptStatus::PartialCharged + } + } + _ => self.status, + } + } + + fn get_amount_capturable( + &self, + payment_data: &payments::PaymentStatusData, + ) -> Option { + let Some(payment_attempt) = payment_data.payment_attempt.as_ref() else { + return None; + }; + + // Based on the status of the response, we can determine the amount capturable + let intent_status = common_enums::IntentStatus::from(self.status); + match intent_status { + // If the status is already succeeded / failed we cannot capture any more amount + common_enums::IntentStatus::Succeeded + | common_enums::IntentStatus::Failed + | common_enums::IntentStatus::Cancelled => Some(MinorUnit::zero()), + // For these statuses, update the capturable amount when it reaches terminal / capturable state + common_enums::IntentStatus::RequiresCustomerAction + | common_enums::IntentStatus::RequiresMerchantAction + | common_enums::IntentStatus::Processing => None, + // Invalid states for this flow + common_enums::IntentStatus::RequiresPaymentMethod + | common_enums::IntentStatus::RequiresConfirmation => None, + common_enums::IntentStatus::RequiresCapture => { + let total_amount = payment_attempt.amount_details.get_net_amount(); + Some(total_amount) + } + // Invalid statues for this flow + common_enums::IntentStatus::PartiallyCaptured + | common_enums::IntentStatus::PartiallyCapturedAndCapturable => None, + } + } + + fn get_captured_amount( + &self, + payment_data: &payments::PaymentStatusData, + ) -> Option { + let Some(payment_attempt) = payment_data.payment_attempt.as_ref() else { + return None; + }; + + // Based on the status of the response, we can determine the amount capturable + let intent_status = common_enums::IntentStatus::from(self.status); + match intent_status { + // If the status is succeeded then we have captured the whole amount or amount_to_capture + common_enums::IntentStatus::Succeeded => { + let amount_to_capture = payment_attempt.amount_details.get_amount_to_capture(); + + let amount_captured = + amount_to_capture.unwrap_or(payment_attempt.amount_details.get_net_amount()); + + Some(amount_captured) + } + // No amount is captured + common_enums::IntentStatus::Cancelled | common_enums::IntentStatus::Failed => { + Some(MinorUnit::zero()) + } + // For these statuses, update the amount captured when it reaches terminal state + common_enums::IntentStatus::RequiresCustomerAction + | common_enums::IntentStatus::RequiresMerchantAction + | common_enums::IntentStatus::Processing => None, + // Invalid states for this flow + common_enums::IntentStatus::RequiresPaymentMethod + | common_enums::IntentStatus::RequiresConfirmation => None, + common_enums::IntentStatus::RequiresCapture => { + let total_amount = payment_attempt.amount_details.get_net_amount(); + Some(total_amount) + } + // Invalid statues for this flow + common_enums::IntentStatus::PartiallyCaptured + | common_enums::IntentStatus::PartiallyCapturedAndCapturable => None, + } + } } diff --git a/crates/openapi/src/openapi_v2.rs b/crates/openapi/src/openapi_v2.rs index 17c004169336..b451c3c1d773 100644 --- a/crates/openapi/src/openapi_v2.rs +++ b/crates/openapi/src/openapi_v2.rs @@ -602,7 +602,7 @@ Never share your secret api keys. Keep them guarded and secure. api_models::payments::DisplayAmountOnSdk, api_models::payments::ErrorDetails, common_utils::types::BrowserInformation, - api_models::payments::ConfirmIntentAmountDetailsResponse, + api_models::payments::PaymentAmountDetailsResponse, routes::payments::ForceSync, )), modifiers(&SecurityAddon) diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs index 5ac8f454c21f..4deb38962c58 100644 --- a/crates/router/src/core/payments.rs +++ b/crates/router/src/core/payments.rs @@ -37,7 +37,7 @@ use futures::future::join_all; use helpers::{decrypt_paze_token, ApplePayData}; #[cfg(feature = "v2")] use hyperswitch_domain_models::payments::{ - PaymentConfirmData, PaymentIntentData, PaymentStatusData, + PaymentCaptureData, PaymentConfirmData, PaymentIntentData, PaymentStatusData, }; #[cfg(feature = "v2")] use hyperswitch_domain_models::router_response_types::RedirectForm; @@ -144,7 +144,7 @@ where services::api::ConnectorIntegration, RouterData: - hyperswitch_domain_models::router_data::TrackerPostUpdateObjects, + hyperswitch_domain_models::router_data::TrackerPostUpdateObjects, // To perform router related operation for PaymentResponse PaymentResponse: Operation, @@ -1482,8 +1482,12 @@ where FData: Send + Sync + Clone, Op: Operation + Send + Sync + Clone, Req: Debug, - D: OperationSessionGetters + OperationSessionSetters + Send + Sync + Clone, - Res: transformers::ToResponse, + D: OperationSessionGetters + + OperationSessionSetters + + transformers::GenerateResponse + + Send + + Sync + + Clone, // To create connector flow specific interface data D: ConstructFlowSpecificData, RouterData: Feature, @@ -1497,13 +1501,14 @@ where // To create updatable objects in post update tracker RouterData: - hyperswitch_domain_models::router_data::TrackerPostUpdateObjects, + hyperswitch_domain_models::router_data::TrackerPostUpdateObjects, { // Validate the request fields - let validate_result = operation + operation .to_validate_request()? .validate_request(&req, &merchant_account)?; + // Get the tracker related information. This includes payment intent and payment attempt let get_tracker_response = operation .to_get_tracker()? .get_trackers( @@ -1532,12 +1537,8 @@ where ) .await?; - Res::generate_response( - payment_data, - customer, - &state.base_url, - operation, - &state.conf.connector_request_reference_id_config, + payment_data.generate_response( + &state, connector_http_status_code, external_latency, header_payload.x_hs_latency, @@ -6351,7 +6352,7 @@ pub async fn payment_start_redirection( services::RedirectionFormData { redirect_form: redirection_data, payment_method_data: None, - amount: payment_attempt.amount_details.net_amount.to_string(), + amount: payment_attempt.amount_details.get_net_amount().to_string(), currency: payment_intent.amount_details.currency.to_string(), }, ))) @@ -7515,3 +7516,218 @@ impl OperationSessionSetters for PaymentStatusData { todo!() } } + +#[cfg(feature = "v2")] +impl OperationSessionGetters for PaymentCaptureData { + #[track_caller] + fn get_payment_attempt(&self) -> &storage::PaymentAttempt { + &self.payment_attempt + } + + fn get_payment_intent(&self) -> &storage::PaymentIntent { + &self.payment_intent + } + + fn get_payment_method_info(&self) -> Option<&domain::PaymentMethod> { + todo!() + } + + fn get_mandate_id(&self) -> Option<&payments_api::MandateIds> { + todo!() + } + + // what is this address find out and not required remove this + fn get_address(&self) -> &PaymentAddress { + todo!() + } + + fn get_creds_identifier(&self) -> Option<&str> { + None + } + + fn get_token(&self) -> Option<&str> { + todo!() + } + + fn get_multiple_capture_data(&self) -> Option<&types::MultipleCaptureData> { + todo!() + } + + fn get_payment_link_data(&self) -> Option { + todo!() + } + + fn get_ephemeral_key(&self) -> Option { + todo!() + } + + fn get_setup_mandate(&self) -> Option<&MandateData> { + todo!() + } + + fn get_poll_config(&self) -> Option { + todo!() + } + + fn get_authentication(&self) -> Option<&storage::Authentication> { + todo!() + } + + fn get_frm_message(&self) -> Option { + todo!() + } + + fn get_refunds(&self) -> Vec { + todo!() + } + + fn get_disputes(&self) -> Vec { + todo!() + } + + fn get_authorizations(&self) -> Vec { + todo!() + } + + fn get_attempts(&self) -> Option> { + todo!() + } + + fn get_recurring_details(&self) -> Option<&RecurringDetails> { + todo!() + } + + fn get_payment_intent_profile_id(&self) -> Option<&id_type::ProfileId> { + Some(&self.payment_intent.profile_id) + } + + fn get_currency(&self) -> storage_enums::Currency { + self.payment_intent.amount_details.currency + } + + fn get_amount(&self) -> api::Amount { + todo!() + } + + fn get_payment_attempt_connector(&self) -> Option<&str> { + todo!() + } + + fn get_billing_address(&self) -> Option { + todo!() + } + + fn get_payment_method_data(&self) -> Option<&domain::PaymentMethodData> { + todo!() + } + + fn get_sessions_token(&self) -> Vec { + todo!() + } + + fn get_token_data(&self) -> Option<&storage::PaymentTokenData> { + todo!() + } + + fn get_mandate_connector(&self) -> Option<&MandateConnectorDetails> { + todo!() + } + + fn get_force_sync(&self) -> Option { + todo!() + } + + fn get_capture_method(&self) -> Option { + todo!() + } + + #[cfg(feature = "v2")] + fn get_optional_payment_attempt(&self) -> Option<&storage::PaymentAttempt> { + Some(&self.payment_attempt) + } +} + +#[cfg(feature = "v2")] +impl OperationSessionSetters for PaymentCaptureData { + fn set_payment_intent(&mut self, payment_intent: storage::PaymentIntent) { + self.payment_intent = payment_intent; + } + + fn set_payment_attempt(&mut self, payment_attempt: storage::PaymentAttempt) { + self.payment_attempt = payment_attempt; + } + + fn set_payment_method_data(&mut self, _payment_method_data: Option) { + todo!() + } + + fn set_payment_method_id_in_attempt(&mut self, _payment_method_id: Option) { + todo!() + } + + fn set_email_if_not_present(&mut self, _email: pii::Email) { + todo!() + } + + fn set_pm_token(&mut self, _token: String) { + todo!() + } + + fn set_connector_customer_id(&mut self, _customer_id: Option) { + // TODO: handle this case. Should we add connector_customer_id in paymentConfirmData? + } + + fn push_sessions_token(&mut self, _token: api::SessionToken) { + todo!() + } + + fn set_surcharge_details(&mut self, _surcharge_details: Option) { + todo!() + } + + #[track_caller] + fn set_merchant_connector_id_in_attempt( + &mut self, + merchant_connector_id: Option, + ) { + todo!() + } + + fn set_frm_message(&mut self, _frm_message: FraudCheck) { + todo!() + } + + fn set_payment_intent_status(&mut self, status: storage_enums::IntentStatus) { + self.payment_intent.status = status; + } + + fn set_authentication_type_in_attempt( + &mut self, + _authentication_type: Option, + ) { + todo!() + } + + fn set_recurring_mandate_payment_data( + &mut self, + _recurring_mandate_payment_data: + hyperswitch_domain_models::router_data::RecurringMandatePaymentData, + ) { + todo!() + } + + fn set_mandate_id(&mut self, _mandate_id: api_models::payments::MandateIds) { + todo!() + } + + fn set_setup_future_usage_in_payment_intent( + &mut self, + setup_future_usage: storage_enums::FutureUsage, + ) { + self.payment_intent.setup_future_usage = setup_future_usage; + } + + fn set_connector_in_payment_attempt(&mut self, connector: Option) { + todo!() + } +} diff --git a/crates/router/src/core/payments/flows/capture_flow.rs b/crates/router/src/core/payments/flows/capture_flow.rs index 8b6fa24fbfd7..1863d673ee9c 100644 --- a/crates/router/src/core/payments/flows/capture_flow.rs +++ b/crates/router/src/core/payments/flows/capture_flow.rs @@ -11,12 +11,12 @@ use crate::{ types::{self, api, domain}, }; +#[cfg(feature = "v1")] #[async_trait] impl ConstructFlowSpecificData for PaymentData { - #[cfg(feature = "v1")] async fn construct_router_data<'a>( &self, state: &SessionState, @@ -45,7 +45,24 @@ impl .await } - #[cfg(feature = "v2")] + async fn get_merchant_recipient_data<'a>( + &self, + _state: &SessionState, + _merchant_account: &domain::MerchantAccount, + _key_store: &domain::MerchantKeyStore, + _merchant_connector_account: &helpers::MerchantConnectorAccountType, + _connector: &api::ConnectorData, + ) -> RouterResult> { + Ok(None) + } +} + +#[cfg(feature = "v2")] +#[async_trait] +impl + ConstructFlowSpecificData + for hyperswitch_domain_models::payments::PaymentCaptureData +{ async fn construct_router_data<'a>( &self, state: &SessionState, @@ -56,8 +73,21 @@ impl merchant_connector_account: &domain::MerchantConnectorAccount, merchant_recipient_data: Option, header_payload: Option, - ) -> RouterResult { - todo!() + ) -> RouterResult< + types::RouterData, + > { + Box::pin(transformers::construct_payment_router_data_for_capture( + state, + self.clone(), + connector_id, + merchant_account, + key_store, + customer, + merchant_connector_account, + merchant_recipient_data, + header_payload, + )) + .await } async fn get_merchant_recipient_data<'a>( diff --git a/crates/router/src/core/payments/operations.rs b/crates/router/src/core/payments/operations.rs index e936f3725455..7cfe049fa142 100644 --- a/crates/router/src/core/payments/operations.rs +++ b/crates/router/src/core/payments/operations.rs @@ -38,6 +38,9 @@ pub mod payment_get_intent; #[cfg(feature = "v2")] pub mod payment_get; +#[cfg(feature = "v2")] +pub mod payment_capture_v2; + use api_models::enums::FrmSuggestion; #[cfg(all(feature = "v1", feature = "dynamic_routing"))] use api_models::routing::RoutableConnectorChoice; @@ -420,7 +423,7 @@ pub trait PostUpdateTracker: Send { where F: 'b + Send + Sync, types::RouterData: - hyperswitch_domain_models::router_data::TrackerPostUpdateObjects; + hyperswitch_domain_models::router_data::TrackerPostUpdateObjects; async fn save_pm_and_mandate<'b>( &self, diff --git a/crates/router/src/core/payments/operations/payment_capture_v2.rs b/crates/router/src/core/payments/operations/payment_capture_v2.rs new file mode 100644 index 000000000000..89594a44a67d --- /dev/null +++ b/crates/router/src/core/payments/operations/payment_capture_v2.rs @@ -0,0 +1,321 @@ +use api_models::{enums::FrmSuggestion, payments::PaymentsCaptureRequest}; +use async_trait::async_trait; +use error_stack::ResultExt; +use hyperswitch_domain_models::payments::PaymentCaptureData; +use router_env::{instrument, tracing}; + +use super::{Domain, GetTracker, Operation, UpdateTracker, ValidateRequest}; +use crate::{ + core::{ + errors::{self, CustomResult, RouterResult, StorageErrorExt}, + payments::{ + self, helpers, + operations::{self, ValidateStatusForOperation}, + populate_surcharge_details, CustomerDetails, PaymentAddress, PaymentData, + }, + utils as core_utils, + }, + routes::{app::ReqState, SessionState}, + services, + types::{ + self, + api::{self, ConnectorCallType, PaymentIdTypeExt}, + domain::{self}, + storage::{self, enums as storage_enums}, + }, + utils::{self, OptionExt}, +}; + +#[derive(Debug, Clone, Copy)] +pub struct PaymentsCapture; + +impl ValidateStatusForOperation for PaymentsCapture { + /// Validate if the current operation can be performed on the current status of the payment intent + fn validate_status_for_operation( + &self, + intent_status: common_enums::IntentStatus, + ) -> Result<(), errors::ApiErrorResponse> { + match intent_status { + common_enums::IntentStatus::RequiresCapture + | common_enums::IntentStatus::PartiallyCapturedAndCapturable => Ok(()), + common_enums::IntentStatus::Succeeded + | common_enums::IntentStatus::Failed + | common_enums::IntentStatus::Cancelled + | common_enums::IntentStatus::Processing + | common_enums::IntentStatus::RequiresCustomerAction + | common_enums::IntentStatus::RequiresMerchantAction + | common_enums::IntentStatus::RequiresPaymentMethod + | common_enums::IntentStatus::PartiallyCaptured + | common_enums::IntentStatus::RequiresConfirmation => { + Err(errors::ApiErrorResponse::PaymentUnexpectedState { + current_flow: format!("{self:?}"), + field_name: "status".to_string(), + current_value: intent_status.to_string(), + states: [ + common_enums::IntentStatus::RequiresCapture, + common_enums::IntentStatus::PartiallyCapturedAndCapturable, + ] + .map(|enum_value| enum_value.to_string()) + .join(", "), + }) + } + } + } +} + +type BoxedConfirmOperation<'b, F> = + super::BoxedOperation<'b, F, PaymentsCaptureRequest, PaymentCaptureData>; + +// TODO: change the macro to include changes for v2 +// TODO: PaymentData in the macro should be an input +impl Operation for &PaymentsCapture { + type Data = PaymentCaptureData; + fn to_validate_request( + &self, + ) -> RouterResult<&(dyn ValidateRequest + Send + Sync)> + { + Ok(*self) + } + fn to_get_tracker( + &self, + ) -> RouterResult<&(dyn GetTracker + Send + Sync)> { + Ok(*self) + } + fn to_domain(&self) -> RouterResult<&(dyn Domain)> { + Ok(*self) + } + fn to_update_tracker( + &self, + ) -> RouterResult<&(dyn UpdateTracker + Send + Sync)> + { + Ok(*self) + } +} +#[automatically_derived] +impl Operation for PaymentsCapture { + type Data = PaymentCaptureData; + fn to_validate_request( + &self, + ) -> RouterResult<&(dyn ValidateRequest + Send + Sync)> + { + Ok(self) + } + fn to_get_tracker( + &self, + ) -> RouterResult<&(dyn GetTracker + Send + Sync)> { + Ok(self) + } + fn to_domain(&self) -> RouterResult<&dyn Domain> { + Ok(self) + } + fn to_update_tracker( + &self, + ) -> RouterResult<&(dyn UpdateTracker + Send + Sync)> + { + Ok(self) + } +} + +impl ValidateRequest> + for PaymentsCapture +{ + #[instrument(skip_all)] + fn validate_request<'a, 'b>( + &'b self, + request: &PaymentsCaptureRequest, + merchant_account: &'a domain::MerchantAccount, + ) -> RouterResult { + let validate_result = operations::ValidateResult { + merchant_id: merchant_account.get_id().to_owned(), + storage_scheme: merchant_account.storage_scheme, + requeue: false, + }; + + Ok(validate_result) + } +} + +#[async_trait] +impl GetTracker, PaymentsCaptureRequest> + for PaymentsCapture +{ + #[instrument(skip_all)] + async fn get_trackers<'a>( + &'a self, + state: &'a SessionState, + payment_id: &common_utils::id_type::GlobalPaymentId, + request: &PaymentsCaptureRequest, + merchant_account: &domain::MerchantAccount, + _profile: &domain::Profile, + key_store: &domain::MerchantKeyStore, + header_payload: &hyperswitch_domain_models::payments::HeaderPayload, + ) -> RouterResult>> { + let db = &*state.store; + let key_manager_state = &state.into(); + + let storage_scheme = merchant_account.storage_scheme; + + let payment_intent = db + .find_payment_intent_by_id(key_manager_state, payment_id, key_store, storage_scheme) + .await + .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?; + + self.validate_status_for_operation(payment_intent.status)?; + + let active_attempt_id = payment_intent + .active_attempt_id + .as_ref() + .get_required_value("active_attempt_id") + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Active attempt id is none when capturing the payment")?; + + let mut payment_attempt = db + .find_payment_attempt_by_id( + key_manager_state, + key_store, + active_attempt_id, + storage_scheme, + ) + .await + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Could not find payment attempt given the attempt id")?; + + if let Some(amount_to_capture) = request.amount_to_capture { + payment_attempt + .amount_details + .set_amount_to_capture(amount_to_capture); + } + + let payment_data = PaymentCaptureData { + flow: std::marker::PhantomData, + payment_intent, + payment_attempt, + }; + + let get_trackers_response = operations::GetTrackerResponse { payment_data }; + + Ok(get_trackers_response) + } +} + +#[async_trait] +impl Domain> for PaymentsCapture { + async fn get_customer_details<'a>( + &'a self, + state: &SessionState, + payment_data: &mut PaymentCaptureData, + merchant_key_store: &domain::MerchantKeyStore, + storage_scheme: storage_enums::MerchantStorageScheme, + ) -> CustomResult<(BoxedConfirmOperation<'a, F>, Option), errors::StorageError> + { + match payment_data.payment_intent.customer_id.clone() { + Some(id) => { + let customer = state + .store + .find_customer_by_global_id( + &state.into(), + id.get_string_repr(), + &payment_data.payment_intent.merchant_id, + merchant_key_store, + storage_scheme, + ) + .await?; + + Ok((Box::new(self), Some(customer))) + } + None => Ok((Box::new(self), None)), + } + } + + #[instrument(skip_all)] + async fn make_pm_data<'a>( + &'a self, + state: &'a SessionState, + payment_data: &mut PaymentCaptureData, + storage_scheme: storage_enums::MerchantStorageScheme, + key_store: &domain::MerchantKeyStore, + customer: &Option, + business_profile: &domain::Profile, + ) -> RouterResult<( + BoxedConfirmOperation<'a, F>, + Option, + Option, + )> { + Ok((Box::new(self), None, None)) + } + + #[instrument(skip_all)] + async fn perform_routing<'a>( + &'a self, + merchant_account: &domain::MerchantAccount, + business_profile: &domain::Profile, + state: &SessionState, + // TODO: do not take the whole payment data here + payment_data: &mut PaymentCaptureData, + mechant_key_store: &domain::MerchantKeyStore, + ) -> CustomResult { + let payment_attempt = &payment_data.payment_attempt; + let connector = payment_attempt + .connector + .as_ref() + .get_required_value("connector") + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Connector is none when constructing response")?; + + let merchant_connector_id = payment_attempt + .merchant_connector_id + .as_ref() + .get_required_value("merchant_connector_id") + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Merchant connector id is none when constructing response")?; + + let connector_data = api::ConnectorData::get_connector_by_name( + &state.conf.connectors, + connector, + api::GetToken::Connector, + Some(merchant_connector_id.to_owned()), + ) + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Invalid connector name received")?; + + Ok(ConnectorCallType::PreDetermined(connector_data)) + } +} + +#[async_trait] +impl UpdateTracker, PaymentsCaptureRequest> for PaymentsCapture { + #[instrument(skip_all)] + async fn update_trackers<'b>( + &'b self, + state: &'b SessionState, + req_state: ReqState, + mut payment_data: PaymentCaptureData, + customer: Option, + storage_scheme: storage_enums::MerchantStorageScheme, + updated_customer: Option, + key_store: &domain::MerchantKeyStore, + frm_suggestion: Option, + header_payload: hyperswitch_domain_models::payments::HeaderPayload, + ) -> RouterResult<(BoxedConfirmOperation<'b, F>, PaymentCaptureData)> + where + F: 'b + Send, + { + let payment_attempt_update = hyperswitch_domain_models::payments::payment_attempt::PaymentAttemptUpdate::PreCaptureUpdate { amount_to_capture: payment_data.payment_attempt.amount_details.get_amount_to_capture(), updated_by: storage_scheme.to_string() }; + + let payment_attempt = state + .store + .update_payment_attempt( + &state.into(), + key_store, + payment_data.payment_attempt.clone(), + payment_attempt_update, + storage_scheme, + ) + .await + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Could not update payment attempt")?; + + payment_data.payment_attempt = payment_attempt; + Ok((Box::new(self), payment_data)) + } +} diff --git a/crates/router/src/core/payments/operations/payment_get.rs b/crates/router/src/core/payments/operations/payment_get.rs index a69c3187c781..2fce0ef6e678 100644 --- a/crates/router/src/core/payments/operations/payment_get.rs +++ b/crates/router/src/core/payments/operations/payment_get.rs @@ -1,38 +1,23 @@ -use api_models::{ - admin::ExtendedCardInfoConfig, - enums::FrmSuggestion, - payments::{ExtendedCardInfo, GetAddressFromPaymentMethodData, PaymentsRetrieveRequest}, -}; +use api_models::{enums::FrmSuggestion, payments::PaymentsRetrieveRequest}; use async_trait::async_trait; use common_utils::ext_traits::AsyncExt; use error_stack::ResultExt; -use hyperswitch_domain_models::payments::{ - payment_attempt::PaymentAttempt, PaymentIntent, PaymentStatusData, -}; +use hyperswitch_domain_models::payments::PaymentStatusData; use router_env::{instrument, tracing}; -use tracing_futures::Instrument; use super::{Domain, GetTracker, Operation, UpdateTracker, ValidateRequest}; use crate::{ core::{ - authentication, errors::{self, CustomResult, RouterResult, StorageErrorExt}, - payments::{ - self, helpers, - operations::{self, ValidateStatusForOperation}, - populate_surcharge_details, CustomerDetails, PaymentAddress, PaymentData, - }, - utils as core_utils, + payments::operations::{self, ValidateStatusForOperation}, }, routes::{app::ReqState, SessionState}, - services, types::{ - self, - api::{self, ConnectorCallType, PaymentIdTypeExt}, + api::{self, ConnectorCallType}, domain::{self}, storage::{self, enums as storage_enums}, }, - utils::{self, OptionExt}, + utils::OptionExt, }; #[derive(Debug, Clone, Copy)] @@ -107,7 +92,7 @@ impl ValidateRequest( &'b self, - request: &PaymentsRetrieveRequest, + _request: &PaymentsRetrieveRequest, merchant_account: &'a domain::MerchantAccount, ) -> RouterResult { let validate_result = operations::ValidateResult { @@ -131,7 +116,7 @@ impl GetTracker, PaymentsRetrieveReques merchant_account: &domain::MerchantAccount, _profile: &domain::Profile, key_store: &domain::MerchantKeyStore, - header_payload: &hyperswitch_domain_models::payments::HeaderPayload, + _header_payload: &hyperswitch_domain_models::payments::HeaderPayload, ) -> RouterResult>> { let db = &*state.store; let key_manager_state = &state.into(); @@ -208,12 +193,12 @@ impl Domain> f #[instrument(skip_all)] async fn make_pm_data<'a>( &'a self, - state: &'a SessionState, - payment_data: &mut PaymentStatusData, - storage_scheme: storage_enums::MerchantStorageScheme, - key_store: &domain::MerchantKeyStore, - customer: &Option, - business_profile: &domain::Profile, + _state: &'a SessionState, + _payment_data: &mut PaymentStatusData, + _storage_scheme: storage_enums::MerchantStorageScheme, + _key_store: &domain::MerchantKeyStore, + _customer: &Option, + _business_profile: &domain::Profile, ) -> RouterResult<( BoxedConfirmOperation<'a, F>, Option, @@ -225,12 +210,12 @@ impl Domain> f #[instrument(skip_all)] async fn perform_routing<'a>( &'a self, - merchant_account: &domain::MerchantAccount, - business_profile: &domain::Profile, + _merchant_account: &domain::MerchantAccount, + _business_profile: &domain::Profile, state: &SessionState, // TODO: do not take the whole payment data here payment_data: &mut PaymentStatusData, - mechant_key_store: &domain::MerchantKeyStore, + _mechant_key_store: &domain::MerchantKeyStore, ) -> CustomResult { match &payment_data.payment_attempt { Some(payment_attempt) if payment_data.should_sync_with_connector => { @@ -269,15 +254,15 @@ impl UpdateTracker, PaymentsRetrieveRequest> f #[instrument(skip_all)] async fn update_trackers<'b>( &'b self, - state: &'b SessionState, - req_state: ReqState, - mut payment_data: PaymentStatusData, - customer: Option, - storage_scheme: storage_enums::MerchantStorageScheme, - updated_customer: Option, - key_store: &domain::MerchantKeyStore, - frm_suggestion: Option, - header_payload: hyperswitch_domain_models::payments::HeaderPayload, + _state: &'b SessionState, + _req_state: ReqState, + payment_data: PaymentStatusData, + _customer: Option, + _storage_scheme: storage_enums::MerchantStorageScheme, + _updated_customer: Option, + _key_store: &domain::MerchantKeyStore, + _frm_suggestion: Option, + _header_payload: hyperswitch_domain_models::payments::HeaderPayload, ) -> RouterResult<(BoxedConfirmOperation<'b, F>, PaymentStatusData)> where F: 'b + Send, diff --git a/crates/router/src/core/payments/operations/payment_response.rs b/crates/router/src/core/payments/operations/payment_response.rs index 8fb36764c970..4e80a6404585 100644 --- a/crates/router/src/core/payments/operations/payment_response.rs +++ b/crates/router/src/core/payments/operations/payment_response.rs @@ -2203,6 +2203,88 @@ impl Operation for PaymentResp } } +#[cfg(feature = "v2")] +impl Operation for PaymentResponse { + type Data = hyperswitch_domain_models::payments::PaymentCaptureData; + fn to_post_update_tracker( + &self, + ) -> RouterResult< + &(dyn PostUpdateTracker + Send + Sync), + > { + Ok(self) + } +} + +#[cfg(feature = "v2")] +#[async_trait] +impl + PostUpdateTracker< + F, + hyperswitch_domain_models::payments::PaymentCaptureData, + types::PaymentsCaptureData, + > for PaymentResponse +{ + async fn update_tracker<'b>( + &'b self, + state: &'b SessionState, + mut payment_data: hyperswitch_domain_models::payments::PaymentCaptureData, + response: types::RouterData, + key_store: &domain::MerchantKeyStore, + storage_scheme: enums::MerchantStorageScheme, + ) -> RouterResult> + where + F: 'b + Send + Sync, + types::RouterData: + hyperswitch_domain_models::router_data::TrackerPostUpdateObjects< + F, + types::PaymentsCaptureData, + hyperswitch_domain_models::payments::PaymentCaptureData, + >, + { + use hyperswitch_domain_models::router_data::TrackerPostUpdateObjects; + + let db = &*state.store; + let key_manager_state = &state.into(); + + let response_router_data = response; + + let payment_intent_update = + response_router_data.get_payment_intent_update(&payment_data, storage_scheme); + + let payment_attempt_update = + response_router_data.get_payment_attempt_update(&payment_data, storage_scheme); + + let updated_payment_intent = db + .update_payment_intent( + key_manager_state, + payment_data.payment_intent, + payment_intent_update, + key_store, + storage_scheme, + ) + .await + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Unable to update payment intent")?; + + let updated_payment_attempt = db + .update_payment_attempt( + key_manager_state, + key_store, + payment_data.payment_attempt, + payment_attempt_update, + storage_scheme, + ) + .await + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Unable to update payment attempt")?; + + payment_data.payment_intent = updated_payment_intent; + payment_data.payment_attempt = updated_payment_attempt; + + Ok(payment_data) + } +} + #[cfg(feature = "v2")] #[async_trait] impl PostUpdateTracker, types::PaymentsAuthorizeData> @@ -2222,6 +2304,7 @@ impl PostUpdateTracker, types::PaymentsAuthor hyperswitch_domain_models::router_data::TrackerPostUpdateObjects< F, types::PaymentsAuthorizeData, + PaymentConfirmData, >, { use hyperswitch_domain_models::router_data::TrackerPostUpdateObjects; @@ -2231,9 +2314,10 @@ impl PostUpdateTracker, types::PaymentsAuthor let response_router_data = response; - let payment_intent_update = response_router_data.get_payment_intent_update(storage_scheme); + let payment_intent_update = + response_router_data.get_payment_intent_update(&payment_data, storage_scheme); let payment_attempt_update = - response_router_data.get_payment_attempt_update(storage_scheme); + response_router_data.get_payment_attempt_update(&payment_data, storage_scheme); let updated_payment_intent = db .update_payment_intent( @@ -2296,6 +2380,7 @@ impl PostUpdateTracker, types::PaymentsSyncDat hyperswitch_domain_models::router_data::TrackerPostUpdateObjects< F, types::PaymentsSyncData, + PaymentStatusData, >, { use hyperswitch_domain_models::router_data::TrackerPostUpdateObjects; @@ -2305,9 +2390,10 @@ impl PostUpdateTracker, types::PaymentsSyncDat let response_router_data = response; - let payment_intent_update = response_router_data.get_payment_intent_update(storage_scheme); + let payment_intent_update = + response_router_data.get_payment_intent_update(&payment_data, storage_scheme); let payment_attempt_update = - response_router_data.get_payment_attempt_update(storage_scheme); + response_router_data.get_payment_attempt_update(&payment_data, storage_scheme); let payment_attempt = payment_data .payment_attempt diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index 8a0983eccab0..44714ab62571 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -17,8 +17,6 @@ use diesel_models::{ }; use error_stack::{report, ResultExt}; #[cfg(feature = "v2")] -use hyperswitch_domain_models::payments::PaymentConfirmData; -#[cfg(feature = "v2")] use hyperswitch_domain_models::ApiModelToDieselModelConvertor; use hyperswitch_domain_models::{payments::payment_intent::CustomerData, router_request_types}; use masking::{ExposeInterface, Maskable, PeekInterface, Secret}; @@ -177,7 +175,7 @@ where #[allow(clippy::too_many_arguments)] pub async fn construct_payment_router_data_for_authorize<'a>( state: &'a SessionState, - payment_data: PaymentConfirmData, + payment_data: hyperswitch_domain_models::payments::PaymentConfirmData, connector_id: &str, merchant_account: &domain::MerchantAccount, _key_store: &domain::MerchantKeyStore, @@ -255,9 +253,9 @@ pub async fn construct_payment_router_data_for_authorize<'a>( amount: payment_data .payment_attempt .amount_details - .net_amount + .get_net_amount() .get_amount_as_i64(), - minor_amount: payment_data.payment_attempt.amount_details.net_amount, + minor_amount: payment_data.payment_attempt.amount_details.get_net_amount(), currency: payment_data.payment_intent.amount_details.currency, browser_info: None, email: None, @@ -375,6 +373,175 @@ pub async fn construct_payment_router_data_for_authorize<'a>( Ok(router_data) } +#[cfg(feature = "v2")] +#[instrument(skip_all)] +#[allow(clippy::too_many_arguments)] +pub async fn construct_payment_router_data_for_capture<'a>( + state: &'a SessionState, + payment_data: hyperswitch_domain_models::payments::PaymentCaptureData, + connector_id: &str, + merchant_account: &domain::MerchantAccount, + _key_store: &domain::MerchantKeyStore, + customer: &'a Option, + merchant_connector_account: &domain::MerchantConnectorAccount, + _merchant_recipient_data: Option, + header_payload: Option, +) -> RouterResult { + use masking::ExposeOptionInterface; + + fp_utils::when(merchant_connector_account.is_disabled(), || { + Err(errors::ApiErrorResponse::MerchantConnectorAccountDisabled) + })?; + + let auth_type = merchant_connector_account + .get_connector_account_details() + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable("Failed while parsing value for ConnectorAuthType")?; + + // TODO: Take Globalid and convert to connector reference id + let customer_id = customer + .to_owned() + .map(|customer| customer.id.clone()) + .map(std::borrow::Cow::Owned) + .map(common_utils::id_type::CustomerId::try_from) + .transpose() + .change_context(errors::ApiErrorResponse::InternalServerError) + .attach_printable( + "Invalid global customer generated, not able to convert to reference id", + )?; + + let payment_method = payment_data.payment_attempt.payment_method_type; + + let connector_request_reference_id = payment_data + .payment_intent + .merchant_reference_id + .map(|id| id.get_string_repr().to_owned()) + .unwrap_or(payment_data.payment_attempt.id.get_string_repr().to_owned()); + + let connector_mandate_request_reference_id = payment_data + .payment_attempt + .connector_mandate_detail + .as_ref() + .and_then(|detail| detail.get_connector_mandate_request_reference_id()); + + let connector = api::ConnectorData::get_connector_by_name( + &state.conf.connectors, + &connector_id, + api::GetToken::Connector, + payment_data.payment_attempt.merchant_connector_id.clone(), + )?; + + let amount_to_capture = payment_data + .payment_attempt + .amount_details + .get_amount_to_capture() + .unwrap_or(payment_data.payment_attempt.amount_details.get_net_amount()); + + let amount = payment_data.payment_attempt.amount_details.get_net_amount(); + let request = types::PaymentsCaptureData { + capture_method: Some(payment_data.payment_intent.capture_method), + amount_to_capture: amount_to_capture.get_amount_as_i64(), // This should be removed once we start moving to connector module + minor_amount_to_capture: amount_to_capture, + currency: payment_data.payment_intent.amount_details.currency, + connector_transaction_id: connector + .connector + .connector_transaction_id(payment_data.payment_attempt.clone())? + .ok_or(errors::ApiErrorResponse::ResourceIdNotFound)?, + payment_amount: amount.get_amount_as_i64(), // This should be removed once we start moving to connector module + minor_payment_amount: amount, + connector_meta: payment_data + .payment_attempt + .connector_metadata + .clone() + .expose_option(), + // TODO: add multiple capture data + multiple_capture_data: None, + // TODO: why do we need browser info during capture? + browser_info: None, + metadata: payment_data.payment_intent.metadata.expose_option(), + integrity_object: None, + }; + + // TODO: evaluate the fields in router data, if they are required or not + let router_data = types::RouterData { + flow: PhantomData, + merchant_id: merchant_account.get_id().clone(), + // TODO: evaluate why we need customer id at the connector level. We already have connector customer id. + customer_id, + connector: connector_id.to_owned(), + // TODO: evaluate why we need payment id at the connector level. We already have connector reference id + payment_id: payment_data + .payment_attempt + .payment_id + .get_string_repr() + .to_owned(), + // TODO: evaluate why we need attempt id at the connector level. We already have connector reference id + attempt_id: payment_data + .payment_attempt + .get_id() + .get_string_repr() + .to_owned(), + status: payment_data.payment_attempt.status, + payment_method, + connector_auth_type: auth_type, + description: payment_data + .payment_intent + .description + .as_ref() + .map(|description| description.get_string_repr()) + .map(ToOwned::to_owned), + // TODO: evaluate why we need to send merchant's return url here + // This should be the return url of application, since application takes care of the redirection + return_url: payment_data + .payment_intent + .return_url + .as_ref() + .map(|description| description.get_string_repr()) + .map(ToOwned::to_owned), + // TODO: Create unified address + address: hyperswitch_domain_models::payment_address::PaymentAddress::default(), + auth_type: payment_data.payment_attempt.authentication_type, + connector_meta_data: None, + connector_wallets_details: None, + request, + response: Err(hyperswitch_domain_models::router_data::ErrorResponse::default()), + amount_captured: None, + minor_amount_captured: None, + access_token: None, + session_token: None, + reference_id: None, + payment_method_status: None, + payment_method_token: None, + connector_customer: None, + recurring_mandate_payment_data: None, + // TODO: This has to be generated as the reference id based on the connector configuration + // Some connectros might not accept accept the global id. This has to be done when generating the reference id + connector_request_reference_id, + preprocessing_id: payment_data.payment_attempt.preprocessing_step_id, + #[cfg(feature = "payouts")] + payout_method_data: None, + #[cfg(feature = "payouts")] + quote_id: None, + // TODO: take this based on the env + test_mode: Some(true), + payment_method_balance: None, + connector_api_version: None, + connector_http_status_code: None, + external_latency: None, + apple_pay_flow: None, + frm_metadata: None, + refund_id: None, + dispute_id: None, + connector_response: None, + integrity_check: Ok(()), + additional_merchant_data: None, + header_payload, + connector_mandate_request_reference_id, + }; + + Ok(router_data) +} + #[cfg(feature = "v2")] #[instrument(skip_all)] #[allow(clippy::too_many_arguments)] @@ -417,7 +584,7 @@ pub async fn construct_router_data_for_psync<'a>( .unwrap_or(attempt.id.get_string_repr().to_owned()); let request = types::PaymentsSyncData { - amount: attempt.amount_details.net_amount, + amount: attempt.amount_details.get_net_amount(), integrity_object: None, mandate_id: None, connector_transaction_id: match attempt.get_connector_payment_id() { @@ -763,6 +930,57 @@ where ) -> RouterResponse; } +/// Generate a response from the given Data. This should be implemented on a payment data object +pub trait GenerateResponse +where + Self: Sized, +{ + #[cfg(feature = "v2")] + fn generate_response( + self, + state: &SessionState, + connector_http_status_code: Option, + external_latency: Option, + is_latency_header_enabled: Option, + merchant_account: &domain::MerchantAccount, + ) -> RouterResponse; +} + +#[cfg(feature = "v2")] +impl GenerateResponse + for hyperswitch_domain_models::payments::PaymentCaptureData +where + F: Clone, +{ + fn generate_response( + self, + state: &SessionState, + connector_http_status_code: Option, + external_latency: Option, + is_latency_header_enabled: Option, + merchant_account: &domain::MerchantAccount, + ) -> RouterResponse { + let payment_intent = &self.payment_intent; + let payment_attempt = &self.payment_attempt; + + let amount = api_models::payments::PaymentAmountDetailsResponse::foreign_from(( + &payment_intent.amount_details, + &payment_attempt.amount_details, + )); + + let response = api_models::payments::PaymentsCaptureResponse { + id: payment_intent.id.clone(), + amount, + status: payment_intent.status, + }; + + Ok(services::ApplicationResponse::JsonWithHeaders(( + response, + vec![], + ))) + } +} + #[cfg(feature = "v1")] impl ToResponse for api::PaymentsResponse where @@ -986,28 +1204,23 @@ where } #[cfg(feature = "v2")] -impl ToResponse for api_models::payments::PaymentsConfirmIntentResponse +impl GenerateResponse + for hyperswitch_domain_models::payments::PaymentConfirmData where F: Clone, - Op: Debug, - D: OperationSessionGetters, { - #[allow(clippy::too_many_arguments)] fn generate_response( - payment_data: D, - _customer: Option, - base_url: &str, - operation: Op, - _connector_request_reference_id_config: &ConnectorRequestReferenceIdConfig, - _connector_http_status_code: Option, - _external_latency: Option, - _is_latency_header_enabled: Option, + self, + state: &SessionState, + connector_http_status_code: Option, + external_latency: Option, + is_latency_header_enabled: Option, merchant_account: &domain::MerchantAccount, - ) -> RouterResponse { - let payment_intent = payment_data.get_payment_intent(); - let payment_attempt = payment_data.get_payment_attempt(); + ) -> RouterResponse { + let payment_intent = self.payment_intent; + let payment_attempt = self.payment_attempt; - let amount = api_models::payments::ConfirmIntentAmountDetailsResponse::foreign_from(( + let amount = api_models::payments::PaymentAmountDetailsResponse::foreign_from(( &payment_intent.amount_details, &payment_attempt.amount_details, )); @@ -1032,14 +1245,17 @@ where .map(api_models::payments::ErrorDetails::foreign_from); // TODO: Add support for other next actions, currently only supporting redirect to url - let redirect_to_url = payment_intent - .create_start_redirection_url(base_url, merchant_account.publishable_key.clone())?; + let redirect_to_url = payment_intent.create_start_redirection_url( + &state.base_url, + merchant_account.publishable_key.clone(), + )?; + let next_action = payment_attempt .redirection_data .as_ref() .map(|_| api_models::payments::NextActionData::RedirectToUrl { redirect_to_url }); - let response = Self { + let response = api_models::payments::PaymentsConfirmIntentResponse { id: payment_intent.id.clone(), status: payment_intent.status, amount, @@ -1065,43 +1281,38 @@ where } #[cfg(feature = "v2")] -impl ToResponse for api_models::payments::PaymentsRetrieveResponse +impl GenerateResponse + for hyperswitch_domain_models::payments::PaymentStatusData where F: Clone, - Op: Debug, - D: OperationSessionGetters, { - #[allow(clippy::too_many_arguments)] fn generate_response( - payment_data: D, - _customer: Option, - _base_url: &str, - operation: Op, - _connector_request_reference_id_config: &ConnectorRequestReferenceIdConfig, - _connector_http_status_code: Option, - _external_latency: Option, - _is_latency_header_enabled: Option, - _merchant_account: &domain::MerchantAccount, - ) -> RouterResponse { - let payment_intent = payment_data.get_payment_intent(); - let payment_attempt = payment_data.get_optional_payment_attempt(); + self, + state: &SessionState, + connector_http_status_code: Option, + external_latency: Option, + is_latency_header_enabled: Option, + merchant_account: &domain::MerchantAccount, + ) -> RouterResponse { + let payment_intent = self.payment_intent; + let optional_payment_attempt = self.payment_attempt.as_ref(); - let amount = api_models::payments::ConfirmIntentAmountDetailsResponse::foreign_from(( + let amount = api_models::payments::PaymentAmountDetailsResponse::foreign_from(( &payment_intent.amount_details, - payment_attempt.map(|payment_attempt| &payment_attempt.amount_details), + optional_payment_attempt.map(|payment_attempt| &payment_attempt.amount_details), )); let connector = - payment_attempt.and_then(|payment_attempt| payment_attempt.connector.clone()); + optional_payment_attempt.and_then(|payment_attempt| payment_attempt.connector.clone()); - let merchant_connector_id = payment_attempt + let merchant_connector_id = optional_payment_attempt .and_then(|payment_attempt| payment_attempt.merchant_connector_id.clone()); - let error = payment_attempt + let error = optional_payment_attempt .and_then(|payment_attempt| payment_attempt.error.clone()) .map(api_models::payments::ErrorDetails::foreign_from); - let response = Self { + let response = api_models::payments::PaymentsRetrieveResponse { id: payment_intent.id.clone(), status: payment_intent.status, amount, @@ -1109,9 +1320,11 @@ where client_secret: payment_intent.client_secret.clone(), created: payment_intent.created_at, payment_method_data: None, - payment_method_type: payment_attempt.map(|attempt| attempt.payment_method_type), - payment_method_subtype: payment_attempt.map(|attempt| attempt.payment_method_subtype), - connector_transaction_id: payment_attempt + payment_method_type: optional_payment_attempt + .map(|attempt| attempt.payment_method_type), + payment_method_subtype: optional_payment_attempt + .map(|attempt| attempt.payment_method_subtype), + connector_transaction_id: optional_payment_attempt .and_then(|attempt| attempt.connector_payment_id.clone()), connector_reference_id: None, merchant_connector_id, @@ -2655,7 +2868,44 @@ impl TryFrom> for types::PaymentsCaptureD type Error = error_stack::Report; fn try_from(additional_data: PaymentAdditionalData<'_, F>) -> Result { - todo!() + use masking::ExposeOptionInterface; + + let payment_data = additional_data.payment_data; + let connector = api::ConnectorData::get_connector_by_name( + &additional_data.state.conf.connectors, + &additional_data.connector_name, + api::GetToken::Connector, + payment_data.payment_attempt.merchant_connector_id.clone(), + )?; + let amount_to_capture = payment_data + .payment_attempt + .amount_details + .get_amount_to_capture() + .unwrap_or(payment_data.payment_attempt.get_total_amount()); + + let amount = payment_data.payment_attempt.get_total_amount(); + Ok(Self { + capture_method: payment_data.get_capture_method(), + amount_to_capture: amount_to_capture.get_amount_as_i64(), // This should be removed once we start moving to connector module + minor_amount_to_capture: amount_to_capture, + currency: payment_data.currency, + connector_transaction_id: connector + .connector + .connector_transaction_id(payment_data.payment_attempt.clone())? + .ok_or(errors::ApiErrorResponse::ResourceIdNotFound)?, + payment_amount: amount.get_amount_as_i64(), // This should be removed once we start moving to connector module + minor_payment_amount: amount, + connector_meta: payment_data + .payment_attempt + .connector_metadata + .expose_option(), + // TODO: add multiple capture data + multiple_capture_data: None, + // TODO: why do we need browser info during capture? + browser_info: None, + metadata: payment_data.payment_intent.metadata.expose_option(), + integrity_object: None, + }) } } @@ -3320,7 +3570,7 @@ impl ForeignFrom<( &hyperswitch_domain_models::payments::AmountDetails, &hyperswitch_domain_models::payments::payment_attempt::AttemptAmountDetails, - )> for api_models::payments::ConfirmIntentAmountDetailsResponse + )> for api_models::payments::PaymentAmountDetailsResponse { fn foreign_from( (intent_amount_details, attempt_amount_details): ( @@ -3331,19 +3581,19 @@ impl Self { order_amount: intent_amount_details.order_amount, currency: intent_amount_details.currency, - shipping_cost: attempt_amount_details.shipping_cost, - order_tax_amount: attempt_amount_details.order_tax_amount, + shipping_cost: attempt_amount_details.get_shipping_cost(), + order_tax_amount: attempt_amount_details.get_order_tax_amount(), skip_external_tax_calculation: common_enums::TaxCalculationOverride::foreign_from( intent_amount_details.skip_external_tax_calculation, ), skip_surcharge_calculation: common_enums::SurchargeCalculationOverride::foreign_from( intent_amount_details.skip_surcharge_calculation, ), - surcharge_amount: attempt_amount_details.surcharge_amount, - tax_on_surcharge: attempt_amount_details.tax_on_surcharge, - net_amount: attempt_amount_details.net_amount, - amount_to_capture: attempt_amount_details.amount_to_capture, - amount_capturable: attempt_amount_details.amount_capturable, + surcharge_amount: attempt_amount_details.get_surcharge_amount(), + tax_on_surcharge: attempt_amount_details.get_tax_on_surcharge(), + net_amount: attempt_amount_details.get_net_amount(), + amount_to_capture: attempt_amount_details.get_amount_to_capture(), + amount_capturable: attempt_amount_details.get_amount_capturable(), amount_captured: intent_amount_details.amount_captured, } } @@ -3356,7 +3606,7 @@ impl ForeignFrom<( &hyperswitch_domain_models::payments::AmountDetails, Option<&hyperswitch_domain_models::payments::payment_attempt::AttemptAmountDetails>, - )> for api_models::payments::ConfirmIntentAmountDetailsResponse + )> for api_models::payments::PaymentAmountDetailsResponse { fn foreign_from( (intent_amount_details, attempt_amount_details): ( @@ -3368,10 +3618,10 @@ impl order_amount: intent_amount_details.order_amount, currency: intent_amount_details.currency, shipping_cost: attempt_amount_details - .and_then(|attempt_amount| attempt_amount.shipping_cost) + .and_then(|attempt_amount| attempt_amount.get_shipping_cost()) .or(intent_amount_details.shipping_cost), order_tax_amount: attempt_amount_details - .and_then(|attempt_amount| attempt_amount.order_tax_amount) + .and_then(|attempt_amount| attempt_amount.get_order_tax_amount()) .or(intent_amount_details .tax_details .as_ref() @@ -3383,17 +3633,18 @@ impl intent_amount_details.skip_surcharge_calculation, ), surcharge_amount: attempt_amount_details - .and_then(|attempt| attempt.surcharge_amount) + .and_then(|attempt| attempt.get_surcharge_amount()) .or(intent_amount_details.surcharge_amount), tax_on_surcharge: attempt_amount_details - .and_then(|attempt| attempt.tax_on_surcharge) + .and_then(|attempt| attempt.get_tax_on_surcharge()) .or(intent_amount_details.tax_on_surcharge), net_amount: attempt_amount_details - .map(|attempt| attempt.net_amount) + .map(|attempt| attempt.get_net_amount()) .unwrap_or(intent_amount_details.calculate_net_amount()), - amount_to_capture: attempt_amount_details.and_then(|attempt| attempt.amount_to_capture), + amount_to_capture: attempt_amount_details + .and_then(|attempt| attempt.get_amount_to_capture()), amount_capturable: attempt_amount_details - .map(|attempt| attempt.amount_capturable) + .map(|attempt| attempt.get_amount_capturable()) .unwrap_or(MinorUnit::zero()), amount_captured: intent_amount_details.amount_captured, } diff --git a/crates/router/src/core/webhooks/incoming_v2.rs b/crates/router/src/core/webhooks/incoming_v2.rs index 0deb91efaa8d..b59576edb645 100644 --- a/crates/router/src/core/webhooks/incoming_v2.rs +++ b/crates/router/src/core/webhooks/incoming_v2.rs @@ -20,7 +20,10 @@ use crate::{ api_locking, errors::{self, ConnectorErrorExt, CustomResult, RouterResponse, StorageErrorExt}, metrics, - payments::{self, transformers::ToResponse}, + payments::{ + self, + transformers::{GenerateResponse, ToResponse}, + }, webhooks::utils::construct_webhook_router_data, }, db::StorageInterface, @@ -445,12 +448,8 @@ async fn payments_incoming_webhook_flow( )) .await?; - let response = api_models::payments::PaymentsRetrieveResponse::generate_response( - payment_data, - customer, - &state.base_url, - payments::operations::PaymentGet, - &state.conf.connector_request_reference_id_config, + let response = payment_data.generate_response( + &state, connector_http_status_code, external_latency, None, diff --git a/crates/router/src/routes/app.rs b/crates/router/src/routes/app.rs index baa2ba4ae152..25739d133cc5 100644 --- a/crates/router/src/routes/app.rs +++ b/crates/router/src/routes/app.rs @@ -557,6 +557,9 @@ impl Payments { .service( web::resource("/finish_redirection/{publishable_key}/{profile_id}") .route(web::get().to(payments::payments_finish_redirection)), + ) + .service( + web::resource("/capture").route(web::post().to(payments::payments_capture)), ), ); diff --git a/crates/router/src/routes/payments.rs b/crates/router/src/routes/payments.rs index 48b15c3b2047..496c592e17b0 100644 --- a/crates/router/src/routes/payments.rs +++ b/crates/router/src/routes/payments.rs @@ -2322,3 +2322,75 @@ pub async fn payments_finish_redirection( ) .await } + +#[cfg(feature = "v2")] +#[instrument(skip(state, req), fields(flow, payment_id))] +pub async fn payments_capture( + state: web::Data, + req: actix_web::HttpRequest, + payload: web::Json, + path: web::Path, +) -> impl Responder { + use hyperswitch_domain_models::payments::PaymentCaptureData; + let flow = Flow::PaymentsCapture; + + let global_payment_id = path.into_inner(); + tracing::Span::current().record("payment_id", global_payment_id.get_string_repr()); + + let internal_payload = internal_payload_types::PaymentsGenericRequestWithResourceId { + global_payment_id, + payload: payload.into_inner(), + }; + + let header_payload = match HeaderPayload::foreign_try_from(req.headers()) { + Ok(headers) => headers, + Err(err) => { + return api::log_and_return_error_response(err); + } + }; + + let locking_action = internal_payload.get_locking_input(flow.clone()); + + Box::pin(api::server_wrap( + flow, + state, + &req, + internal_payload, + |state, auth: auth::AuthenticationData, req, req_state| async { + let payment_id = req.global_payment_id; + let request = req.payload; + + let operation = payments::operations::payment_capture_v2::PaymentsCapture; + + Box::pin(payments::payments_core::< + api_types::Capture, + api_models::payments::PaymentsCaptureResponse, + _, + _, + _, + PaymentCaptureData, + >( + state, + req_state, + auth.merchant_account, + auth.profile, + auth.key_store, + operation, + request, + payment_id, + payments::CallConnectorAction::Trigger, + header_payload.clone(), + )) + .await + }, + auth::auth_type( + &auth::HeaderAuth(auth::ApiKeyAuth), + &auth::JWTAuth { + permission: Permission::ProfileAccountWrite, + }, + req.headers(), + ), + locking_action, + )) + .await +} diff --git a/crates/router/src/types.rs b/crates/router/src/types.rs index bea009949f94..b66f80b9c2d9 100644 --- a/crates/router/src/types.rs +++ b/crates/router/src/types.rs @@ -462,7 +462,7 @@ impl Capturable for PaymentsSyncData { payment_data .payment_attempt .amount_details - .amount_to_capture + .get_amount_to_capture() .or_else(|| Some(payment_data.payment_attempt.get_total_amount())) .map(|amt| amt.get_amount_as_i64()) } From ff28a6ce718dd8819b7cdc1837262daf7585a9c6 Mon Sep 17 00:00:00 2001 From: "hyperswitch-bot[bot]" <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 19:49:10 +0000 Subject: [PATCH 02/12] docs(openapi): re-generate OpenAPI specification --- api-reference-v2/openapi_spec.json | 202 ++++++++++++----------------- api-reference/openapi_spec.json | 2 +- 2 files changed, 87 insertions(+), 117 deletions(-) diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json index 6eab5ed2655c..dd3f447a135c 100644 --- a/api-reference-v2/openapi_spec.json +++ b/api-reference-v2/openapi_spec.json @@ -6121,88 +6121,6 @@ "greater_than_equal" ] }, - "ConfirmIntentAmountDetailsResponse": { - "type": "object", - "required": [ - "currency", - "skip_external_tax_calculation", - "skip_surcharge_calculation", - "net_amount", - "amount_capturable" - ], - "properties": { - "order_amount": { - "type": "integer", - "format": "int64", - "description": "The payment amount. Amount for the payment in the lowest denomination of the currency, (i.e) in cents for USD denomination, in yen for JPY denomination etc. E.g., Pass 100 to charge $1.00 and 1 for 1¥ since ¥ is a zero-decimal currency. Read more about [the Decimal and Non-Decimal Currencies](https://github.com/juspay/hyperswitch/wiki/Decimal-and-Non%E2%80%90Decimal-Currencies)", - "example": 6540, - "minimum": 0 - }, - "currency": { - "$ref": "#/components/schemas/Currency" - }, - "shipping_cost": { - "allOf": [ - { - "$ref": "#/components/schemas/MinorUnit" - } - ], - "nullable": true - }, - "order_tax_amount": { - "allOf": [ - { - "$ref": "#/components/schemas/MinorUnit" - } - ], - "nullable": true - }, - "skip_external_tax_calculation": { - "$ref": "#/components/schemas/TaxCalculationOverride" - }, - "skip_surcharge_calculation": { - "$ref": "#/components/schemas/SurchargeCalculationOverride" - }, - "surcharge_amount": { - "allOf": [ - { - "$ref": "#/components/schemas/MinorUnit" - } - ], - "nullable": true - }, - "tax_on_surcharge": { - "allOf": [ - { - "$ref": "#/components/schemas/MinorUnit" - } - ], - "nullable": true - }, - "net_amount": { - "$ref": "#/components/schemas/MinorUnit" - }, - "amount_to_capture": { - "allOf": [ - { - "$ref": "#/components/schemas/MinorUnit" - } - ], - "nullable": true - }, - "amount_capturable": { - "$ref": "#/components/schemas/MinorUnit" - }, - "amount_captured": { - "allOf": [ - { - "$ref": "#/components/schemas/MinorUnit" - } - ], - "nullable": true - } - } - }, "Connector": { "type": "string", "description": "A connector is an integration to fulfill payments", @@ -12044,6 +11962,88 @@ } } }, + "PaymentAmountDetailsResponse": { + "type": "object", + "required": [ + "currency", + "skip_external_tax_calculation", + "skip_surcharge_calculation", + "net_amount", + "amount_capturable" + ], + "properties": { + "order_amount": { + "type": "integer", + "format": "int64", + "description": "The payment amount. Amount for the payment in the lowest denomination of the currency, (i.e) in cents for USD denomination, in yen for JPY denomination etc. E.g., Pass 100 to charge $1.00 and 1 for 1¥ since ¥ is a zero-decimal currency. Read more about [the Decimal and Non-Decimal Currencies](https://github.com/juspay/hyperswitch/wiki/Decimal-and-Non%E2%80%90Decimal-Currencies)", + "example": 6540, + "minimum": 0 + }, + "currency": { + "$ref": "#/components/schemas/Currency" + }, + "shipping_cost": { + "allOf": [ + { + "$ref": "#/components/schemas/MinorUnit" + } + ], + "nullable": true + }, + "order_tax_amount": { + "allOf": [ + { + "$ref": "#/components/schemas/MinorUnit" + } + ], + "nullable": true + }, + "skip_external_tax_calculation": { + "$ref": "#/components/schemas/TaxCalculationOverride" + }, + "skip_surcharge_calculation": { + "$ref": "#/components/schemas/SurchargeCalculationOverride" + }, + "surcharge_amount": { + "allOf": [ + { + "$ref": "#/components/schemas/MinorUnit" + } + ], + "nullable": true + }, + "tax_on_surcharge": { + "allOf": [ + { + "$ref": "#/components/schemas/MinorUnit" + } + ], + "nullable": true + }, + "net_amount": { + "$ref": "#/components/schemas/MinorUnit" + }, + "amount_to_capture": { + "allOf": [ + { + "$ref": "#/components/schemas/MinorUnit" + } + ], + "nullable": true + }, + "amount_capturable": { + "$ref": "#/components/schemas/MinorUnit" + }, + "amount_captured": { + "allOf": [ + { + "$ref": "#/components/schemas/MinorUnit" + } + ], + "nullable": true + } + } + }, "PaymentAttemptResponse": { "type": "object", "required": [ @@ -13869,42 +13869,12 @@ }, "PaymentsCaptureRequest": { "type": "object", - "required": [ - "amount_to_capture" - ], "properties": { - "merchant_id": { - "type": "string", - "description": "The unique identifier for the merchant", - "nullable": true - }, "amount_to_capture": { "type": "integer", "format": "int64", - "description": "The Amount to be captured/ debited from the user's payment method.", - "example": 6540 - }, - "refund_uncaptured_amount": { - "type": "boolean", - "description": "Decider to refund the uncaptured amount", - "nullable": true - }, - "statement_descriptor_suffix": { - "type": "string", - "description": "Provides information about a card payment that customers see on their statements.", - "nullable": true - }, - "statement_descriptor_prefix": { - "type": "string", - "description": "Concatenated with the statement descriptor suffix that’s set on the account to form the complete statement descriptor.", - "nullable": true - }, - "merchant_connector_details": { - "allOf": [ - { - "$ref": "#/components/schemas/MerchantConnectorDetailsWrap" - } - ], + "description": "The Amount to be captured/ debited from the user's payment method. If not passed the full amount will be captured.", + "example": 6540, "nullable": true } } @@ -14006,7 +13976,7 @@ "$ref": "#/components/schemas/IntentStatus" }, "amount": { - "$ref": "#/components/schemas/ConfirmIntentAmountDetailsResponse" + "$ref": "#/components/schemas/PaymentAmountDetailsResponse" }, "connector": { "type": "string", @@ -15742,7 +15712,7 @@ "$ref": "#/components/schemas/IntentStatus" }, "amount": { - "$ref": "#/components/schemas/ConfirmIntentAmountDetailsResponse" + "$ref": "#/components/schemas/PaymentAmountDetailsResponse" }, "connector": { "type": "string", diff --git a/api-reference/openapi_spec.json b/api-reference/openapi_spec.json index 56b77bff1aa9..931078214a21 100644 --- a/api-reference/openapi_spec.json +++ b/api-reference/openapi_spec.json @@ -16643,7 +16643,7 @@ "amount_to_capture": { "type": "integer", "format": "int64", - "description": "The Amount to be captured/ debited from the user's payment method.", + "description": "The Amount to be captured/ debited from the user's payment method. If not passed the full amount will be captured.", "example": 6540 }, "refund_uncaptured_amount": { From 25c19d2338bcf96825f3ae1894132f4606f430ef Mon Sep 17 00:00:00 2001 From: Narayan Bhat Date: Tue, 3 Dec 2024 13:15:25 +0530 Subject: [PATCH 03/12] chore: cargo clippy --- crates/api_models/src/events/payment.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/api_models/src/events/payment.rs b/crates/api_models/src/events/payment.rs index b21cb2c5095d..a78aaf483aa0 100644 --- a/crates/api_models/src/events/payment.rs +++ b/crates/api_models/src/events/payment.rs @@ -11,9 +11,8 @@ use super::{ ))] use crate::payment_methods::CustomerPaymentMethodsListResponse; #[cfg(all(feature = "v2", feature = "payment_methods_v2"))] -use crate::payment_methods::CustomerPaymentMethodsListResponse; +use crate::{events, payment_methods::CustomerPaymentMethodsListResponse}; use crate::{ - events, payment_methods::{ CustomerDefaultPaymentMethodResponse, DefaultPaymentMethod, ListCountriesCurrenciesRequest, ListCountriesCurrenciesResponse, PaymentMethodCollectLinkRenderRequest, From 4e14701e927822e749cf71b4f3010e808c511bc3 Mon Sep 17 00:00:00 2001 From: Narayan Bhat Date: Tue, 3 Dec 2024 13:22:19 +0530 Subject: [PATCH 04/12] chore: cargo clippy_v2 --- crates/hyperswitch_domain_models/src/router_data.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/crates/hyperswitch_domain_models/src/router_data.rs b/crates/hyperswitch_domain_models/src/router_data.rs index ec9144872696..b4c8c2952b34 100644 --- a/crates/hyperswitch_domain_models/src/router_data.rs +++ b/crates/hyperswitch_domain_models/src/router_data.rs @@ -1004,9 +1004,7 @@ impl &self, payment_data: &payments::PaymentStatusData, ) -> Option { - let Some(payment_attempt) = payment_data.payment_attempt.as_ref() else { - return None; - }; + let payment_attempt = payment_data.payment_attempt.as_ref()?; // Based on the status of the response, we can determine the amount capturable let intent_status = common_enums::IntentStatus::from(self.status); @@ -1036,9 +1034,7 @@ impl &self, payment_data: &payments::PaymentStatusData, ) -> Option { - let Some(payment_attempt) = payment_data.payment_attempt.as_ref() else { - return None; - }; + let payment_attempt = payment_data.payment_attempt.as_ref()?; // Based on the status of the response, we can determine the amount capturable let intent_status = common_enums::IntentStatus::from(self.status); From 2a790cea3c792586ccba11f3e11fdd9b7a4e02e9 Mon Sep 17 00:00:00 2001 From: Narayan Bhat Date: Tue, 3 Dec 2024 16:41:29 +0530 Subject: [PATCH 05/12] chore: cargo clippy_v2 --- crates/router/src/core/payments/transformers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index be8d116f7010..939ce359dc44 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -427,7 +427,7 @@ pub async fn construct_payment_router_data_for_capture<'a>( let connector = api::ConnectorData::get_connector_by_name( &state.conf.connectors, - &connector_id, + connector_id, api::GetToken::Connector, payment_data.payment_attempt.merchant_connector_id.clone(), )?; From 52786abf9a5f9a7ae5ad8df90c590e8f9b33c223 Mon Sep 17 00:00:00 2001 From: Narayan Bhat Date: Wed, 4 Dec 2024 16:45:26 +0530 Subject: [PATCH 06/12] refactor: add validation for amount_to_capture --- .../src/payments/payment_attempt.rs | 12 ++++++++++++ .../core/payments/operations/payment_capture_v2.rs | 12 +++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs index 5807ebecc199..60eb90d6bfbd 100644 --- a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs +++ b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs @@ -276,6 +276,18 @@ impl AttemptAmountDetails { pub fn set_amount_to_capture(&mut self, amount_to_capture: MinorUnit) { self.amount_to_capture = Some(amount_to_capture); } + + /// Validate the amount to capture that is sent in the request + pub fn validate_amount_to_capture( + &self, + request_amount_to_capture: MinorUnit, + ) -> Result<(), ValidationError> { + common_utils::fp_utils::when(request_amount_to_capture > self.get_net_amount(), || { + Err(ValidationError::IncorrectValueProvided { + field_name: "amount_to_capture", + }) + }) + } } #[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)] diff --git a/crates/router/src/core/payments/operations/payment_capture_v2.rs b/crates/router/src/core/payments/operations/payment_capture_v2.rs index 89594a44a67d..db414fe261bb 100644 --- a/crates/router/src/core/payments/operations/payment_capture_v2.rs +++ b/crates/router/src/core/payments/operations/payment_capture_v2.rs @@ -122,7 +122,7 @@ impl ValidateRequest( &'b self, - request: &PaymentsCaptureRequest, + _request: &PaymentsCaptureRequest, merchant_account: &'a domain::MerchantAccount, ) -> RouterResult { let validate_result = operations::ValidateResult { @@ -181,6 +181,16 @@ impl GetTracker, PaymentsCaptureReques .attach_printable("Could not find payment attempt given the attempt id")?; if let Some(amount_to_capture) = request.amount_to_capture { + payment_attempt + .amount_details + .validate_amount_to_capture(amount_to_capture) + .change_context(errors::ApiErrorResponse::PreconditionFailed { + message: format!( + "`amount_to_capture` is greater than the net amount {}", + payment_attempt.amount_details.get_net_amount() + ), + })?; + payment_attempt .amount_details .set_amount_to_capture(amount_to_capture); From 52ba04b7884850f87169c23bb359ccb11ac7127d Mon Sep 17 00:00:00 2001 From: "hyperswitch-bot[bot]" <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Date: Wed, 4 Dec 2024 15:03:22 +0000 Subject: [PATCH 07/12] docs(openapi): re-generate OpenAPI specification --- api-reference-v2/openapi_spec.json | 3172 +++++++++++++++++++++------- 1 file changed, 2402 insertions(+), 770 deletions(-) diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json index 8ad7edbfc8df..f2449a73ce5a 100644 --- a/api-reference-v2/openapi_spec.json +++ b/api-reference-v2/openapi_spec.json @@ -22,7 +22,9 @@ "paths": { "/v2/organization": { "post": { - "tags": ["Organization"], + "tags": [ + "Organization" + ], "summary": "Organization - Create", "description": "Create a new organization", "operationId": "Create an Organization", @@ -67,7 +69,9 @@ }, "/v2/organization/{id}": { "get": { - "tags": ["Organization"], + "tags": [ + "Organization" + ], "summary": "Organization - Retrieve", "description": "Retrieve an existing organization", "operationId": "Retrieve an Organization", @@ -104,7 +108,9 @@ ] }, "put": { - "tags": ["Organization"], + "tags": [ + "Organization" + ], "summary": "Organization - Update", "description": "Create a new organization for .", "operationId": "Update an Organization", @@ -160,7 +166,9 @@ }, "/v2/organization/{id}/merchant-accounts": { "get": { - "tags": ["Organization"], + "tags": [ + "Organization" + ], "summary": "Organization - Merchant Account - List", "description": "List merchant accounts for an Organization", "operationId": "List Merchant Accounts", @@ -202,7 +210,9 @@ }, "/v2/connector-accounts": { "post": { - "tags": ["Merchant Connector Account"], + "tags": [ + "Merchant Connector Account" + ], "summary": "Connector Account - Create", "description": "Creates a new Connector Account for the merchant account. The connector could be a payment processor/facilitator/acquirer or a provider of specialized services like Fraud/Accounting etc.", "operationId": "Create a Merchant Connector", @@ -277,7 +287,9 @@ }, "/v2/connector-accounts/{id}": { "get": { - "tags": ["Merchant Connector Account"], + "tags": [ + "Merchant Connector Account" + ], "summary": "Connector Account - Retrieve", "description": "Retrieves details of a Connector account", "operationId": "Retrieve a Merchant Connector", @@ -318,7 +330,9 @@ ] }, "put": { - "tags": ["Merchant Connector Account"], + "tags": [ + "Merchant Connector Account" + ], "summary": "Connector Account - Update", "description": "To update an existing Connector account. Helpful in enabling/disabling different payment methods and other settings for the connector", "operationId": "Update a Merchant Connector", @@ -388,7 +402,9 @@ ] }, "delete": { - "tags": ["Merchant Connector Account"], + "tags": [ + "Merchant Connector Account" + ], "summary": "Merchant Connector - Delete", "description": "Delete or Detach a Merchant Connector from Merchant Account", "operationId": "Delete a Merchant Connector", @@ -431,7 +447,9 @@ }, "/v2/merchant-accounts": { "post": { - "tags": ["Merchant Account"], + "tags": [ + "Merchant Account" + ], "summary": "Merchant Account - Create", "description": "Create a new account for a *merchant* and the *merchant* could be a seller or retailer or client who likes to receive and send payments.\n\nBefore creating the merchant account, it is mandatory to create an organization.", "operationId": "Create a Merchant Account", @@ -508,7 +526,9 @@ }, "/v2/merchant-accounts/{id}": { "get": { - "tags": ["Merchant Account"], + "tags": [ + "Merchant Account" + ], "summary": "Merchant Account - Retrieve", "description": "Retrieve a *merchant* account details.", "operationId": "Retrieve a Merchant Account", @@ -545,7 +565,9 @@ ] }, "put": { - "tags": ["Merchant Account"], + "tags": [ + "Merchant Account" + ], "summary": "Merchant Account - Update", "description": "Updates details of an existing merchant account. Helpful in updating merchant details such as email, contact details, or other configuration details like webhook, routing algorithm etc", "operationId": "Update a Merchant Account", @@ -610,7 +632,9 @@ }, "/v2/merchant-accounts/{id}/profiles": { "get": { - "tags": ["Merchant Account"], + "tags": [ + "Merchant Account" + ], "summary": "Merchant Account - Profile List", "description": "List profiles for an Merchant", "operationId": "List Profiles", @@ -652,7 +676,9 @@ }, "/v2/payments/{payment_id}/create-external-sdk-tokens": { "post": { - "tags": ["Payments"], + "tags": [ + "Payments" + ], "summary": "Payments - Session token", "description": "Creates a session object or a session token for wallets like Apple Pay, Google Pay, etc. These tokens are used by Hyperswitch's SDK to initiate these wallets' SDK.", "operationId": "Create Session tokens for a Payment", @@ -701,7 +727,9 @@ }, "/v2/profiles": { "post": { - "tags": ["Profile"], + "tags": [ + "Profile" + ], "summary": "Profile - Create", "description": "Creates a new *profile* for a merchant", "operationId": "Create A Profile", @@ -760,7 +788,9 @@ }, "/v2/profiles/{id}": { "get": { - "tags": ["Profile"], + "tags": [ + "Profile" + ], "summary": "Profile - Retrieve", "description": "Retrieve existing *profile*", "operationId": "Retrieve a Profile", @@ -809,7 +839,9 @@ ] }, "put": { - "tags": ["Profile"], + "tags": [ + "Profile" + ], "summary": "Profile - Update", "description": "Update the *profile*", "operationId": "Update a Profile", @@ -877,7 +909,9 @@ }, "/v2/profiles/{id}/connector-accounts": { "get": { - "tags": ["Business Profile"], + "tags": [ + "Business Profile" + ], "summary": "Profile - Connector Accounts List", "description": "List Connector Accounts for the profile", "operationId": "List all Merchant Connectors", @@ -934,7 +968,9 @@ }, "/v2/profiles/{id}/activate-routing-algorithm": { "patch": { - "tags": ["Profile"], + "tags": [ + "Profile" + ], "summary": "Profile - Activate routing algorithm", "description": "Activates a routing algorithm under a profile", "operationId": "Activates a routing algorithm under a profile", @@ -999,7 +1035,9 @@ }, "/v2/profiles/{id}/deactivate-routing-algorithm": { "patch": { - "tags": ["Profile"], + "tags": [ + "Profile" + ], "summary": "Profile - Deactivate routing algorithm", "description": "Deactivates a routing algorithm under a profile", "operationId": " Deactivates a routing algorithm under a profile", @@ -1050,7 +1088,9 @@ }, "/v2/profiles/{id}/fallback-routing": { "patch": { - "tags": ["Profile"], + "tags": [ + "Profile" + ], "summary": "Profile - Update Default Fallback Routing Algorithm", "description": "Update the default fallback routing algorithm for the profile", "operationId": "Update the default fallback routing algorithm for the profile", @@ -1112,7 +1152,9 @@ ] }, "get": { - "tags": ["Profile"], + "tags": [ + "Profile" + ], "summary": "Profile - Retrieve Default Fallback Routing Algorithm", "description": "Retrieve the default fallback routing algorithm for the profile", "operationId": "Retrieve the default fallback routing algorithm for the profile", @@ -1157,7 +1199,9 @@ }, "/v2/profiles/{id}/routing-algorithm": { "get": { - "tags": ["Profile"], + "tags": [ + "Profile" + ], "summary": "Profile - Retrieve Active Routing Algorithm", "description": "_\nRetrieve active routing algorithm under the profile", "operationId": "Retrieve the active routing algorithm under the profile", @@ -1229,7 +1273,9 @@ }, "/v2/routing-algorithm": { "post": { - "tags": ["Routing"], + "tags": [ + "Routing" + ], "summary": "Routing - Create", "description": "Create a routing algorithm", "operationId": "Create a routing algorithm", @@ -1282,7 +1328,9 @@ }, "/v2/routing-algorithm/{id}": { "get": { - "tags": ["Routing"], + "tags": [ + "Routing" + ], "summary": "Routing - Retrieve", "description": "Retrieve a routing algorithm with its algorithm id", "operationId": "Retrieve a routing algorithm with its algorithm id", @@ -1330,7 +1378,9 @@ }, "/v2/api-keys": { "post": { - "tags": ["API Key"], + "tags": [ + "API Key" + ], "summary": "API Key - Create", "description": "Create a new API Key for accessing our APIs from your servers. The plaintext API Key will be\ndisplayed only once on creation, so ensure you store it securely.", "operationId": "Create an API Key", @@ -1368,7 +1418,9 @@ }, "/v2/api-keys/{id}": { "get": { - "tags": ["API Key"], + "tags": [ + "API Key" + ], "summary": "API Key - Retrieve", "description": "Retrieve information about the specified API Key.", "operationId": "Retrieve an API Key", @@ -1405,7 +1457,9 @@ ] }, "put": { - "tags": ["API Key"], + "tags": [ + "API Key" + ], "summary": "API Key - Update", "description": "Update information for the specified API Key.", "operationId": "Update an API Key", @@ -1452,7 +1506,9 @@ ] }, "delete": { - "tags": ["API Key"], + "tags": [ + "API Key" + ], "summary": "API Key - Revoke", "description": "Revoke the specified API Key. Once revoked, the API Key can no longer be used for\nauthenticating with our APIs.", "operationId": "Revoke an API Key", @@ -1491,7 +1547,9 @@ }, "/v2/api-keys/list": { "get": { - "tags": ["API Key"], + "tags": [ + "API Key" + ], "summary": "API Key - List", "description": "List all the API Keys associated to a merchant account.", "operationId": "List all API Keys associated with a merchant account", @@ -1543,7 +1601,9 @@ }, "/v2/customers": { "post": { - "tags": ["Customers"], + "tags": [ + "Customers" + ], "summary": "Customers - Create", "description": "Creates a customer object and stores the customer details to be reused for future payments.\nIncase the customer already exists in the system, this API will respond with the customer details.", "operationId": "Create a Customer", @@ -1589,7 +1649,9 @@ }, "/v2/customers/{id}": { "get": { - "tags": ["Customers"], + "tags": [ + "Customers" + ], "summary": "Customers - Retrieve", "description": "Retrieves a customer's details.", "operationId": "Retrieve a Customer", @@ -1629,7 +1691,9 @@ ] }, "post": { - "tags": ["Customers"], + "tags": [ + "Customers" + ], "summary": "Customers - Update", "description": "Updates the customer's details in a customer object.", "operationId": "Update a Customer", @@ -1684,7 +1748,9 @@ ] }, "delete": { - "tags": ["Customers"], + "tags": [ + "Customers" + ], "summary": "Customers - Delete", "description": "Delete a customer record.", "operationId": "Delete a Customer", @@ -1723,7 +1789,9 @@ }, "/v2/customers/list": { "get": { - "tags": ["Customers"], + "tags": [ + "Customers" + ], "summary": "Customers - List", "description": "Lists all the customers for a particular merchant id.", "operationId": "List all Customers for a Merchant", @@ -1754,7 +1822,9 @@ }, "/v2/payments/create-intent": { "post": { - "tags": ["Payments"], + "tags": [ + "Payments" + ], "summary": "Payments - Create Intent", "description": "**Creates a payment intent object when amount_details are passed.**\n\nYou will require the 'API - Key' from the Hyperswitch dashboard to make the first call, and use the 'client secret' returned in this API along with your 'publishable key' to make subsequent API calls from your client.", "operationId": "Create a Payment Intent", @@ -1802,7 +1872,9 @@ }, "/v2/payments/{id}/get-intent": { "get": { - "tags": ["Payments"], + "tags": [ + "Payments" + ], "summary": "Payments - Get Intent", "description": "**Get a payment intent object when id is passed in path**\n\nYou will require the 'API - Key' from the Hyperswitch dashboard to make the call.", "operationId": "Get the Payment Intent details", @@ -1841,7 +1913,9 @@ }, "/v2/payments/{id}/confirm-intent": { "post": { - "tags": ["Payments"], + "tags": [ + "Payments" + ], "summary": "Payments - Confirm Intent", "description": "**Confirms a payment intent object with the payment method data**\n\n.", "operationId": "Confirm Payment Intent", @@ -1895,7 +1969,9 @@ }, "/v2/payments/{id}": { "get": { - "tags": ["Payments"], + "tags": [ + "Payments" + ], "summary": "Payments - Get", "description": "Retrieves a Payment. This API can also be used to get the status of a previously initiated payment or next action for an ongoing payment", "operationId": "Retrieve a Payment", @@ -1943,7 +2019,9 @@ }, "/v2/payments/{id}/saved-payment-methods": { "get": { - "tags": ["Payment Methods"], + "tags": [ + "Payment Methods" + ], "summary": "List customer saved payment methods for a payment", "description": "To filter and list the applicable payment methods for a particular Customer ID, is to be associated with a payment", "operationId": "List all Payment Methods for a Customer", @@ -1984,7 +2062,9 @@ }, "/v2/customers/{id}/saved-payment-methods": { "get": { - "tags": ["Payment Methods"], + "tags": [ + "Payment Methods" + ], "summary": "List saved payment methods for a Customer", "description": "To filter and list the applicable payment methods for a particular Customer ID, to be used in a non-payments context", "operationId": "List all Payment Methods for a Customer", @@ -2025,7 +2105,9 @@ }, "/v2/payment-methods": { "post": { - "tags": ["Payment Methods"], + "tags": [ + "Payment Methods" + ], "summary": "Payment Method - Create", "description": "Creates and stores a payment method against a customer. In case of cards, this API should be used only by PCI compliant merchants.", "operationId": "Create Payment Method", @@ -2063,7 +2145,9 @@ }, "/v2/payment-methods/create-intent": { "post": { - "tags": ["Payment Methods"], + "tags": [ + "Payment Methods" + ], "summary": "Payment Method - Create Intent", "description": "Creates a payment method for customer with billing information and other metadata.", "operationId": "Create Payment Method Intent", @@ -2101,7 +2185,9 @@ }, "/v2/payment-methods/{id}/confirm-intent": { "post": { - "tags": ["Payment Methods"], + "tags": [ + "Payment Methods" + ], "summary": "Payment Method - Confirm Intent", "description": "Update a payment method with customer's payment method related information.", "operationId": "Confirm Payment Method Intent", @@ -2139,7 +2225,9 @@ }, "/v2/payment-methods/{id}/update-saved-payment-method": { "patch": { - "tags": ["Payment Methods"], + "tags": [ + "Payment Methods" + ], "summary": "Payment Method - Update", "description": "Update an existing payment method of a customer.", "operationId": "Update Payment Method", @@ -2177,7 +2265,9 @@ }, "/v2/payment-methods/{id}": { "get": { - "tags": ["Payment Methods"], + "tags": [ + "Payment Methods" + ], "summary": "Payment Method - Retrieve", "description": "Retrieves a payment method of a customer.", "operationId": "Retrieve Payment Method", @@ -2214,7 +2304,9 @@ ] }, "delete": { - "tags": ["Payment Methods"], + "tags": [ + "Payment Methods" + ], "summary": "Payment Method - Delete", "description": "Deletes a payment method of a customer.", "operationId": "Delete Payment Method", @@ -2253,7 +2345,9 @@ }, "/v2/refunds": { "post": { - "tags": ["Refunds"], + "tags": [ + "Refunds" + ], "summary": "Refunds - Create", "description": "Creates a refund against an already processed payment. In case of some processors, you can even opt to refund only a partial amount multiple times until the original charge amount has been refunded", "operationId": "Create a Refund", @@ -2321,17 +2415,25 @@ "AcceptanceType": { "type": "string", "description": "This is used to indicate if the mandate was accepted online or offline", - "enum": ["online", "offline"] + "enum": [ + "online", + "offline" + ] }, "AcceptedCountries": { "oneOf": [ { "type": "object", - "required": ["type", "list"], + "required": [ + "type", + "list" + ], "properties": { "type": { "type": "string", - "enum": ["enable_only"] + "enum": [ + "enable_only" + ] }, "list": { "type": "array", @@ -2343,11 +2445,16 @@ }, { "type": "object", - "required": ["type", "list"], + "required": [ + "type", + "list" + ], "properties": { "type": { "type": "string", - "enum": ["disable_only"] + "enum": [ + "disable_only" + ] }, "list": { "type": "array", @@ -2359,11 +2466,15 @@ }, { "type": "object", - "required": ["type"], + "required": [ + "type" + ], "properties": { "type": { "type": "string", - "enum": ["all_accepted"] + "enum": [ + "all_accepted" + ] } } } @@ -2377,11 +2488,16 @@ "oneOf": [ { "type": "object", - "required": ["type", "list"], + "required": [ + "type", + "list" + ], "properties": { "type": { "type": "string", - "enum": ["enable_only"] + "enum": [ + "enable_only" + ] }, "list": { "type": "array", @@ -2393,11 +2509,16 @@ }, { "type": "object", - "required": ["type", "list"], + "required": [ + "type", + "list" + ], "properties": { "type": { "type": "string", - "enum": ["disable_only"] + "enum": [ + "disable_only" + ] }, "list": { "type": "array", @@ -2409,11 +2530,15 @@ }, { "type": "object", - "required": ["type"], + "required": [ + "type" + ], "properties": { "type": { "type": "string", - "enum": ["all_accepted"] + "enum": [ + "all_accepted" + ] } } } @@ -2424,7 +2549,10 @@ }, "AchBankDebitAdditionalData": { "type": "object", - "required": ["account_number", "routing_number"], + "required": [ + "account_number", + "routing_number" + ], "properties": { "account_number": { "type": "string", @@ -2476,7 +2604,10 @@ }, "AchBankTransfer": { "type": "object", - "required": ["bank_account_number", "bank_routing_number"], + "required": [ + "bank_account_number", + "bank_routing_number" + ], "properties": { "bank_name": { "type": "string", @@ -2513,7 +2644,10 @@ "AchBankTransferAdditionalData": { "type": "object", "description": "Masked payout method details for ach bank transfer payout method", - "required": ["bank_account_number", "bank_routing_number"], + "required": [ + "bank_account_number", + "bank_routing_number" + ], "properties": { "bank_account_number": { "type": "string", @@ -2590,7 +2724,9 @@ "oneOf": [ { "type": "object", - "required": ["open_banking_recipient_data"], + "required": [ + "open_banking_recipient_data" + ], "properties": { "open_banking_recipient_data": { "$ref": "#/components/schemas/MerchantRecipientData" @@ -2603,7 +2739,9 @@ "oneOf": [ { "type": "object", - "required": ["Card"], + "required": [ + "Card" + ], "properties": { "Card": { "$ref": "#/components/schemas/CardAdditionalData" @@ -2612,7 +2750,9 @@ }, { "type": "object", - "required": ["Bank"], + "required": [ + "Bank" + ], "properties": { "Bank": { "$ref": "#/components/schemas/BankAdditionalData" @@ -2621,7 +2761,9 @@ }, { "type": "object", - "required": ["Wallet"], + "required": [ + "Wallet" + ], "properties": { "Wallet": { "$ref": "#/components/schemas/WalletAdditionalData" @@ -2771,7 +2913,9 @@ }, "AmountDetails": { "type": "object", - "required": ["currency"], + "required": [ + "currency" + ], "properties": { "order_amount": { "type": "integer", @@ -2901,7 +3045,10 @@ }, "AmountInfo": { "type": "object", - "required": ["label", "amount"], + "required": [ + "label", + "amount" + ], "properties": { "label": { "type": "string", @@ -2923,7 +3070,9 @@ "oneOf": [ { "type": "string", - "enum": ["never"] + "enum": [ + "never" + ] }, { "type": "string", @@ -2933,7 +3082,11 @@ }, "ApplePayAddressParameters": { "type": "string", - "enum": ["postalAddress", "phone", "email"] + "enum": [ + "postalAddress", + "phone", + "email" + ] }, "ApplePayBillingContactFields": { "type": "array", @@ -2943,7 +3096,11 @@ }, "ApplePayPaymentRequest": { "type": "object", - "required": ["country_code", "currency_code", "total"], + "required": [ + "country_code", + "currency_code", + "total" + ], "properties": { "country_code": { "$ref": "#/components/schemas/CountryAlpha2" @@ -3055,11 +3212,18 @@ }, "ApplepayInitiative": { "type": "string", - "enum": ["web", "ios"] + "enum": [ + "web", + "ios" + ] }, "ApplepayPaymentMethod": { "type": "object", - "required": ["display_name", "network", "type"], + "required": [ + "display_name", + "network", + "type" + ], "properties": { "display_name": { "type": "string", @@ -3077,7 +3241,11 @@ }, "ApplepaySessionTokenResponse": { "type": "object", - "required": ["connector", "delayed_session_token", "sdk_next_action"], + "required": [ + "connector", + "delayed_session_token", + "sdk_next_action" + ], "properties": { "session_token_data": { "allOf": [ @@ -3155,7 +3323,10 @@ }, "AuthenticationConnectorDetails": { "type": "object", - "required": ["authentication_connectors", "three_ds_requestor_url"], + "required": [ + "authentication_connectors", + "three_ds_requestor_url" + ], "properties": { "authentication_connectors": { "type": "array", @@ -3172,24 +3343,44 @@ }, "AuthenticationConnectors": { "type": "string", - "enum": ["threedsecureio", "netcetera", "gpayments"] + "enum": [ + "threedsecureio", + "netcetera", + "gpayments" + ] }, "AuthenticationStatus": { "type": "string", - "enum": ["started", "pending", "success", "failed"] + "enum": [ + "started", + "pending", + "success", + "failed" + ] }, "AuthenticationType": { "type": "string", "description": "Pass this parameter to force 3DS or non 3DS auth for this payment. Some connectors will still force 3DS auth even in case of passing 'no_three_ds' here and vice versa. Default value is 'no_three_ds' if not set", - "enum": ["three_ds", "no_three_ds"] + "enum": [ + "three_ds", + "no_three_ds" + ] }, "AuthorizationStatus": { "type": "string", - "enum": ["success", "failure", "processing", "unresolved"] + "enum": [ + "success", + "failure", + "processing", + "unresolved" + ] }, "BacsBankDebitAdditionalData": { "type": "object", - "required": ["account_number", "sort_code"], + "required": [ + "account_number", + "sort_code" + ], "properties": { "account_number": { "type": "string", @@ -3211,7 +3402,10 @@ }, "BacsBankTransfer": { "type": "object", - "required": ["bank_account_number", "bank_sort_code"], + "required": [ + "bank_account_number", + "bank_sort_code" + ], "properties": { "bank_name": { "type": "string", @@ -3248,7 +3442,10 @@ "BacsBankTransferAdditionalData": { "type": "object", "description": "Masked payout method details for bacs bank transfer payout method", - "required": ["bank_sort_code", "bank_account_number"], + "required": [ + "bank_sort_code", + "bank_account_number" + ], "properties": { "bank_sort_code": { "type": "string", @@ -3284,7 +3481,11 @@ }, "BacsBankTransferInstructions": { "type": "object", - "required": ["account_holder_name", "account_number", "sort_code"], + "required": [ + "account_holder_name", + "account_number", + "sort_code" + ], "properties": { "account_holder_name": { "type": "string", @@ -3364,7 +3565,10 @@ }, "BankCodeResponse": { "type": "object", - "required": ["bank_name", "eligible_connectors"], + "required": [ + "bank_name", + "eligible_connectors" + ], "properties": { "bank_name": { "type": "array", @@ -3384,7 +3588,9 @@ "oneOf": [ { "type": "object", - "required": ["ach"], + "required": [ + "ach" + ], "properties": { "ach": { "$ref": "#/components/schemas/AchBankDebitAdditionalData" @@ -3393,7 +3599,9 @@ }, { "type": "object", - "required": ["bacs"], + "required": [ + "bacs" + ], "properties": { "bacs": { "$ref": "#/components/schemas/BacsBankDebitAdditionalData" @@ -3402,7 +3610,9 @@ }, { "type": "object", - "required": ["becs"], + "required": [ + "becs" + ], "properties": { "becs": { "$ref": "#/components/schemas/BecsBankDebitAdditionalData" @@ -3411,7 +3621,9 @@ }, { "type": "object", - "required": ["sepa"], + "required": [ + "sepa" + ], "properties": { "sepa": { "$ref": "#/components/schemas/SepaBankDebitAdditionalData" @@ -3449,7 +3661,9 @@ "oneOf": [ { "type": "object", - "required": ["ach_bank_debit"], + "required": [ + "ach_bank_debit" + ], "properties": { "ach_bank_debit": { "type": "object", @@ -3508,11 +3722,16 @@ }, { "type": "object", - "required": ["sepa_bank_debit"], + "required": [ + "sepa_bank_debit" + ], "properties": { "sepa_bank_debit": { "type": "object", - "required": ["iban", "bank_account_holder_name"], + "required": [ + "iban", + "bank_account_holder_name" + ], "properties": { "billing_details": { "allOf": [ @@ -3538,11 +3757,16 @@ }, { "type": "object", - "required": ["becs_bank_debit"], + "required": [ + "becs_bank_debit" + ], "properties": { "becs_bank_debit": { "type": "object", - "required": ["account_number", "bsb_number"], + "required": [ + "account_number", + "bsb_number" + ], "properties": { "billing_details": { "allOf": [ @@ -3574,7 +3798,9 @@ }, { "type": "object", - "required": ["bacs_bank_debit"], + "required": [ + "bacs_bank_debit" + ], "properties": { "bacs_bank_debit": { "type": "object", @@ -3630,7 +3856,9 @@ }, "BankDebitTypes": { "type": "object", - "required": ["eligible_connectors"], + "required": [ + "eligible_connectors" + ], "properties": { "eligible_connectors": { "type": "array", @@ -3642,7 +3870,10 @@ }, "BankHolderType": { "type": "string", - "enum": ["personal", "business"] + "enum": [ + "personal", + "business" + ] }, "BankNames": { "type": "string", @@ -3798,7 +4029,10 @@ }, "BankRedirectBilling": { "type": "object", - "required": ["billing_name", "email"], + "required": [ + "billing_name", + "email" + ], "properties": { "billing_name": { "type": "string", @@ -3816,7 +4050,9 @@ "oneOf": [ { "type": "object", - "required": ["bancontact_card"], + "required": [ + "bancontact_card" + ], "properties": { "bancontact_card": { "type": "object", @@ -3861,7 +4097,9 @@ }, { "type": "object", - "required": ["bizum"], + "required": [ + "bizum" + ], "properties": { "bizum": { "type": "object" @@ -3870,7 +4108,9 @@ }, { "type": "object", - "required": ["blik"], + "required": [ + "blik" + ], "properties": { "blik": { "type": "object", @@ -3885,11 +4125,16 @@ }, { "type": "object", - "required": ["eps"], + "required": [ + "eps" + ], "properties": { "eps": { "type": "object", - "required": ["bank_name", "country"], + "required": [ + "bank_name", + "country" + ], "properties": { "billing_details": { "allOf": [ @@ -3911,11 +4156,15 @@ }, { "type": "object", - "required": ["giropay"], + "required": [ + "giropay" + ], "properties": { "giropay": { "type": "object", - "required": ["country"], + "required": [ + "country" + ], "properties": { "billing_details": { "allOf": [ @@ -3944,11 +4193,16 @@ }, { "type": "object", - "required": ["ideal"], + "required": [ + "ideal" + ], "properties": { "ideal": { "type": "object", - "required": ["bank_name", "country"], + "required": [ + "bank_name", + "country" + ], "properties": { "billing_details": { "allOf": [ @@ -3970,7 +4224,9 @@ }, { "type": "object", - "required": ["interac"], + "required": [ + "interac" + ], "properties": { "interac": { "type": "object", @@ -3994,11 +4250,15 @@ }, { "type": "object", - "required": ["online_banking_czech_republic"], + "required": [ + "online_banking_czech_republic" + ], "properties": { "online_banking_czech_republic": { "type": "object", - "required": ["issuer"], + "required": [ + "issuer" + ], "properties": { "issuer": { "$ref": "#/components/schemas/BankNames" @@ -4009,7 +4269,9 @@ }, { "type": "object", - "required": ["online_banking_finland"], + "required": [ + "online_banking_finland" + ], "properties": { "online_banking_finland": { "type": "object", @@ -4024,11 +4286,15 @@ }, { "type": "object", - "required": ["online_banking_poland"], + "required": [ + "online_banking_poland" + ], "properties": { "online_banking_poland": { "type": "object", - "required": ["issuer"], + "required": [ + "issuer" + ], "properties": { "issuer": { "$ref": "#/components/schemas/BankNames" @@ -4039,11 +4305,15 @@ }, { "type": "object", - "required": ["online_banking_slovakia"], + "required": [ + "online_banking_slovakia" + ], "properties": { "online_banking_slovakia": { "type": "object", - "required": ["issuer"], + "required": [ + "issuer" + ], "properties": { "issuer": { "$ref": "#/components/schemas/BankNames" @@ -4054,11 +4324,16 @@ }, { "type": "object", - "required": ["open_banking_uk"], + "required": [ + "open_banking_uk" + ], "properties": { "open_banking_uk": { "type": "object", - "required": ["issuer", "country"], + "required": [ + "issuer", + "country" + ], "properties": { "issuer": { "$ref": "#/components/schemas/BankNames" @@ -4072,7 +4347,9 @@ }, { "type": "object", - "required": ["przelewy24"], + "required": [ + "przelewy24" + ], "properties": { "przelewy24": { "type": "object", @@ -4099,11 +4376,15 @@ }, { "type": "object", - "required": ["sofort"], + "required": [ + "sofort" + ], "properties": { "sofort": { "type": "object", - "required": ["country"], + "required": [ + "country" + ], "properties": { "billing_details": { "allOf": [ @@ -4128,11 +4409,15 @@ }, { "type": "object", - "required": ["trustly"], + "required": [ + "trustly" + ], "properties": { "trustly": { "type": "object", - "required": ["country"], + "required": [ + "country" + ], "properties": { "country": { "$ref": "#/components/schemas/CountryAlpha2" @@ -4143,11 +4428,15 @@ }, { "type": "object", - "required": ["online_banking_fpx"], + "required": [ + "online_banking_fpx" + ], "properties": { "online_banking_fpx": { "type": "object", - "required": ["issuer"], + "required": [ + "issuer" + ], "properties": { "issuer": { "$ref": "#/components/schemas/BankNames" @@ -4158,11 +4447,15 @@ }, { "type": "object", - "required": ["online_banking_thailand"], + "required": [ + "online_banking_thailand" + ], "properties": { "online_banking_thailand": { "type": "object", - "required": ["issuer"], + "required": [ + "issuer" + ], "properties": { "issuer": { "$ref": "#/components/schemas/BankNames" @@ -4173,7 +4466,9 @@ }, { "type": "object", - "required": ["local_bank_redirect"], + "required": [ + "local_bank_redirect" + ], "properties": { "local_bank_redirect": { "type": "object" @@ -4186,7 +4481,9 @@ "oneOf": [ { "type": "object", - "required": ["BancontactCard"], + "required": [ + "BancontactCard" + ], "properties": { "BancontactCard": { "$ref": "#/components/schemas/BancontactBankRedirectAdditionalData" @@ -4195,7 +4492,9 @@ }, { "type": "object", - "required": ["Blik"], + "required": [ + "Blik" + ], "properties": { "Blik": { "$ref": "#/components/schemas/BlikBankRedirectAdditionalData" @@ -4204,7 +4503,9 @@ }, { "type": "object", - "required": ["Giropay"], + "required": [ + "Giropay" + ], "properties": { "Giropay": { "$ref": "#/components/schemas/GiropayBankRedirectAdditionalData" @@ -4242,7 +4543,9 @@ "oneOf": [ { "type": "object", - "required": ["ach"], + "required": [ + "ach" + ], "properties": { "ach": { "type": "object" @@ -4251,7 +4554,9 @@ }, { "type": "object", - "required": ["sepa"], + "required": [ + "sepa" + ], "properties": { "sepa": { "type": "object" @@ -4260,7 +4565,9 @@ }, { "type": "object", - "required": ["bacs"], + "required": [ + "bacs" + ], "properties": { "bacs": { "type": "object" @@ -4269,7 +4576,9 @@ }, { "type": "object", - "required": ["multibanco"], + "required": [ + "multibanco" + ], "properties": { "multibanco": { "type": "object" @@ -4278,7 +4587,9 @@ }, { "type": "object", - "required": ["permata"], + "required": [ + "permata" + ], "properties": { "permata": { "type": "object" @@ -4287,7 +4598,9 @@ }, { "type": "object", - "required": ["bca"], + "required": [ + "bca" + ], "properties": { "bca": { "type": "object" @@ -4296,7 +4609,9 @@ }, { "type": "object", - "required": ["bni_va"], + "required": [ + "bni_va" + ], "properties": { "bni_va": { "type": "object" @@ -4305,7 +4620,9 @@ }, { "type": "object", - "required": ["bri_va"], + "required": [ + "bri_va" + ], "properties": { "bri_va": { "type": "object" @@ -4314,7 +4631,9 @@ }, { "type": "object", - "required": ["cimb_va"], + "required": [ + "cimb_va" + ], "properties": { "cimb_va": { "type": "object" @@ -4323,7 +4642,9 @@ }, { "type": "object", - "required": ["danamon_va"], + "required": [ + "danamon_va" + ], "properties": { "danamon_va": { "type": "object" @@ -4332,7 +4653,9 @@ }, { "type": "object", - "required": ["mandiri_va"], + "required": [ + "mandiri_va" + ], "properties": { "mandiri_va": { "type": "object" @@ -4341,7 +4664,9 @@ }, { "type": "object", - "required": ["pix"], + "required": [ + "pix" + ], "properties": { "pix": { "$ref": "#/components/schemas/PixBankTransferAdditionalData" @@ -4350,7 +4675,9 @@ }, { "type": "object", - "required": ["pse"], + "required": [ + "pse" + ], "properties": { "pse": { "type": "object" @@ -4359,8 +4686,10 @@ }, { "type": "object", - "required": ["local_bank_transfer"], - "properties": { + "required": [ + "local_bank_transfer" + ], + "properties": { "local_bank_transfer": { "$ref": "#/components/schemas/LocalBankTransferAdditionalData" } @@ -4372,7 +4701,9 @@ "oneOf": [ { "type": "object", - "required": ["ach_bank_transfer"], + "required": [ + "ach_bank_transfer" + ], "properties": { "ach_bank_transfer": { "type": "object", @@ -4391,11 +4722,15 @@ }, { "type": "object", - "required": ["sepa_bank_transfer"], + "required": [ + "sepa_bank_transfer" + ], "properties": { "sepa_bank_transfer": { "type": "object", - "required": ["country"], + "required": [ + "country" + ], "properties": { "billing_details": { "allOf": [ @@ -4414,7 +4749,9 @@ }, { "type": "object", - "required": ["bacs_bank_transfer"], + "required": [ + "bacs_bank_transfer" + ], "properties": { "bacs_bank_transfer": { "type": "object", @@ -4433,7 +4770,9 @@ }, { "type": "object", - "required": ["multibanco_bank_transfer"], + "required": [ + "multibanco_bank_transfer" + ], "properties": { "multibanco_bank_transfer": { "type": "object", @@ -4452,7 +4791,9 @@ }, { "type": "object", - "required": ["permata_bank_transfer"], + "required": [ + "permata_bank_transfer" + ], "properties": { "permata_bank_transfer": { "type": "object", @@ -4471,7 +4812,9 @@ }, { "type": "object", - "required": ["bca_bank_transfer"], + "required": [ + "bca_bank_transfer" + ], "properties": { "bca_bank_transfer": { "type": "object", @@ -4490,7 +4833,9 @@ }, { "type": "object", - "required": ["bni_va_bank_transfer"], + "required": [ + "bni_va_bank_transfer" + ], "properties": { "bni_va_bank_transfer": { "type": "object", @@ -4509,7 +4854,9 @@ }, { "type": "object", - "required": ["bri_va_bank_transfer"], + "required": [ + "bri_va_bank_transfer" + ], "properties": { "bri_va_bank_transfer": { "type": "object", @@ -4528,7 +4875,9 @@ }, { "type": "object", - "required": ["cimb_va_bank_transfer"], + "required": [ + "cimb_va_bank_transfer" + ], "properties": { "cimb_va_bank_transfer": { "type": "object", @@ -4547,7 +4896,9 @@ }, { "type": "object", - "required": ["danamon_va_bank_transfer"], + "required": [ + "danamon_va_bank_transfer" + ], "properties": { "danamon_va_bank_transfer": { "type": "object", @@ -4566,7 +4917,9 @@ }, { "type": "object", - "required": ["mandiri_va_bank_transfer"], + "required": [ + "mandiri_va_bank_transfer" + ], "properties": { "mandiri_va_bank_transfer": { "type": "object", @@ -4585,7 +4938,9 @@ }, { "type": "object", - "required": ["pix"], + "required": [ + "pix" + ], "properties": { "pix": { "type": "object", @@ -4614,7 +4969,9 @@ }, { "type": "object", - "required": ["pse"], + "required": [ + "pse" + ], "properties": { "pse": { "type": "object" @@ -4623,7 +4980,9 @@ }, { "type": "object", - "required": ["local_bank_transfer"], + "required": [ + "local_bank_transfer" + ], "properties": { "local_bank_transfer": { "type": "object", @@ -4642,7 +5001,9 @@ "oneOf": [ { "type": "object", - "required": ["doku_bank_transfer_instructions"], + "required": [ + "doku_bank_transfer_instructions" + ], "properties": { "doku_bank_transfer_instructions": { "$ref": "#/components/schemas/DokuBankTransferInstructions" @@ -4651,7 +5012,9 @@ }, { "type": "object", - "required": ["ach_credit_transfer"], + "required": [ + "ach_credit_transfer" + ], "properties": { "ach_credit_transfer": { "$ref": "#/components/schemas/AchTransfer" @@ -4660,7 +5023,9 @@ }, { "type": "object", - "required": ["sepa_bank_instructions"], + "required": [ + "sepa_bank_instructions" + ], "properties": { "sepa_bank_instructions": { "$ref": "#/components/schemas/SepaBankTransferInstructions" @@ -4669,7 +5034,9 @@ }, { "type": "object", - "required": ["bacs_bank_instructions"], + "required": [ + "bacs_bank_instructions" + ], "properties": { "bacs_bank_instructions": { "$ref": "#/components/schemas/BacsBankTransferInstructions" @@ -4678,7 +5045,9 @@ }, { "type": "object", - "required": ["multibanco"], + "required": [ + "multibanco" + ], "properties": { "multibanco": { "$ref": "#/components/schemas/MultibancoTransferInstructions" @@ -4724,7 +5093,9 @@ }, "BankTransferTypes": { "type": "object", - "required": ["eligible_connectors"], + "required": [ + "eligible_connectors" + ], "properties": { "eligible_connectors": { "type": "array", @@ -4732,17 +5103,26 @@ "type": "string" }, "description": "The list of eligible connectors for a given payment experience", - "example": ["stripe", "adyen"] + "example": [ + "stripe", + "adyen" + ] } } }, "BankType": { "type": "string", - "enum": ["checking", "savings"] + "enum": [ + "checking", + "savings" + ] }, "BecsBankDebitAdditionalData": { "type": "object", - "required": ["account_number", "bsb_number"], + "required": [ + "account_number", + "bsb_number" + ], "properties": { "account_number": { "type": "string", @@ -4774,17 +5154,26 @@ }, "BlocklistDataKind": { "type": "string", - "enum": ["payment_method", "card_bin", "extended_card_bin"] + "enum": [ + "payment_method", + "card_bin", + "extended_card_bin" + ] }, "BlocklistRequest": { "oneOf": [ { "type": "object", - "required": ["type", "data"], + "required": [ + "type", + "data" + ], "properties": { "type": { "type": "string", - "enum": ["card_bin"] + "enum": [ + "card_bin" + ] }, "data": { "type": "string" @@ -4793,11 +5182,16 @@ }, { "type": "object", - "required": ["type", "data"], + "required": [ + "type", + "data" + ], "properties": { "type": { "type": "string", - "enum": ["fingerprint"] + "enum": [ + "fingerprint" + ] }, "data": { "type": "string" @@ -4806,11 +5200,16 @@ }, { "type": "object", - "required": ["type", "data"], + "required": [ + "type", + "data" + ], "properties": { "type": { "type": "string", - "enum": ["extended_card_bin"] + "enum": [ + "extended_card_bin" + ] }, "data": { "type": "string" @@ -4824,7 +5223,11 @@ }, "BlocklistResponse": { "type": "object", - "required": ["fingerprint_id", "data_kind", "created_at"], + "required": [ + "fingerprint_id", + "data_kind", + "created_at" + ], "properties": { "fingerprint_id": { "type": "string" @@ -4919,7 +5322,9 @@ }, { "type": "object", - "required": ["enabled_payment_methods"], + "required": [ + "enabled_payment_methods" + ], "properties": { "enabled_payment_methods": { "type": "array", @@ -4940,7 +5345,9 @@ }, { "type": "object", - "required": ["allowed_domains"], + "required": [ + "allowed_domains" + ], "properties": { "domain_name": { "type": "string", @@ -5022,7 +5429,12 @@ "CaptureMethod": { "type": "string", "description": "Default value if not passed is set to 'automatic' which results in Auth and Capture in one single API request. Pass 'manual' or 'manual_multiple' in case you want do a separate Auth and Capture by first authorizing and placing a hold on your customer's funds so that you can use the Payments/Capture endpoint later to capture the authorized amount. Pass 'manual' if you want to only capture the amount later once or 'manual_multiple' if you want to capture the funds multiple times later. Both 'manual' and 'manual_multiple' are only supported by a specific list of processors", - "enum": ["automatic", "manual", "manual_multiple", "scheduled"] + "enum": [ + "automatic", + "manual", + "manual_multiple", + "scheduled" + ] }, "CaptureResponse": { "type": "object", @@ -5098,7 +5510,12 @@ }, "CaptureStatus": { "type": "string", - "enum": ["started", "charged", "pending", "failed"] + "enum": [ + "started", + "charged", + "pending", + "failed" + ] }, "Card": { "type": "object", @@ -5175,7 +5592,11 @@ "CardAdditionalData": { "type": "object", "description": "Masked payout method details for card payout method", - "required": ["card_exp_month", "card_exp_year", "card_holder_name"], + "required": [ + "card_exp_month", + "card_exp_year", + "card_holder_name" + ], "properties": { "card_issuer": { "type": "string", @@ -5302,7 +5723,9 @@ }, "CardDetailFromLocker": { "type": "object", - "required": ["saved_to_locker"], + "required": [ + "saved_to_locker" + ], "properties": { "issuer_country": { "allOf": [ @@ -5363,7 +5786,9 @@ }, "CardDetailUpdate": { "type": "object", - "required": ["card_holder_name"], + "required": [ + "card_holder_name" + ], "properties": { "card_holder_name": { "type": "string", @@ -5398,7 +5823,9 @@ }, "CardNetworkTypes": { "type": "object", - "required": ["eligible_connectors"], + "required": [ + "eligible_connectors" + ], "properties": { "card_network": { "allOf": [ @@ -5422,7 +5849,10 @@ "type": "string" }, "description": "The list of eligible connectors for a given card network", - "example": ["stripe", "adyen"] + "example": [ + "stripe", + "adyen" + ] } } }, @@ -5459,7 +5889,9 @@ "oneOf": [ { "type": "object", - "required": ["knet"], + "required": [ + "knet" + ], "properties": { "knet": { "type": "object" @@ -5468,7 +5900,9 @@ }, { "type": "object", - "required": ["benefit"], + "required": [ + "benefit" + ], "properties": { "benefit": { "type": "object" @@ -5477,7 +5911,9 @@ }, { "type": "object", - "required": ["momo_atm"], + "required": [ + "momo_atm" + ], "properties": { "momo_atm": { "type": "object" @@ -5486,7 +5922,9 @@ }, { "type": "object", - "required": ["card_redirect"], + "required": [ + "card_redirect" + ], "properties": { "card_redirect": { "type": "object" @@ -5567,7 +6005,9 @@ }, "CardToken": { "type": "object", - "required": ["card_holder_name"], + "required": [ + "card_holder_name" + ], "properties": { "card_holder_name": { "type": "string", @@ -5583,7 +6023,9 @@ }, "CardTokenAdditionalData": { "type": "object", - "required": ["card_holder_name"], + "required": [ + "card_holder_name" + ], "properties": { "card_holder_name": { "type": "string", @@ -5609,7 +6051,10 @@ }, "CardType": { "type": "string", - "enum": ["credit", "debit"] + "enum": [ + "credit", + "debit" + ] }, "CashappQr": { "type": "object" @@ -5617,7 +6062,9 @@ "ChargeRefunds": { "type": "object", "description": "Charge specific fields for controlling the revert of funds from either platform or connected account. Check sub-fields for more details.", - "required": ["charge_id"], + "required": [ + "charge_id" + ], "properties": { "charge_id": { "type": "string", @@ -5638,7 +6085,12 @@ "Comparison": { "type": "object", "description": "Represents a single comparison condition.", - "required": ["lhs", "comparison", "value", "metadata"], + "required": [ + "lhs", + "comparison", + "value", + "metadata" + ], "properties": { "lhs": { "type": "string", @@ -5669,88 +6121,6 @@ "greater_than_equal" ] }, - "ConfirmIntentAmountDetailsResponse": { - "type": "object", - "required": [ - "currency", - "external_tax_calculation", - "surcharge_calculation", - "net_amount", - "amount_capturable" - ], - "properties": { - "order_amount": { - "type": "integer", - "format": "int64", - "description": "The payment amount. Amount for the payment in the lowest denomination of the currency, (i.e) in cents for USD denomination, in yen for JPY denomination etc. E.g., Pass 100 to charge $1.00 and 1 for 1¥ since ¥ is a zero-decimal currency. Read more about [the Decimal and Non-Decimal Currencies](https://github.com/juspay/hyperswitch/wiki/Decimal-and-Non%E2%80%90Decimal-Currencies)", - "example": 6540, - "minimum": 0 - }, - "currency": { - "$ref": "#/components/schemas/Currency" - }, - "shipping_cost": { - "allOf": [ - { - "$ref": "#/components/schemas/MinorUnit" - } - ], - "nullable": true - }, - "order_tax_amount": { - "allOf": [ - { - "$ref": "#/components/schemas/MinorUnit" - } - ], - "nullable": true - }, - "external_tax_calculation": { - "$ref": "#/components/schemas/TaxCalculationOverride" - }, - "surcharge_calculation": { - "$ref": "#/components/schemas/SurchargeCalculationOverride" - }, - "surcharge_amount": { - "allOf": [ - { - "$ref": "#/components/schemas/MinorUnit" - } - ], - "nullable": true - }, - "tax_on_surcharge": { - "allOf": [ - { - "$ref": "#/components/schemas/MinorUnit" - } - ], - "nullable": true - }, - "net_amount": { - "$ref": "#/components/schemas/MinorUnit" - }, - "amount_to_capture": { - "allOf": [ - { - "$ref": "#/components/schemas/MinorUnit" - } - ], - "nullable": true - }, - "amount_capturable": { - "$ref": "#/components/schemas/MinorUnit" - }, - "amount_captured": { - "allOf": [ - { - "$ref": "#/components/schemas/MinorUnit" - } - ], - "nullable": true - } - } - }, "Connector": { "type": "string", "description": "A connector is an integration to fulfill payments", @@ -5873,11 +6243,16 @@ "oneOf": [ { "type": "object", - "required": ["type", "data"], + "required": [ + "type", + "data" + ], "properties": { "type": { "type": "string", - "enum": ["priority"] + "enum": [ + "priority" + ] }, "data": { "type": "array", @@ -5889,11 +6264,16 @@ }, { "type": "object", - "required": ["type", "data"], + "required": [ + "type", + "data" + ], "properties": { "type": { "type": "string", - "enum": ["volume_split"] + "enum": [ + "volume_split" + ] }, "data": { "type": "array", @@ -5910,7 +6290,10 @@ }, "ConnectorStatus": { "type": "string", - "enum": ["inactive", "active"] + "enum": [ + "inactive", + "active" + ] }, "ConnectorType": { "type": "string", @@ -5931,7 +6314,10 @@ }, "ConnectorVolumeSplit": { "type": "object", - "required": ["connector", "split"], + "required": [ + "connector", + "split" + ], "properties": { "connector": { "$ref": "#/components/schemas/RoutableConnectorChoice" @@ -6226,7 +6612,10 @@ "CreateApiKeyRequest": { "type": "object", "description": "The request body for creating an API Key.", - "required": ["name", "expiration"], + "required": [ + "name", + "expiration" + ], "properties": { "name": { "type": "string", @@ -6494,7 +6883,9 @@ "CustomerAcceptance": { "type": "object", "description": "This \"CustomerAcceptance\" object is passed during Payments-Confirm request, it enlists the type, time, and mode of acceptance properties related to an acceptance done by the customer. The customer_acceptance sub object is usually passed by the SDK or client.", - "required": ["acceptance_type"], + "required": [ + "acceptance_type" + ], "properties": { "acceptance_type": { "$ref": "#/components/schemas/AcceptanceType" @@ -6519,7 +6910,10 @@ }, "CustomerDefaultPaymentMethodResponse": { "type": "object", - "required": ["customer_id", "payment_method"], + "required": [ + "customer_id", + "payment_method" + ], "properties": { "default_payment_method_id": { "type": "string", @@ -6587,7 +6981,9 @@ "CustomerDetails": { "type": "object", "description": "Passing this object creates a new customer or attaches an existing customer to the payment", - "required": ["id"], + "required": [ + "id" + ], "properties": { "id": { "type": "string", @@ -6773,7 +7169,9 @@ }, "CustomerPaymentMethodsListResponse": { "type": "object", - "required": ["customer_payment_methods"], + "required": [ + "customer_payment_methods" + ], "properties": { "customer_payment_methods": { "type": "array", @@ -6792,7 +7190,10 @@ "CustomerRequest": { "type": "object", "description": "The customer details", - "required": ["name", "email"], + "required": [ + "name", + "email" + ], "properties": { "merchant_reference_id": { "type": "string", @@ -6860,7 +7261,11 @@ }, "CustomerResponse": { "type": "object", - "required": ["merchant_reference_id", "created_at", "id"], + "required": [ + "merchant_reference_id", + "created_at", + "id" + ], "properties": { "merchant_reference_id": { "type": "string", @@ -6946,11 +7351,17 @@ }, "DecoupledAuthenticationType": { "type": "string", - "enum": ["challenge", "frictionless"] + "enum": [ + "challenge", + "frictionless" + ] }, "DefaultPaymentMethod": { "type": "object", - "required": ["customer_id", "payment_method_id"], + "required": [ + "customer_id", + "payment_method_id" + ], "properties": { "customer_id": { "type": "string", @@ -6966,11 +7377,18 @@ "DeviceChannel": { "type": "string", "description": "Device Channel indicating whether request is coming from App or Browser", - "enum": ["APP", "BRW"] + "enum": [ + "APP", + "BRW" + ] }, "DisplayAmountOnSdk": { "type": "object", - "required": ["net_amount", "order_tax_amount", "shipping_cost"], + "required": [ + "net_amount", + "order_tax_amount", + "shipping_cost" + ], "properties": { "net_amount": { "type": "string", @@ -7151,7 +7569,11 @@ "DisputeStage": { "type": "string", "description": "Stage of the dispute", - "enum": ["pre_dispute", "dispute", "pre_arbitration"] + "enum": [ + "pre_dispute", + "dispute", + "pre_arbitration" + ] }, "DisputeStatus": { "type": "string", @@ -7168,7 +7590,11 @@ }, "DokuBankTransferInstructions": { "type": "object", - "required": ["expires_at", "reference", "instructions_url"], + "required": [ + "expires_at", + "reference", + "instructions_url" + ], "properties": { "expires_at": { "type": "string", @@ -7209,12 +7635,18 @@ "EnablePaymentLinkRequest": { "type": "string", "description": "Whether payment link is requested to be enabled or not for this transaction", - "enum": ["Enable", "Skip"] + "enum": [ + "Enable", + "Skip" + ] }, "EnabledPaymentMethod": { "type": "object", "description": "Object for EnabledPaymentMethod", - "required": ["payment_method", "payment_method_types"], + "required": [ + "payment_method", + "payment_method_types" + ], "properties": { "payment_method": { "$ref": "#/components/schemas/PaymentMethod" @@ -7232,7 +7664,12 @@ "EphemeralKeyCreateResponse": { "type": "object", "description": "ephemeral_key for the customer_id mentioned", - "required": ["customer_id", "created_at", "expires", "secret"], + "required": [ + "customer_id", + "created_at", + "expires", + "secret" + ], "properties": { "customer_id": { "type": "string", @@ -7270,7 +7707,10 @@ "ErrorDetails": { "type": "object", "description": "Error details for the payment", - "required": ["code", "message"], + "required": [ + "code", + "message" + ], "properties": { "code": { "type": "string", @@ -7294,8 +7734,14 @@ }, "EventClass": { "type": "string", - "enum": ["payments", "refunds", "disputes", "mandates", "payouts"] - }, + "enum": [ + "payments", + "refunds", + "disputes", + "mandates", + "payouts" + ] + }, "EventListItemResponse": { "type": "object", "description": "The response body for each item when listing events.", @@ -7366,7 +7812,10 @@ }, { "type": "object", - "required": ["request", "response"], + "required": [ + "request", + "response" + ], "properties": { "request": { "$ref": "#/components/schemas/OutgoingWebhookRequestContent" @@ -7485,7 +7934,9 @@ }, "ExtendedCardInfoConfig": { "type": "object", - "required": ["public_key"], + "required": [ + "public_key" + ], "properties": { "public_key": { "type": "string", @@ -7503,7 +7954,9 @@ }, "ExtendedCardInfoResponse": { "type": "object", - "required": ["payload"], + "required": [ + "payload" + ], "properties": { "payload": { "type": "string" @@ -7513,12 +7966,17 @@ "External3dsAuthenticationRequest": { "type": "string", "description": "Whether 3ds authentication is requested or not", - "enum": ["Enable", "Skip"] + "enum": [ + "Enable", + "Skip" + ] }, "ExternalAuthenticationDetailsResponse": { "type": "object", "description": "Details of external authentication", - "required": ["status"], + "required": [ + "status" + ], "properties": { "authentication_flow": { "allOf": [ @@ -7584,43 +8042,63 @@ "oneOf": [ { "type": "string", - "enum": ["user_card_number"] + "enum": [ + "user_card_number" + ] }, { "type": "string", - "enum": ["user_card_expiry_month"] + "enum": [ + "user_card_expiry_month" + ] }, { "type": "string", - "enum": ["user_card_expiry_year"] + "enum": [ + "user_card_expiry_year" + ] }, { "type": "string", - "enum": ["user_card_cvc"] + "enum": [ + "user_card_cvc" + ] }, { "type": "string", - "enum": ["user_full_name"] + "enum": [ + "user_full_name" + ] }, { "type": "string", - "enum": ["user_email_address"] + "enum": [ + "user_email_address" + ] }, { "type": "string", - "enum": ["user_phone_number"] + "enum": [ + "user_phone_number" + ] }, { "type": "string", - "enum": ["user_phone_number_country_code"] + "enum": [ + "user_phone_number_country_code" + ] }, { "type": "object", - "required": ["user_country"], + "required": [ + "user_country" + ], "properties": { "user_country": { "type": "object", - "required": ["options"], + "required": [ + "options" + ], "properties": { "options": { "type": "array", @@ -7634,11 +8112,15 @@ }, { "type": "object", - "required": ["user_currency"], + "required": [ + "user_currency" + ], "properties": { "user_currency": { "type": "object", - "required": ["options"], + "required": [ + "options" + ], "properties": { "options": { "type": "array", @@ -7652,39 +8134,57 @@ }, { "type": "string", - "enum": ["user_crypto_currency_network"] + "enum": [ + "user_crypto_currency_network" + ] }, { "type": "string", - "enum": ["user_billing_name"] + "enum": [ + "user_billing_name" + ] }, { "type": "string", - "enum": ["user_address_line1"] + "enum": [ + "user_address_line1" + ] }, { "type": "string", - "enum": ["user_address_line2"] + "enum": [ + "user_address_line2" + ] }, { "type": "string", - "enum": ["user_address_city"] + "enum": [ + "user_address_city" + ] }, { "type": "string", - "enum": ["user_address_pincode"] + "enum": [ + "user_address_pincode" + ] }, { "type": "string", - "enum": ["user_address_state"] + "enum": [ + "user_address_state" + ] }, { "type": "object", - "required": ["user_address_country"], + "required": [ + "user_address_country" + ], "properties": { "user_address_country": { "type": "object", - "required": ["options"], + "required": [ + "options" + ], "properties": { "options": { "type": "array", @@ -7698,35 +8198,51 @@ }, { "type": "string", - "enum": ["user_shipping_name"] + "enum": [ + "user_shipping_name" + ] }, { "type": "string", - "enum": ["user_shipping_address_line1"] + "enum": [ + "user_shipping_address_line1" + ] }, { "type": "string", - "enum": ["user_shipping_address_line2"] + "enum": [ + "user_shipping_address_line2" + ] }, { "type": "string", - "enum": ["user_shipping_address_city"] + "enum": [ + "user_shipping_address_city" + ] }, { "type": "string", - "enum": ["user_shipping_address_pincode"] + "enum": [ + "user_shipping_address_pincode" + ] }, { "type": "string", - "enum": ["user_shipping_address_state"] + "enum": [ + "user_shipping_address_state" + ] }, { "type": "object", - "required": ["user_shipping_address_country"], + "required": [ + "user_shipping_address_country" + ], "properties": { "user_shipping_address_country": { "type": "object", - "required": ["options"], + "required": [ + "options" + ], "properties": { "options": { "type": "array", @@ -7740,27 +8256,39 @@ }, { "type": "string", - "enum": ["user_blik_code"] + "enum": [ + "user_blik_code" + ] }, { "type": "string", - "enum": ["user_bank"] + "enum": [ + "user_bank" + ] }, { "type": "string", - "enum": ["user_bank_account_number"] + "enum": [ + "user_bank_account_number" + ] }, { "type": "string", - "enum": ["text"] + "enum": [ + "text" + ] }, { "type": "object", - "required": ["drop_down"], + "required": [ + "drop_down" + ], "properties": { "drop_down": { "type": "object", - "required": ["options"], + "required": [ + "options" + ], "properties": { "options": { "type": "array", @@ -7774,19 +8302,27 @@ }, { "type": "string", - "enum": ["user_date_of_birth"] + "enum": [ + "user_date_of_birth" + ] }, { "type": "string", - "enum": ["user_vpa_id"] + "enum": [ + "user_vpa_id" + ] }, { "type": "object", - "required": ["language_preference"], + "required": [ + "language_preference" + ], "properties": { "language_preference": { "type": "object", - "required": ["options"], + "required": [ + "options" + ], "properties": { "options": { "type": "array", @@ -7800,47 +8336,71 @@ }, { "type": "string", - "enum": ["user_pix_key"] + "enum": [ + "user_pix_key" + ] }, { "type": "string", - "enum": ["user_cpf"] + "enum": [ + "user_cpf" + ] }, { "type": "string", - "enum": ["user_cnpj"] + "enum": [ + "user_cnpj" + ] }, { "type": "string", - "enum": ["user_iban"] + "enum": [ + "user_iban" + ] }, { "type": "string", - "enum": ["user_msisdn"] + "enum": [ + "user_msisdn" + ] }, { "type": "string", - "enum": ["user_client_identifier"] + "enum": [ + "user_client_identifier" + ] }, { "type": "string", - "enum": ["order_details_product_name"] + "enum": [ + "order_details_product_name" + ] } ], "description": "Possible field type of required fields in payment_method_data" }, "ForceSync": { "type": "string", - "enum": ["true", "false"] + "enum": [ + "true", + "false" + ] }, "FrmAction": { "type": "string", - "enum": ["cancel_txn", "auto_refund", "manual_review"] + "enum": [ + "cancel_txn", + "auto_refund", + "manual_review" + ] }, "FrmConfigs": { "type": "object", "description": "Details of FrmConfigs are mentioned here... it should be passed in payment connector create api call, and stored in merchant_connector_table", - "required": ["gateway", "payment_methods"], + "required": [ + "gateway", + "payment_methods" + ], "properties": { "gateway": { "$ref": "#/components/schemas/ConnectorType" @@ -7858,7 +8418,9 @@ "FrmMessage": { "type": "object", "description": "frm message is an object sent inside the payments response...when frm is invoked, its value is Some(...), else its None", - "required": ["frm_name"], + "required": [ + "frm_name" + ], "properties": { "frm_name": { "type": "string" @@ -7892,7 +8454,9 @@ "FrmPaymentMethod": { "type": "object", "description": "Details of FrmPaymentMethod are mentioned here... it should be passed in payment connector create api call, and stored in merchant_connector_table", - "required": ["payment_method"], + "required": [ + "payment_method" + ], "properties": { "payment_method": { "$ref": "#/components/schemas/PaymentMethod" @@ -7919,7 +8483,12 @@ "FrmPaymentMethodType": { "type": "object", "description": "Details of FrmPaymentMethodType are mentioned here... it should be passed in payment connector create api call, and stored in merchant_connector_table", - "required": ["payment_method_type", "card_networks", "flow", "action"], + "required": [ + "payment_method_type", + "card_networks", + "flow", + "action" + ], "properties": { "payment_method_type": { "$ref": "#/components/schemas/PaymentMethodType" @@ -7938,12 +8507,18 @@ }, "FrmPreferredFlowTypes": { "type": "string", - "enum": ["pre", "post"] + "enum": [ + "pre", + "post" + ] }, "FutureUsage": { "type": "string", "description": "Indicates that you intend to make future payments with the payment methods used for this Payment. Providing this parameter will attach the payment method to the Customer, if present, after the Payment is confirmed and any required actions from the user are complete.\n- On_session - Payment method saved only at hyperswitch when consent is provided by the user. CVV will asked during the returning user payment\n- Off_session - Payment method saved at both hyperswitch and Processor when consent is provided by the user. No input is required during the returning user payment.", - "enum": ["off_session", "on_session"] + "enum": [ + "off_session", + "on_session" + ] }, "GcashRedirection": { "type": "object" @@ -7979,7 +8554,9 @@ "oneOf": [ { "type": "object", - "required": ["givex"], + "required": [ + "givex" + ], "properties": { "givex": { "$ref": "#/components/schemas/GivexGiftCardAdditionalData" @@ -7988,7 +8565,9 @@ }, { "type": "object", - "required": ["pay_safe_card"], + "required": [ + "pay_safe_card" + ], "properties": { "pay_safe_card": { "type": "object" @@ -8001,7 +8580,9 @@ "oneOf": [ { "type": "object", - "required": ["givex"], + "required": [ + "givex" + ], "properties": { "givex": { "$ref": "#/components/schemas/GiftCardDetails" @@ -8010,7 +8591,9 @@ }, { "type": "object", - "required": ["pay_safe_card"], + "required": [ + "pay_safe_card" + ], "properties": { "pay_safe_card": { "type": "object" @@ -8021,7 +8604,10 @@ }, "GiftCardDetails": { "type": "object", - "required": ["number", "cvc"], + "required": [ + "number", + "cvc" + ], "properties": { "number": { "type": "string", @@ -8073,7 +8659,9 @@ }, "GivexGiftCardAdditionalData": { "type": "object", - "required": ["last4"], + "required": [ + "last4" + ], "properties": { "last4": { "type": "string", @@ -8087,7 +8675,10 @@ }, "GooglePayAssuranceDetails": { "type": "object", - "required": ["card_holder_authenticated", "account_verified"], + "required": [ + "card_holder_authenticated", + "account_verified" + ], "properties": { "card_holder_authenticated": { "type": "boolean", @@ -8101,7 +8692,10 @@ }, "GooglePayPaymentMethodInfo": { "type": "object", - "required": ["card_network", "card_details"], + "required": [ + "card_network", + "card_details" + ], "properties": { "card_network": { "type": "string", @@ -8185,7 +8779,11 @@ }, "GooglePayThirdPartySdk": { "type": "object", - "required": ["delayed_session_token", "connector", "sdk_next_action"], + "required": [ + "delayed_session_token", + "connector", + "sdk_next_action" + ], "properties": { "delayed_session_token": { "type": "boolean", @@ -8205,7 +8803,12 @@ }, "GooglePayWalletData": { "type": "object", - "required": ["type", "description", "info", "tokenization_data"], + "required": [ + "type", + "description", + "info", + "tokenization_data" + ], "properties": { "type": { "type": "string", @@ -8225,7 +8828,10 @@ }, "GpayAllowedMethodsParameters": { "type": "object", - "required": ["allowed_auth_methods", "allowed_card_networks"], + "required": [ + "allowed_auth_methods", + "allowed_card_networks" + ], "properties": { "allowed_auth_methods": { "type": "array", @@ -8263,7 +8869,11 @@ }, "GpayAllowedPaymentMethods": { "type": "object", - "required": ["type", "parameters", "tokenization_specification"], + "required": [ + "type", + "parameters", + "tokenization_specification" + ], "properties": { "type": { "type": "string", @@ -8279,11 +8889,17 @@ }, "GpayBillingAddressFormat": { "type": "string", - "enum": ["FULL", "MIN"] + "enum": [ + "FULL", + "MIN" + ] }, "GpayBillingAddressParameters": { "type": "object", - "required": ["phone_number_required", "format"], + "required": [ + "phone_number_required", + "format" + ], "properties": { "phone_number_required": { "type": "boolean", @@ -8296,7 +8912,9 @@ }, "GpayMerchantInfo": { "type": "object", - "required": ["merchant_name"], + "required": [ + "merchant_name" + ], "properties": { "merchant_id": { "type": "string", @@ -8321,7 +8939,9 @@ }, "GpayShippingAddressParameters": { "type": "object", - "required": ["phone_number_required"], + "required": [ + "phone_number_required" + ], "properties": { "phone_number_required": { "type": "boolean", @@ -8331,7 +8951,9 @@ }, "GpayTokenParameters": { "type": "object", - "required": ["gateway"], + "required": [ + "gateway" + ], "properties": { "gateway": { "type": "string", @@ -8354,7 +8976,10 @@ }, "GpayTokenizationData": { "type": "object", - "required": ["type", "token"], + "required": [ + "type", + "token" + ], "properties": { "type": { "type": "string", @@ -8368,7 +8993,10 @@ }, "GpayTokenizationSpecification": { "type": "object", - "required": ["type", "parameters"], + "required": [ + "type", + "parameters" + ], "properties": { "type": { "type": "string", @@ -8475,11 +9103,21 @@ }, "GsmDecision": { "type": "string", - "enum": ["retry", "requeue", "do_default"] + "enum": [ + "retry", + "requeue", + "do_default" + ] }, "GsmDeleteRequest": { "type": "object", - "required": ["connector", "flow", "sub_flow", "code", "message"], + "required": [ + "connector", + "flow", + "sub_flow", + "code", + "message" + ], "properties": { "connector": { "type": "string", @@ -8606,7 +9244,13 @@ }, "GsmRetrieveRequest": { "type": "object", - "required": ["connector", "flow", "sub_flow", "code", "message"], + "required": [ + "connector", + "flow", + "sub_flow", + "code", + "message" + ], "properties": { "connector": { "$ref": "#/components/schemas/Connector" @@ -8631,7 +9275,13 @@ }, "GsmUpdateRequest": { "type": "object", - "required": ["connector", "flow", "sub_flow", "code", "message"], + "required": [ + "connector", + "flow", + "sub_flow", + "code", + "message" + ], "properties": { "connector": { "type": "string", @@ -8699,7 +9349,9 @@ "IfStatement": { "type": "object", "description": "Represents an IF statement with conditions and optional nested IF statements\n\n```text\npayment.method = card {\npayment.method.cardtype = (credit, debit) {\npayment.method.network = (amex, rupay, diners)\n}\n}\n```", - "required": ["condition"], + "required": [ + "condition" + ], "properties": { "condition": { "type": "array", @@ -8836,7 +9488,10 @@ }, "KlarnaSessionTokenResponse": { "type": "object", - "required": ["session_token", "session_id"], + "required": [ + "session_token", + "session_id" + ], "properties": { "session_token": { "type": "string", @@ -8863,7 +9518,9 @@ }, "ListBlocklistQuery": { "type": "object", - "required": ["data_kind"], + "required": [ + "data_kind" + ], "properties": { "data_kind": { "$ref": "#/components/schemas/BlocklistDataKind" @@ -8893,7 +9550,10 @@ }, "MandateAmountData": { "type": "object", - "required": ["amount", "currency"], + "required": [ + "amount", + "currency" + ], "properties": { "amount": { "type": "integer", @@ -9075,7 +9735,10 @@ }, "MandateRevokedResponse": { "type": "object", - "required": ["mandate_id", "status"], + "required": [ + "mandate_id", + "status" + ], "properties": { "mandate_id": { "type": "string", @@ -9101,13 +9764,20 @@ "MandateStatus": { "type": "string", "description": "The status of the mandate, which indicates whether it can be used to initiate a payment.", - "enum": ["active", "inactive", "pending", "revoked"] + "enum": [ + "active", + "inactive", + "pending", + "revoked" + ] }, "MandateType": { "oneOf": [ { "type": "object", - "required": ["single_use"], + "required": [ + "single_use" + ], "properties": { "single_use": { "$ref": "#/components/schemas/MandateAmountData" @@ -9116,7 +9786,9 @@ }, { "type": "object", - "required": ["multi_use"], + "required": [ + "multi_use" + ], "properties": { "multi_use": { "allOf": [ @@ -9132,7 +9804,9 @@ }, "MaskedBankDetails": { "type": "object", - "required": ["mask"], + "required": [ + "mask" + ], "properties": { "mask": { "type": "string" @@ -9141,7 +9815,9 @@ }, "MbWayRedirection": { "type": "object", - "required": ["telephone_number"], + "required": [ + "telephone_number" + ], "properties": { "telephone_number": { "type": "string", @@ -9151,7 +9827,9 @@ }, "MerchantAccountCreate": { "type": "object", - "required": ["merchant_name"], + "required": [ + "merchant_name" + ], "properties": { "merchant_name": { "type": "string", @@ -9179,11 +9857,16 @@ "oneOf": [ { "type": "object", - "required": ["iban"], + "required": [ + "iban" + ], "properties": { "iban": { "type": "object", - "required": ["iban", "name"], + "required": [ + "iban", + "name" + ], "properties": { "iban": { "type": "string" @@ -9201,11 +9884,17 @@ }, { "type": "object", - "required": ["bacs"], + "required": [ + "bacs" + ], "properties": { "bacs": { "type": "object", - "required": ["account_number", "sort_code", "name"], + "required": [ + "account_number", + "sort_code", + "name" + ], "properties": { "account_number": { "type": "string" @@ -9228,7 +9917,10 @@ }, "MerchantAccountDeleteResponse": { "type": "object", - "required": ["merchant_id", "deleted"], + "required": [ + "merchant_id", + "deleted" + ], "properties": { "merchant_id": { "type": "string", @@ -9322,7 +10014,11 @@ "MerchantConnectorCreate": { "type": "object", "description": "Create a new Merchant Connector for the merchant account. The connector could be a payment processor / facilitator / acquirer or specialized services like Fraud / Accounting etc.\"", - "required": ["connector_type", "connector_name", "profile_id"], + "required": [ + "connector_type", + "connector_name", + "profile_id" + ], "properties": { "connector_type": { "$ref": "#/components/schemas/ConnectorType" @@ -9358,20 +10054,36 @@ "example": [ { "accepted_countries": { - "list": ["FR", "DE", "IN"], + "list": [ + "FR", + "DE", + "IN" + ], "type": "disable_only" }, "accepted_currencies": { - "list": ["USD", "EUR"], + "list": [ + "USD", + "EUR" + ], "type": "enable_only" }, "installment_payment_enabled": true, "maximum_amount": 68607706, "minimum_amount": 1, "payment_method": "wallet", - "payment_method_issuers": ["labore magna ipsum", "aute"], - "payment_method_types": ["upi_collect", "upi_intent"], - "payment_schemes": ["Discover", "Discover"], + "payment_method_issuers": [ + "labore magna ipsum", + "aute" + ], + "payment_method_types": [ + "upi_collect", + "upi_intent" + ], + "payment_schemes": [ + "Discover", + "Discover" + ], "recurring_enabled": true } ], @@ -9440,7 +10152,11 @@ }, "MerchantConnectorDeleteResponse": { "type": "object", - "required": ["merchant_id", "id", "deleted"], + "required": [ + "merchant_id", + "id", + "deleted" + ], "properties": { "merchant_id": { "type": "string", @@ -9478,7 +10194,9 @@ "MerchantConnectorDetailsWrap": { "type": "object", "description": "Merchant connector details used to make payments.", - "required": ["creds_identifier"], + "required": [ + "creds_identifier" + ], "properties": { "creds_identifier": { "type": "string", @@ -9496,7 +10214,9 @@ }, "MerchantConnectorId": { "type": "object", - "required": ["id"], + "required": [ + "id" + ], "properties": { "id": { "type": "string" @@ -9544,20 +10264,36 @@ "example": [ { "accepted_countries": { - "list": ["FR", "DE", "IN"], + "list": [ + "FR", + "DE", + "IN" + ], "type": "disable_only" }, "accepted_currencies": { - "list": ["USD", "EUR"], + "list": [ + "USD", + "EUR" + ], "type": "enable_only" }, "installment_payment_enabled": true, "maximum_amount": 68607706, "minimum_amount": 1, "payment_method": "wallet", - "payment_method_issuers": ["labore magna ipsum", "aute"], - "payment_method_types": ["upi_collect", "upi_intent"], - "payment_schemes": ["Discover", "Discover"], + "payment_method_issuers": [ + "labore magna ipsum", + "aute" + ], + "payment_method_types": [ + "upi_collect", + "upi_intent" + ], + "payment_schemes": [ + "Discover", + "Discover" + ], "recurring_enabled": true } ], @@ -9647,20 +10383,36 @@ "example": [ { "accepted_countries": { - "list": ["FR", "DE", "IN"], + "list": [ + "FR", + "DE", + "IN" + ], "type": "disable_only" }, "accepted_currencies": { - "list": ["USD", "EUR"], + "list": [ + "USD", + "EUR" + ], "type": "enable_only" }, "installment_payment_enabled": true, "maximum_amount": 68607706, "minimum_amount": 1, "payment_method": "wallet", - "payment_method_issuers": ["labore magna ipsum", "aute"], - "payment_method_types": ["upi_collect", "upi_intent"], - "payment_schemes": ["Discover", "Discover"], + "payment_method_issuers": [ + "labore magna ipsum", + "aute" + ], + "payment_method_types": [ + "upi_collect", + "upi_intent" + ], + "payment_schemes": [ + "Discover", + "Discover" + ], "recurring_enabled": true } ], @@ -9733,7 +10485,11 @@ "MerchantConnectorUpdate": { "type": "object", "description": "Create a new Merchant Connector for the merchant account. The connector could be a payment processor / facilitator / acquirer or specialized services like Fraud / Accounting etc.\"", - "required": ["connector_type", "status", "merchant_id"], + "required": [ + "connector_type", + "status", + "merchant_id" + ], "properties": { "connector_type": { "$ref": "#/components/schemas/ConnectorType" @@ -9761,20 +10517,36 @@ "example": [ { "accepted_countries": { - "list": ["FR", "DE", "IN"], + "list": [ + "FR", + "DE", + "IN" + ], "type": "disable_only" }, "accepted_currencies": { - "list": ["USD", "EUR"], + "list": [ + "USD", + "EUR" + ], "type": "enable_only" }, "installment_payment_enabled": true, "maximum_amount": 68607706, "minimum_amount": 1, "payment_method": "wallet", - "payment_method_issuers": ["labore magna ipsum", "aute"], - "payment_method_types": ["upi_collect", "upi_intent"], - "payment_schemes": ["Discover", "Discover"], + "payment_method_issuers": [ + "labore magna ipsum", + "aute" + ], + "payment_method_types": [ + "upi_collect", + "upi_intent" + ], + "payment_schemes": [ + "Discover", + "Discover" + ], "recurring_enabled": true } ], @@ -9845,7 +10617,10 @@ }, "MerchantConnectorWebhookDetails": { "type": "object", - "required": ["merchant_secret", "additional_secret"], + "required": [ + "merchant_secret", + "additional_secret" + ], "properties": { "merchant_secret": { "type": "string", @@ -9932,7 +10707,9 @@ "oneOf": [ { "type": "object", - "required": ["connector_recipient_id"], + "required": [ + "connector_recipient_id" + ], "properties": { "connector_recipient_id": { "type": "string", @@ -9942,7 +10719,9 @@ }, { "type": "object", - "required": ["wallet_id"], + "required": [ + "wallet_id" + ], "properties": { "wallet_id": { "type": "string", @@ -9952,7 +10731,9 @@ }, { "type": "object", - "required": ["account_data"], + "required": [ + "account_data" + ], "properties": { "account_data": { "$ref": "#/components/schemas/MerchantAccountData" @@ -10005,7 +10786,10 @@ }, "MetadataValue": { "type": "object", - "required": ["key", "value"], + "required": [ + "key", + "value" + ], "properties": { "key": { "type": "string" @@ -10017,7 +10801,9 @@ }, "MifinityData": { "type": "object", - "required": ["date_of_birth"], + "required": [ + "date_of_birth" + ], "properties": { "date_of_birth": { "type": "string", @@ -10036,24 +10822,35 @@ }, "MitExemptionRequest": { "type": "string", - "enum": ["Apply", "Skip"] + "enum": [ + "Apply", + "Skip" + ] }, "MobilePayRedirection": { "type": "object" }, "MobilePaymentConsent": { "type": "string", - "enum": ["consent_required", "consent_not_required", "consent_optional"] + "enum": [ + "consent_required", + "consent_not_required", + "consent_optional" + ] }, "MobilePaymentData": { "oneOf": [ { "type": "object", - "required": ["direct_carrier_billing"], + "required": [ + "direct_carrier_billing" + ], "properties": { "direct_carrier_billing": { "type": "object", - "required": ["msisdn"], + "required": [ + "msisdn" + ], "properties": { "msisdn": { "type": "string", @@ -10074,7 +10871,9 @@ }, "MobilePaymentNextStepData": { "type": "object", - "required": ["consent_data_required"], + "required": [ + "consent_data_required" + ], "properties": { "consent_data_required": { "$ref": "#/components/schemas/MobilePaymentConsent" @@ -10111,7 +10910,10 @@ }, "MultibancoTransferInstructions": { "type": "object", - "required": ["reference", "entity"], + "required": [ + "reference", + "entity" + ], "properties": { "reference": { "type": "string", @@ -10196,42 +10998,59 @@ }, "NextActionCall": { "type": "string", - "enum": ["post_session_tokens", "confirm", "sync", "complete_authorize"] + "enum": [ + "post_session_tokens", + "confirm", + "sync", + "complete_authorize" + ] }, "NextActionData": { "oneOf": [ { "type": "object", "description": "Contains the url for redirection flow", - "required": ["redirect_to_url", "type"], + "required": [ + "redirect_to_url", + "type" + ], "properties": { "redirect_to_url": { "type": "string" }, "type": { "type": "string", - "enum": ["redirect_to_url"] + "enum": [ + "redirect_to_url" + ] } } }, { "type": "object", "description": "Informs the next steps for bank transfer and also contains the charges details (ex: amount received, amount charged etc)", - "required": ["bank_transfer_steps_and_charges_details", "type"], + "required": [ + "bank_transfer_steps_and_charges_details", + "type" + ], "properties": { "bank_transfer_steps_and_charges_details": { "$ref": "#/components/schemas/BankTransferNextStepsData" }, "type": { "type": "string", - "enum": ["display_bank_transfer_information"] + "enum": [ + "display_bank_transfer_information" + ] } } }, { "type": "object", "description": "Contains third party sdk session token response", - "required": ["type"], + "required": [ + "type" + ], "properties": { "session_token": { "allOf": [ @@ -10243,14 +11062,20 @@ }, "type": { "type": "string", - "enum": ["third_party_sdk_session_token"] + "enum": [ + "third_party_sdk_session_token" + ] } } }, { "type": "object", "description": "Contains url for Qr code image, this qr code has to be shown in sdk", - "required": ["image_data_url", "qr_code_url", "type"], + "required": [ + "image_data_url", + "qr_code_url", + "type" + ], "properties": { "image_data_url": { "type": "string", @@ -10267,42 +11092,57 @@ }, "type": { "type": "string", - "enum": ["qr_code_information"] + "enum": [ + "qr_code_information" + ] } } }, { "type": "object", "description": "Contains url to fetch Qr code data", - "required": ["qr_code_fetch_url", "type"], + "required": [ + "qr_code_fetch_url", + "type" + ], "properties": { "qr_code_fetch_url": { "type": "string" }, "type": { "type": "string", - "enum": ["fetch_qr_code_information"] + "enum": [ + "fetch_qr_code_information" + ] } } }, { "type": "object", "description": "Contains the download url and the reference number for transaction", - "required": ["voucher_details", "type"], + "required": [ + "voucher_details", + "type" + ], "properties": { "voucher_details": { "type": "string" }, "type": { "type": "string", - "enum": ["display_voucher_information"] + "enum": [ + "display_voucher_information" + ] } } }, { "type": "object", "description": "Contains duration for displaying a wait screen, wait screen with timer is displayed by sdk", - "required": ["display_from_timestamp", "type"], + "required": [ + "display_from_timestamp", + "type" + ], "properties": { "display_from_timestamp": { "type": "integer" @@ -10313,48 +11153,65 @@ }, "type": { "type": "string", - "enum": ["wait_screen_information"] + "enum": [ + "wait_screen_information" + ] } } }, { "type": "object", "description": "Contains the information regarding three_ds_method_data submission, three_ds authentication, and authorization flows", - "required": ["three_ds_data", "type"], + "required": [ + "three_ds_data", + "type" + ], "properties": { "three_ds_data": { "$ref": "#/components/schemas/ThreeDsData" }, "type": { "type": "string", - "enum": ["three_ds_invoke"] + "enum": [ + "three_ds_invoke" + ] } } }, { "type": "object", - "required": ["next_action_data", "type"], + "required": [ + "next_action_data", + "type" + ], "properties": { "next_action_data": { "$ref": "#/components/schemas/SdkNextActionData" }, "type": { "type": "string", - "enum": ["invoke_sdk_client"] + "enum": [ + "invoke_sdk_client" + ] } } }, { "type": "object", "description": "Contains consent to collect otp for mobile payment", - "required": ["consent_data_required", "type"], + "required": [ + "consent_data_required", + "type" + ], "properties": { "consent_data_required": { "$ref": "#/components/schemas/MobilePaymentConsent" }, "type": { "type": "string", - "enum": ["collect_otp"] + "enum": [ + "collect_otp" + ] } } } @@ -10456,7 +11313,10 @@ "NumberComparison": { "type": "object", "description": "Represents a number comparison for \"NumberComparisonArrayValue\"", - "required": ["comparisonType", "number"], + "required": [ + "comparisonType", + "number" + ], "properties": { "comparisonType": { "$ref": "#/components/schemas/ComparisonType" @@ -10468,7 +11328,10 @@ }, "OnlineMandate": { "type": "object", - "required": ["ip_address", "user_agent"], + "required": [ + "ip_address", + "user_agent" + ], "properties": { "ip_address": { "type": "string", @@ -10486,7 +11349,9 @@ "oneOf": [ { "type": "object", - "required": ["open_banking_pis"], + "required": [ + "open_banking_pis" + ], "properties": { "open_banking_pis": { "type": "object" @@ -10512,7 +11377,9 @@ }, "OpenBankingSessionToken": { "type": "object", - "required": ["open_banking_session_token"], + "required": [ + "open_banking_session_token" + ], "properties": { "open_banking_session_token": { "type": "string", @@ -10522,7 +11389,10 @@ }, "OrderDetails": { "type": "object", - "required": ["product_name", "quantity"], + "required": [ + "product_name", + "quantity" + ], "properties": { "product_name": { "type": "string", @@ -10583,7 +11453,11 @@ }, "OrderDetailsWithAmount": { "type": "object", - "required": ["product_name", "quantity", "amount"], + "required": [ + "product_name", + "quantity", + "amount" + ], "properties": { "product_name": { "type": "string", @@ -10647,11 +11521,16 @@ }, "OrderFulfillmentTimeOrigin": { "type": "string", - "enum": ["create", "confirm"] + "enum": [ + "create", + "confirm" + ] }, "OrganizationCreateRequest": { "type": "object", - "required": ["organization_name"], + "required": [ + "organization_name" + ], "properties": { "organization_name": { "type": "string", @@ -10672,7 +11551,11 @@ }, "OrganizationResponse": { "type": "object", - "required": ["id", "modified_at", "created_at"], + "required": [ + "id", + "modified_at", + "created_at" + ], "properties": { "id": { "type": "string", @@ -10729,7 +11612,12 @@ }, "OutgoingWebhook": { "type": "object", - "required": ["merchant_id", "event_id", "event_type", "content"], + "required": [ + "merchant_id", + "event_id", + "event_type", + "content" + ], "properties": { "merchant_id": { "type": "string", @@ -10757,11 +11645,16 @@ { "type": "object", "title": "PaymentsResponse", - "required": ["type", "object"], + "required": [ + "type", + "object" + ], "properties": { "type": { "type": "string", - "enum": ["payment_details"] + "enum": [ + "payment_details" + ] }, "object": { "$ref": "#/components/schemas/PaymentsResponse" @@ -10771,11 +11664,16 @@ { "type": "object", "title": "RefundResponse", - "required": ["type", "object"], + "required": [ + "type", + "object" + ], "properties": { "type": { "type": "string", - "enum": ["refund_details"] + "enum": [ + "refund_details" + ] }, "object": { "$ref": "#/components/schemas/RefundResponse" @@ -10785,11 +11683,16 @@ { "type": "object", "title": "DisputeResponse", - "required": ["type", "object"], + "required": [ + "type", + "object" + ], "properties": { "type": { "type": "string", - "enum": ["dispute_details"] + "enum": [ + "dispute_details" + ] }, "object": { "$ref": "#/components/schemas/DisputeResponse" @@ -10799,11 +11702,16 @@ { "type": "object", "title": "MandateResponse", - "required": ["type", "object"], + "required": [ + "type", + "object" + ], "properties": { "type": { "type": "string", - "enum": ["mandate_details"] + "enum": [ + "mandate_details" + ] }, "object": { "$ref": "#/components/schemas/MandateResponse" @@ -10813,11 +11721,16 @@ { "type": "object", "title": "PayoutCreateResponse", - "required": ["type", "object"], + "required": [ + "type", + "object" + ], "properties": { "type": { "type": "string", - "enum": ["payout_details"] + "enum": [ + "payout_details" + ] }, "object": { "$ref": "#/components/schemas/PayoutCreateResponse" @@ -10832,7 +11745,10 @@ "OutgoingWebhookRequestContent": { "type": "object", "description": "The request information (headers and body) sent in the webhook.", - "required": ["body", "headers"], + "required": [ + "body", + "headers" + ], "properties": { "body": { "type": "string", @@ -10855,8 +11771,14 @@ }, "description": "The request headers sent in the webhook.", "example": [ - ["content-type", "application/json"], - ["content-length", "1024"] + [ + "content-type", + "application/json" + ], + [ + "content-length", + "1024" + ] ] } } @@ -10887,8 +11809,14 @@ }, "description": "The response headers received for the webhook sent.", "example": [ - ["content-type", "application/json"], - ["content-length", "1024"] + [ + "content-type", + "application/json" + ], + [ + "content-length", + "1024" + ] ], "nullable": true }, @@ -10912,7 +11840,9 @@ "oneOf": [ { "type": "object", - "required": ["klarna_redirect"], + "required": [ + "klarna_redirect" + ], "properties": { "klarna_redirect": { "type": "object", @@ -10937,12 +11867,16 @@ }, { "type": "object", - "required": ["klarna_sdk"], + "required": [ + "klarna_sdk" + ], "properties": { "klarna_sdk": { "type": "object", "description": "For Klarna Sdk as PayLater Option", - "required": ["token"], + "required": [ + "token" + ], "properties": { "token": { "type": "string", @@ -10954,7 +11888,9 @@ }, { "type": "object", - "required": ["affirm_redirect"], + "required": [ + "affirm_redirect" + ], "properties": { "affirm_redirect": { "type": "object", @@ -10964,7 +11900,9 @@ }, { "type": "object", - "required": ["afterpay_clearpay_redirect"], + "required": [ + "afterpay_clearpay_redirect" + ], "properties": { "afterpay_clearpay_redirect": { "type": "object", @@ -10986,7 +11924,9 @@ }, { "type": "object", - "required": ["pay_bright_redirect"], + "required": [ + "pay_bright_redirect" + ], "properties": { "pay_bright_redirect": { "type": "object", @@ -10996,7 +11936,9 @@ }, { "type": "object", - "required": ["walley_redirect"], + "required": [ + "walley_redirect" + ], "properties": { "walley_redirect": { "type": "object", @@ -11006,7 +11948,9 @@ }, { "type": "object", - "required": ["alma_redirect"], + "required": [ + "alma_redirect" + ], "properties": { "alma_redirect": { "type": "object", @@ -11016,7 +11960,9 @@ }, { "type": "object", - "required": ["atome_redirect"], + "required": [ + "atome_redirect" + ], "properties": { "atome_redirect": { "type": "object" @@ -11027,7 +11973,9 @@ }, "PayPalWalletData": { "type": "object", - "required": ["token"], + "required": [ + "token" + ], "properties": { "token": { "type": "string", @@ -11052,8 +12000,8 @@ "type": "object", "required": [ "currency", - "skip_external_tax_calculation", - "skip_surcharge_calculation", + "external_tax_calculation", + "surcharge_calculation", "net_amount", "amount_capturable" ], @@ -11084,10 +12032,10 @@ ], "nullable": true }, - "skip_external_tax_calculation": { + "external_tax_calculation": { "$ref": "#/components/schemas/TaxCalculationOverride" }, - "skip_surcharge_calculation": { + "surcharge_calculation": { "$ref": "#/components/schemas/SurchargeCalculationOverride" }, "surcharge_amount": { @@ -11284,7 +12232,11 @@ "PaymentChargeRequest": { "type": "object", "description": "Fee information to be charged on the payment being collected", - "required": ["charge_type", "fees", "transfer_account_id"], + "required": [ + "charge_type", + "fees", + "transfer_account_id" + ], "properties": { "charge_type": { "$ref": "#/components/schemas/PaymentChargeType" @@ -11304,7 +12256,11 @@ "PaymentChargeResponse": { "type": "object", "description": "Fee information to be charged on the payment being collected", - "required": ["charge_type", "application_fees", "transfer_account_id"], + "required": [ + "charge_type", + "application_fees", + "transfer_account_id" + ], "properties": { "charge_id": { "type": "string", @@ -11330,7 +12286,9 @@ "oneOf": [ { "type": "object", - "required": ["Stripe"], + "required": [ + "Stripe" + ], "properties": { "Stripe": { "$ref": "#/components/schemas/StripeChargeType" @@ -11371,7 +12329,9 @@ }, "PaymentExperienceTypes": { "type": "object", - "required": ["eligible_connectors"], + "required": [ + "eligible_connectors" + ], "properties": { "payment_experience_type": { "allOf": [ @@ -11387,7 +12347,10 @@ "type": "string" }, "description": "The list of eligible connectors for a given payment experience", - "example": ["stripe", "adyen"] + "example": [ + "stripe", + "adyen" + ] } } }, @@ -11526,7 +12489,10 @@ }, "PaymentLinkInitiateRequest": { "type": "object", - "required": ["merchant_id", "payment_id"], + "required": [ + "merchant_id", + "payment_id" + ], "properties": { "merchant_id": { "type": "string" @@ -11538,7 +12504,10 @@ }, "PaymentLinkResponse": { "type": "object", - "required": ["link", "payment_link_id"], + "required": [ + "link", + "payment_link_id" + ], "properties": { "link": { "type": "string", @@ -11558,11 +12527,17 @@ "PaymentLinkStatus": { "type": "string", "description": "Status Of the Payment Link", - "enum": ["active", "expired"] + "enum": [ + "active", + "expired" + ] }, "PaymentLinkTransactionDetails": { "type": "object", - "required": ["key", "value"], + "required": [ + "key", + "value" + ], "properties": { "key": { "type": "string", @@ -11657,7 +12632,10 @@ }, "PaymentListResponse": { "type": "object", - "required": ["size", "data"], + "required": [ + "size", + "data" + ], "properties": { "size": { "type": "integer", @@ -11705,7 +12683,9 @@ }, { "type": "object", - "required": ["customer_id"], + "required": [ + "customer_id" + ], "properties": { "pm_collect_link_id": { "type": "string", @@ -11752,7 +12732,12 @@ }, { "type": "object", - "required": ["pm_collect_link_id", "customer_id", "expiry", "link"], + "required": [ + "pm_collect_link_id", + "customer_id", + "expiry", + "link" + ], "properties": { "pm_collect_link_id": { "type": "string", @@ -11839,7 +12824,9 @@ "oneOf": [ { "type": "object", - "required": ["card"], + "required": [ + "card" + ], "properties": { "card": { "$ref": "#/components/schemas/CardDetail" @@ -11853,7 +12840,9 @@ { "type": "object", "title": "Card", - "required": ["card"], + "required": [ + "card" + ], "properties": { "card": { "$ref": "#/components/schemas/Card" @@ -11863,7 +12852,9 @@ { "type": "object", "title": "CardRedirect", - "required": ["card_redirect"], + "required": [ + "card_redirect" + ], "properties": { "card_redirect": { "$ref": "#/components/schemas/CardRedirectData" @@ -11873,7 +12864,9 @@ { "type": "object", "title": "Wallet", - "required": ["wallet"], + "required": [ + "wallet" + ], "properties": { "wallet": { "$ref": "#/components/schemas/WalletData" @@ -11883,7 +12876,9 @@ { "type": "object", "title": "PayLater", - "required": ["pay_later"], + "required": [ + "pay_later" + ], "properties": { "pay_later": { "$ref": "#/components/schemas/PayLaterData" @@ -11893,7 +12888,9 @@ { "type": "object", "title": "BankRedirect", - "required": ["bank_redirect"], + "required": [ + "bank_redirect" + ], "properties": { "bank_redirect": { "$ref": "#/components/schemas/BankRedirectData" @@ -11903,7 +12900,9 @@ { "type": "object", "title": "BankDebit", - "required": ["bank_debit"], + "required": [ + "bank_debit" + ], "properties": { "bank_debit": { "$ref": "#/components/schemas/BankDebitData" @@ -11913,7 +12912,9 @@ { "type": "object", "title": "BankTransfer", - "required": ["bank_transfer"], + "required": [ + "bank_transfer" + ], "properties": { "bank_transfer": { "$ref": "#/components/schemas/BankTransferData" @@ -11923,7 +12924,9 @@ { "type": "object", "title": "RealTimePayment", - "required": ["real_time_payment"], + "required": [ + "real_time_payment" + ], "properties": { "real_time_payment": { "$ref": "#/components/schemas/RealTimePaymentData" @@ -11933,7 +12936,9 @@ { "type": "object", "title": "Crypto", - "required": ["crypto"], + "required": [ + "crypto" + ], "properties": { "crypto": { "$ref": "#/components/schemas/CryptoData" @@ -11943,17 +12948,23 @@ { "type": "string", "title": "MandatePayment", - "enum": ["mandate_payment"] + "enum": [ + "mandate_payment" + ] }, { "type": "string", "title": "Reward", - "enum": ["reward"] + "enum": [ + "reward" + ] }, { "type": "object", "title": "Upi", - "required": ["upi"], + "required": [ + "upi" + ], "properties": { "upi": { "$ref": "#/components/schemas/UpiData" @@ -11963,7 +12974,9 @@ { "type": "object", "title": "Voucher", - "required": ["voucher"], + "required": [ + "voucher" + ], "properties": { "voucher": { "$ref": "#/components/schemas/VoucherData" @@ -11973,7 +12986,9 @@ { "type": "object", "title": "GiftCard", - "required": ["gift_card"], + "required": [ + "gift_card" + ], "properties": { "gift_card": { "$ref": "#/components/schemas/GiftCardData" @@ -11983,7 +12998,9 @@ { "type": "object", "title": "CardToken", - "required": ["card_token"], + "required": [ + "card_token" + ], "properties": { "card_token": { "$ref": "#/components/schemas/CardToken" @@ -11993,7 +13010,9 @@ { "type": "object", "title": "OpenBanking", - "required": ["open_banking"], + "required": [ + "open_banking" + ], "properties": { "open_banking": { "$ref": "#/components/schemas/OpenBankingData" @@ -12003,7 +13022,9 @@ { "type": "object", "title": "MobilePayment", - "required": ["mobile_payment"], + "required": [ + "mobile_payment" + ], "properties": { "mobile_payment": { "$ref": "#/components/schemas/MobilePaymentData" @@ -12042,7 +13063,9 @@ "oneOf": [ { "type": "object", - "required": ["card"], + "required": [ + "card" + ], "properties": { "card": { "$ref": "#/components/schemas/CardResponse" @@ -12051,7 +13074,9 @@ }, { "type": "object", - "required": ["bank_transfer"], + "required": [ + "bank_transfer" + ], "properties": { "bank_transfer": { "$ref": "#/components/schemas/BankTransferResponse" @@ -12060,7 +13085,9 @@ }, { "type": "object", - "required": ["wallet"], + "required": [ + "wallet" + ], "properties": { "wallet": { "$ref": "#/components/schemas/WalletResponse" @@ -12069,7 +13096,9 @@ }, { "type": "object", - "required": ["pay_later"], + "required": [ + "pay_later" + ], "properties": { "pay_later": { "$ref": "#/components/schemas/PaylaterResponse" @@ -12078,7 +13107,9 @@ }, { "type": "object", - "required": ["bank_redirect"], + "required": [ + "bank_redirect" + ], "properties": { "bank_redirect": { "$ref": "#/components/schemas/BankRedirectResponse" @@ -12087,7 +13118,9 @@ }, { "type": "object", - "required": ["crypto"], + "required": [ + "crypto" + ], "properties": { "crypto": { "$ref": "#/components/schemas/CryptoResponse" @@ -12096,7 +13129,9 @@ }, { "type": "object", - "required": ["bank_debit"], + "required": [ + "bank_debit" + ], "properties": { "bank_debit": { "$ref": "#/components/schemas/BankDebitResponse" @@ -12105,7 +13140,9 @@ }, { "type": "object", - "required": ["mandate_payment"], + "required": [ + "mandate_payment" + ], "properties": { "mandate_payment": { "type": "object" @@ -12114,7 +13151,9 @@ }, { "type": "object", - "required": ["reward"], + "required": [ + "reward" + ], "properties": { "reward": { "type": "object" @@ -12123,7 +13162,9 @@ }, { "type": "object", - "required": ["real_time_payment"], + "required": [ + "real_time_payment" + ], "properties": { "real_time_payment": { "$ref": "#/components/schemas/RealTimePaymentDataResponse" @@ -12132,7 +13173,9 @@ }, { "type": "object", - "required": ["upi"], + "required": [ + "upi" + ], "properties": { "upi": { "$ref": "#/components/schemas/UpiResponse" @@ -12141,7 +13184,9 @@ }, { "type": "object", - "required": ["voucher"], + "required": [ + "voucher" + ], "properties": { "voucher": { "$ref": "#/components/schemas/VoucherResponse" @@ -12150,7 +13195,9 @@ }, { "type": "object", - "required": ["gift_card"], + "required": [ + "gift_card" + ], "properties": { "gift_card": { "$ref": "#/components/schemas/GiftCardResponse" @@ -12159,7 +13206,9 @@ }, { "type": "object", - "required": ["card_redirect"], + "required": [ + "card_redirect" + ], "properties": { "card_redirect": { "$ref": "#/components/schemas/CardRedirectResponse" @@ -12168,7 +13217,9 @@ }, { "type": "object", - "required": ["card_token"], + "required": [ + "card_token" + ], "properties": { "card_token": { "$ref": "#/components/schemas/CardTokenResponse" @@ -12177,7 +13228,9 @@ }, { "type": "object", - "required": ["open_banking"], + "required": [ + "open_banking" + ], "properties": { "open_banking": { "$ref": "#/components/schemas/OpenBankingResponse" @@ -12186,7 +13239,9 @@ }, { "type": "object", - "required": ["mobile_payment"], + "required": [ + "mobile_payment" + ], "properties": { "mobile_payment": { "$ref": "#/components/schemas/MobilePaymentResponse" @@ -12222,7 +13277,9 @@ }, "PaymentMethodDeleteResponse": { "type": "object", - "required": ["payment_method_id"], + "required": [ + "payment_method_id" + ], "properties": { "payment_method_id": { "type": "string", @@ -12266,7 +13323,9 @@ }, "PaymentMethodIntentCreate": { "type": "object", - "required": ["customer_id"], + "required": [ + "customer_id" + ], "properties": { "metadata": { "type": "object", @@ -12310,7 +13369,9 @@ "oneOf": [ { "type": "object", - "required": ["card"], + "required": [ + "card" + ], "properties": { "card": { "$ref": "#/components/schemas/CardDetailFromLocker" @@ -12319,7 +13380,9 @@ }, { "type": "object", - "required": ["bank"], + "required": [ + "bank" + ], "properties": { "bank": { "$ref": "#/components/schemas/Bank" @@ -12345,7 +13408,11 @@ "$ref": "#/components/schemas/CountryAlpha2" }, "description": "The two-letter ISO currency code", - "example": ["US", "UK", "IN"], + "example": [ + "US", + "UK", + "IN" + ], "nullable": true }, "amount": { @@ -12362,7 +13429,10 @@ "$ref": "#/components/schemas/Currency" }, "description": "The three-letter ISO currency code", - "example": ["USD", "EUR"], + "example": [ + "USD", + "EUR" + ], "nullable": true }, "recurring_enabled": { @@ -12377,7 +13447,10 @@ "$ref": "#/components/schemas/CardNetwork" }, "description": "Indicates whether the payment method is eligible for card netwotks", - "example": ["visa", "mastercard"], + "example": [ + "visa", + "mastercard" + ], "nullable": true }, "limit": { @@ -12532,7 +13605,9 @@ "oneOf": [ { "type": "object", - "required": ["card"], + "required": [ + "card" + ], "properties": { "card": { "$ref": "#/components/schemas/CardDetailFromLocker" @@ -12544,7 +13619,12 @@ "PaymentMethodStatus": { "type": "string", "description": "Payment Method Status", - "enum": ["active", "inactive", "processing", "awaiting_data"] + "enum": [ + "active", + "inactive", + "processing", + "awaiting_data" + ] }, "PaymentMethodType": { "type": "string", @@ -12649,7 +13729,9 @@ }, "PaymentMethodUpdate": { "type": "object", - "required": ["payment_method_data"], + "required": [ + "payment_method_data" + ], "properties": { "payment_method_data": { "$ref": "#/components/schemas/PaymentMethodUpdateData" @@ -12669,7 +13751,9 @@ "oneOf": [ { "type": "object", - "required": ["card"], + "required": [ + "card" + ], "properties": { "card": { "$ref": "#/components/schemas/CardDetailUpdate" @@ -12681,7 +13765,9 @@ "PaymentMethodsEnabled": { "type": "object", "description": "Details of all the payment methods enabled for the connector for the given merchant account", - "required": ["payment_method"], + "required": [ + "payment_method" + ], "properties": { "payment_method": { "$ref": "#/components/schemas/PaymentMethod" @@ -12692,7 +13778,9 @@ "$ref": "#/components/schemas/RequestPaymentMethodTypes" }, "description": "Subtype of payment method", - "example": ["credit"], + "example": [ + "credit" + ], "nullable": true } }, @@ -12722,11 +13810,15 @@ }, { "type": "object", - "required": ["payment_processing_details_at"], + "required": [ + "payment_processing_details_at" + ], "properties": { "payment_processing_details_at": { "type": "string", - "enum": ["Hyperswitch"] + "enum": [ + "Hyperswitch" + ] } } } @@ -12734,11 +13826,15 @@ }, { "type": "object", - "required": ["payment_processing_details_at"], + "required": [ + "payment_processing_details_at" + ], "properties": { "payment_processing_details_at": { "type": "string", - "enum": ["Connector"] + "enum": [ + "Connector" + ] } } } @@ -12780,7 +13876,12 @@ "PaymentType": { "type": "string", "description": "The type of the payment that differentiates between normal and various types of mandate payments. Use 'setup_mandate' in case of zero auth flow.", - "enum": ["normal", "new_mandate", "setup_mandate", "recurring_mandate"] + "enum": [ + "normal", + "new_mandate", + "setup_mandate", + "recurring_mandate" + ] }, "PaymentsCancelRequest": { "type": "object", @@ -12814,7 +13915,9 @@ }, "PaymentsCompleteAuthorizeRequest": { "type": "object", - "required": ["client_secret"], + "required": [ + "client_secret" + ], "properties": { "shipping": { "allOf": [ @@ -12982,7 +14085,9 @@ }, "PaymentsCreateIntentRequest": { "type": "object", - "required": ["amount_details"], + "required": [ + "amount_details" + ], "properties": { "amount_details": { "$ref": "#/components/schemas/AmountDetails" @@ -13711,7 +14816,11 @@ }, "PaymentsDynamicTaxCalculationRequest": { "type": "object", - "required": ["shipping", "client_secret", "payment_method_type"], + "required": [ + "shipping", + "client_secret", + "payment_method_type" + ], "properties": { "shipping": { "$ref": "#/components/schemas/Address" @@ -13732,7 +14841,11 @@ }, "PaymentsDynamicTaxCalculationResponse": { "type": "object", - "required": ["payment_id", "net_amount", "display_amount"], + "required": [ + "payment_id", + "net_amount", + "display_amount" + ], "properties": { "payment_id": { "type": "string", @@ -13792,7 +14905,10 @@ }, "PaymentsExternalAuthenticationResponse": { "type": "object", - "required": ["trans_status", "three_ds_requestor_url"], + "required": [ + "trans_status", + "three_ds_requestor_url" + ], "properties": { "trans_status": { "$ref": "#/components/schemas/TransactionStatus" @@ -13835,7 +14951,9 @@ }, "PaymentsIncrementalAuthorizationRequest": { "type": "object", - "required": ["amount"], + "required": [ + "amount" + ], "properties": { "amount": { "type": "integer", @@ -14614,7 +15732,13 @@ "PaymentsRetrieveResponse": { "type": "object", "description": "Response for Payment Intent Confirm", - "required": ["id", "status", "amount", "client_secret", "created"], + "required": [ + "id", + "status", + "amount", + "client_secret", + "created" + ], "properties": { "id": { "type": "string", @@ -14725,7 +15849,10 @@ }, "PaymentsSessionResponse": { "type": "object", - "required": ["payment_id", "session_token"], + "required": [ + "payment_id", + "session_token" + ], "properties": { "payment_id": { "type": "string", @@ -14745,7 +15872,11 @@ }, "PayoutAttemptResponse": { "type": "object", - "required": ["attempt_id", "status", "amount"], + "required": [ + "attempt_id", + "status", + "amount" + ], "properties": { "attempt_id": { "type": "string", @@ -14933,7 +16064,10 @@ "$ref": "#/components/schemas/PayoutConnectors" }, "description": "This field allows the merchant to manually select a connector with which the payout can go through.", - "example": ["wise", "adyen"], + "example": [ + "wise", + "adyen" + ], "nullable": true }, "confirm": { @@ -15373,7 +16507,10 @@ }, "PayoutLinkInitiateRequest": { "type": "object", - "required": ["merchant_id", "payout_id"], + "required": [ + "merchant_id", + "payout_id" + ], "properties": { "merchant_id": { "type": "string" @@ -15385,8 +16522,11 @@ }, "PayoutLinkResponse": { "type": "object", - "required": ["payout_link_id", "link"], - "properties": { + "required": [ + "payout_link_id", + "link" + ], + "properties": { "payout_link_id": { "type": "string" }, @@ -15457,7 +16597,10 @@ }, { "type": "object", - "required": ["currency", "entity_type"], + "required": [ + "currency", + "entity_type" + ], "properties": { "payout_id": { "type": "string", @@ -15497,7 +16640,10 @@ "$ref": "#/components/schemas/PayoutConnectors" }, "description": "The list of connectors to filter payouts list", - "example": ["wise", "adyen"], + "example": [ + "wise", + "adyen" + ], "nullable": true }, "currency": { @@ -15509,7 +16655,10 @@ "$ref": "#/components/schemas/PayoutStatus" }, "description": "The list of payout status to filter payouts list", - "example": ["pending", "failed"], + "example": [ + "pending", + "failed" + ], "nullable": true }, "payout_method": { @@ -15518,7 +16667,10 @@ "$ref": "#/components/schemas/PayoutType" }, "description": "The list of payout methods to filter payouts list", - "example": ["bank", "card"], + "example": [ + "bank", + "card" + ], "nullable": true }, "entity_type": { @@ -15530,7 +16682,10 @@ }, "PayoutListResponse": { "type": "object", - "required": ["size", "data"], + "required": [ + "size", + "data" + ], "properties": { "size": { "type": "integer", @@ -15556,7 +16711,9 @@ "oneOf": [ { "type": "object", - "required": ["card"], + "required": [ + "card" + ], "properties": { "card": { "$ref": "#/components/schemas/CardPayout" @@ -15565,7 +16722,9 @@ }, { "type": "object", - "required": ["bank"], + "required": [ + "bank" + ], "properties": { "bank": { "$ref": "#/components/schemas/Bank" @@ -15574,7 +16733,9 @@ }, { "type": "object", - "required": ["wallet"], + "required": [ + "wallet" + ], "properties": { "wallet": { "$ref": "#/components/schemas/Wallet" @@ -15588,7 +16749,9 @@ "oneOf": [ { "type": "object", - "required": ["card"], + "required": [ + "card" + ], "properties": { "card": { "$ref": "#/components/schemas/CardAdditionalData" @@ -15597,7 +16760,9 @@ }, { "type": "object", - "required": ["bank"], + "required": [ + "bank" + ], "properties": { "bank": { "$ref": "#/components/schemas/BankAdditionalData" @@ -15606,7 +16771,9 @@ }, { "type": "object", - "required": ["wallet"], + "required": [ + "wallet" + ], "properties": { "wallet": { "$ref": "#/components/schemas/WalletAdditionalData" @@ -15620,7 +16787,9 @@ "oneOf": [ { "type": "object", - "required": ["PayoutActionRequest"], + "required": [ + "PayoutActionRequest" + ], "properties": { "PayoutActionRequest": { "$ref": "#/components/schemas/PayoutActionRequest" @@ -15629,7 +16798,9 @@ }, { "type": "object", - "required": ["PayoutCreateRequest"], + "required": [ + "PayoutCreateRequest" + ], "properties": { "PayoutCreateRequest": { "$ref": "#/components/schemas/PayoutCreateRequest" @@ -15638,7 +16809,9 @@ }, { "type": "object", - "required": ["PayoutRetrieveRequest"], + "required": [ + "PayoutRetrieveRequest" + ], "properties": { "PayoutRetrieveRequest": { "$ref": "#/components/schemas/PayoutRetrieveRequest" @@ -15662,7 +16835,9 @@ }, "PayoutRetrieveRequest": { "type": "object", - "required": ["payout_id"], + "required": [ + "payout_id" + ], "properties": { "payout_id": { "type": "string", @@ -15718,11 +16893,19 @@ "PayoutType": { "type": "string", "description": "The payout_type of the payout request is a mandatory field for confirming the payouts. It should be specified in the Create request. If not provided, it must be updated in the Payout Update request before it can be confirmed.", - "enum": ["card", "bank", "wallet"] + "enum": [ + "card", + "bank", + "wallet" + ] }, "Paypal": { "type": "object", - "required": ["email", "telephone_number", "paypal_id"], + "required": [ + "email", + "telephone_number", + "paypal_id" + ], "properties": { "email": { "type": "string", @@ -15779,7 +16962,11 @@ }, "PaypalSessionTokenResponse": { "type": "object", - "required": ["connector", "session_token", "sdk_next_action"], + "required": [ + "connector", + "session_token", + "sdk_next_action" + ], "properties": { "connector": { "type": "string", @@ -15835,7 +17022,9 @@ }, "PazeWalletData": { "type": "object", - "required": ["complete_response"], + "required": [ + "complete_response" + ], "properties": { "complete_response": { "type": "string" @@ -15861,7 +17050,10 @@ }, "PixBankTransfer": { "type": "object", - "required": ["bank_account_number", "pix_key"], + "required": [ + "bank_account_number", + "pix_key" + ], "properties": { "bank_name": { "type": "string", @@ -15918,7 +17110,11 @@ }, "PollConfigResponse": { "type": "object", - "required": ["poll_id", "delay_in_secs", "frequency"], + "required": [ + "poll_id", + "delay_in_secs", + "frequency" + ], "properties": { "poll_id": { "type": "string", @@ -15938,7 +17134,10 @@ }, "PollResponse": { "type": "object", - "required": ["poll_id", "status"], + "required": [ + "poll_id", + "status" + ], "properties": { "poll_id": { "type": "string", @@ -15951,16 +17150,26 @@ }, "PollStatus": { "type": "string", - "enum": ["pending", "completed", "not_found"] + "enum": [ + "pending", + "completed", + "not_found" + ] }, "PresenceOfCustomerDuringPayment": { "type": "string", "description": "Set to true to indicate that the customer is in your checkout flow during this payment, and therefore is able to authenticate. This parameter should be false when merchant's doing merchant initiated payments and customer is not present while doing the payment.", - "enum": ["Present", "Absent"] + "enum": [ + "Present", + "Absent" + ] }, "PrimaryBusinessDetails": { "type": "object", - "required": ["country", "business"], + "required": [ + "country", + "business" + ], "properties": { "country": { "$ref": "#/components/schemas/CountryAlpha2" @@ -15975,7 +17184,9 @@ "ProcessorPaymentToken": { "type": "object", "description": "Processor payment token for MIT payments where payment_method_data is not available", - "required": ["processor_payment_token"], + "required": [ + "processor_payment_token" + ], "properties": { "processor_payment_token": { "type": "string" @@ -15999,7 +17210,9 @@ }, "ProfileCreate": { "type": "object", - "required": ["profile_name"], + "required": [ + "profile_name" + ], "properties": { "profile_name": { "type": "string", @@ -16162,7 +17375,10 @@ }, "ProfileDefaultRoutingConfig": { "type": "object", - "required": ["profile_id", "connectors"], + "required": [ + "profile_id", + "connectors" + ], "properties": { "profile_id": { "type": "string" @@ -16371,7 +17587,11 @@ "ProgramConnectorSelection": { "type": "object", "description": "The program, having a default connector selection and\na bunch of rules. Also can hold arbitrary metadata.", - "required": ["defaultSelection", "rules", "metadata"], + "required": [ + "defaultSelection", + "rules", + "metadata" + ], "properties": { "defaultSelection": { "$ref": "#/components/schemas/ConnectorSelection" @@ -16389,7 +17609,9 @@ "oneOf": [ { "type": "object", - "required": ["fps"], + "required": [ + "fps" + ], "properties": { "fps": { "type": "object" @@ -16398,7 +17620,9 @@ }, { "type": "object", - "required": ["duit_now"], + "required": [ + "duit_now" + ], "properties": { "duit_now": { "type": "object" @@ -16407,7 +17631,9 @@ }, { "type": "object", - "required": ["prompt_pay"], + "required": [ + "prompt_pay" + ], "properties": { "prompt_pay": { "type": "object" @@ -16416,7 +17642,9 @@ }, { "type": "object", - "required": ["viet_qr"], + "required": [ + "viet_qr" + ], "properties": { "viet_qr": { "type": "object" @@ -16442,7 +17670,9 @@ }, "ReceiverDetails": { "type": "object", - "required": ["amount_received"], + "required": [ + "amount_received" + ], "properties": { "amount_received": { "type": "integer", @@ -16465,17 +17695,27 @@ }, "ReconStatus": { "type": "string", - "enum": ["not_requested", "requested", "active", "disabled"] + "enum": [ + "not_requested", + "requested", + "active", + "disabled" + ] }, "RecurringDetails": { "oneOf": [ { "type": "object", - "required": ["type", "data"], + "required": [ + "type", + "data" + ], "properties": { "type": { "type": "string", - "enum": ["mandate_id"] + "enum": [ + "mandate_id" + ] }, "data": { "type": "string" @@ -16484,11 +17724,16 @@ }, { "type": "object", - "required": ["type", "data"], + "required": [ + "type", + "data" + ], "properties": { "type": { "type": "string", - "enum": ["payment_method_id"] + "enum": [ + "payment_method_id" + ] }, "data": { "type": "string" @@ -16497,11 +17742,16 @@ }, { "type": "object", - "required": ["type", "data"], + "required": [ + "type", + "data" + ], "properties": { "type": { "type": "string", - "enum": ["processor_payment_token"] + "enum": [ + "processor_payment_token" + ] }, "data": { "$ref": "#/components/schemas/ProcessorPaymentToken" @@ -16510,11 +17760,16 @@ }, { "type": "object", - "required": ["type", "data"], + "required": [ + "type", + "data" + ], "properties": { "type": { "type": "string", - "enum": ["network_transaction_id_and_card_details"] + "enum": [ + "network_transaction_id_and_card_details" + ] }, "data": { "$ref": "#/components/schemas/NetworkTransactionIdAndCardDetails" @@ -16542,7 +17797,10 @@ }, "RefundErrorDetails": { "type": "object", - "required": ["code", "message"], + "required": [ + "code", + "message" + ], "properties": { "code": { "type": "string" @@ -16638,7 +17896,11 @@ }, "RefundListResponse": { "type": "object", - "required": ["count", "total_count", "data"], + "required": [ + "count", + "total_count", + "data" + ], "properties": { "count": { "type": "integer", @@ -16661,7 +17923,9 @@ }, "RefundRequest": { "type": "object", - "required": ["payment_id"], + "required": [ + "payment_id" + ], "properties": { "payment_id": { "type": "string", @@ -16826,12 +18090,20 @@ "RefundStatus": { "type": "string", "description": "The status for refunds", - "enum": ["succeeded", "failed", "pending", "review"] + "enum": [ + "succeeded", + "failed", + "pending", + "review" + ] }, "RefundType": { "type": "string", "description": "To indicate whether to refund needs to be instant or scheduled", - "enum": ["scheduled", "instant"] + "enum": [ + "scheduled", + "instant" + ] }, "RefundUpdateRequest": { "type": "object", @@ -16853,7 +18125,9 @@ }, "RefundsCreateRequest": { "type": "object", - "required": ["payment_id"], + "required": [ + "payment_id" + ], "properties": { "payment_id": { "type": "string", @@ -16904,7 +18178,11 @@ }, "RequestIncrementalAuthorization": { "type": "string", - "enum": ["true", "false", "default"] + "enum": [ + "true", + "false", + "default" + ] }, "RequestPaymentMethodTypes": { "type": "object", @@ -16981,7 +18259,9 @@ "RequestSurchargeDetails": { "type": "object", "description": "Details of surcharge applied on this payment, if applicable", - "required": ["surcharge_amount"], + "required": [ + "surcharge_amount" + ], "properties": { "surcharge_amount": { "type": "integer", @@ -17001,7 +18281,11 @@ "RequiredFieldInfo": { "type": "object", "description": "Required fields info used while listing the payment_method_data", - "required": ["required_field", "display_name", "field_type"], + "required": [ + "required_field", + "display_name", + "field_type" + ], "properties": { "required_field": { "type": "string", @@ -17022,7 +18306,9 @@ }, "ResponsePaymentMethodTypes": { "type": "object", - "required": ["payment_method_subtype"], + "required": [ + "payment_method_subtype" + ], "properties": { "payment_method_subtype": { "$ref": "#/components/schemas/PaymentMethodType" @@ -17092,7 +18378,10 @@ }, "ResponsePaymentMethodsEnabled": { "type": "object", - "required": ["payment_method", "payment_method_types"], + "required": [ + "payment_method", + "payment_method_types" + ], "properties": { "payment_method": { "$ref": "#/components/schemas/PaymentMethod" @@ -17235,12 +18524,19 @@ "RetryAction": { "type": "string", "description": "Denotes the retry action", - "enum": ["manual_retry", "requeue"] + "enum": [ + "manual_retry", + "requeue" + ] }, "RevokeApiKeyResponse": { "type": "object", "description": "The response body for revoking an API Key.", - "required": ["merchant_id", "key_id", "revoked"], + "required": [ + "merchant_id", + "key_id", + "revoked" + ], "properties": { "merchant_id": { "type": "string", @@ -17263,7 +18559,9 @@ }, "RewardData": { "type": "object", - "required": ["merchant_id"], + "required": [ + "merchant_id" + ], "properties": { "merchant_id": { "type": "string", @@ -17273,12 +18571,17 @@ }, "RoutableChoiceKind": { "type": "string", - "enum": ["OnlyConnector", "FullStruct"] + "enum": [ + "OnlyConnector", + "FullStruct" + ] }, "RoutableConnectorChoice": { "type": "object", "description": "Routable Connector chosen for a payment", - "required": ["connector"], + "required": [ + "connector" + ], "properties": { "connector": { "$ref": "#/components/schemas/RoutableConnectors" @@ -17378,11 +18681,16 @@ "oneOf": [ { "type": "object", - "required": ["type", "data"], + "required": [ + "type", + "data" + ], "properties": { "type": { "type": "string", - "enum": ["single"] + "enum": [ + "single" + ] }, "data": { "$ref": "#/components/schemas/RoutableConnectorChoice" @@ -17391,11 +18699,16 @@ }, { "type": "object", - "required": ["type", "data"], + "required": [ + "type", + "data" + ], "properties": { "type": { "type": "string", - "enum": ["priority"] + "enum": [ + "priority" + ] }, "data": { "type": "array", @@ -17407,11 +18720,16 @@ }, { "type": "object", - "required": ["type", "data"], + "required": [ + "type", + "data" + ], "properties": { "type": { "type": "string", - "enum": ["volume_split"] + "enum": [ + "volume_split" + ] }, "data": { "type": "array", @@ -17423,11 +18741,16 @@ }, { "type": "object", - "required": ["type", "data"], + "required": [ + "type", + "data" + ], "properties": { "type": { "type": "string", - "enum": ["advanced"] + "enum": [ + "advanced" + ] }, "data": { "$ref": "#/components/schemas/ProgramConnectorSelection" @@ -17442,7 +18765,9 @@ }, "RoutingAlgorithmId": { "type": "object", - "required": ["routing_algorithm_id"], + "required": [ + "routing_algorithm_id" + ], "properties": { "routing_algorithm_id": { "type": "string" @@ -17451,11 +18776,22 @@ }, "RoutingAlgorithmKind": { "type": "string", - "enum": ["single", "priority", "volume_split", "advanced", "dynamic"] + "enum": [ + "single", + "priority", + "volume_split", + "advanced", + "dynamic" + ] }, "RoutingConfigRequest": { "type": "object", - "required": ["name", "description", "algorithm", "profile_id"], + "required": [ + "name", + "description", + "algorithm", + "profile_id" + ], "properties": { "name": { "type": "string" @@ -17473,7 +18809,10 @@ }, "RoutingDictionary": { "type": "object", - "required": ["merchant_id", "records"], + "required": [ + "merchant_id", + "records" + ], "properties": { "merchant_id": { "type": "string" @@ -17565,7 +18904,11 @@ "RuleConnectorSelection": { "type": "object", "description": "Represents a rule\n\n```text\nrule_name: [stripe, adyen, checkout]\n{\npayment.method = card {\npayment.method.cardtype = (credit, debit) {\npayment.method.network = (amex, rupay, diners)\n}\n\npayment.method.cardtype = credit\n}\n}\n```", - "required": ["name", "connectorSelection", "statements"], + "required": [ + "name", + "connectorSelection", + "statements" + ], "properties": { "name": { "type": "string" @@ -17583,7 +18926,11 @@ }, "SamsungPayAmountDetails": { "type": "object", - "required": ["option", "currency_code", "total"], + "required": [ + "option", + "currency_code", + "total" + ], "properties": { "option": { "$ref": "#/components/schemas/SamsungPayAmountFormat" @@ -17600,7 +18947,10 @@ }, "SamsungPayAmountFormat": { "type": "string", - "enum": ["FORMAT_TOTAL_PRICE_ONLY", "FORMAT_TOTAL_ESTIMATED_AMOUNT"] + "enum": [ + "FORMAT_TOTAL_PRICE_ONLY", + "FORMAT_TOTAL_ESTIMATED_AMOUNT" + ] }, "SamsungPayAppWalletData": { "type": "object", @@ -17649,11 +18999,20 @@ }, "SamsungPayCardBrand": { "type": "string", - "enum": ["visa", "mastercard", "amex", "discover", "unknown"] + "enum": [ + "visa", + "mastercard", + "amex", + "discover", + "unknown" + ] }, "SamsungPayMerchantPaymentInformation": { "type": "object", - "required": ["name", "country_code"], + "required": [ + "name", + "country_code" + ], "properties": { "name": { "type": "string", @@ -17671,7 +19030,9 @@ }, "SamsungPayProtocolType": { "type": "string", - "enum": ["PROTOCOL3DS"] + "enum": [ + "PROTOCOL3DS" + ] }, "SamsungPaySessionTokenResponse": { "type": "object", @@ -17717,7 +19078,10 @@ }, "SamsungPayTokenData": { "type": "object", - "required": ["version", "data"], + "required": [ + "version", + "data" + ], "properties": { "type": { "type": "string", @@ -17746,7 +19110,9 @@ }, "SamsungPayWalletData": { "type": "object", - "required": ["payment_credential"], + "required": [ + "payment_credential" + ], "properties": { "payment_credential": { "$ref": "#/components/schemas/SamsungPayWalletCredentials" @@ -17755,7 +19121,11 @@ }, "SamsungPayWebWalletData": { "type": "object", - "required": ["card_brand", "card_last4digits", "3_d_s"], + "required": [ + "card_brand", + "card_last4digits", + "3_d_s" + ], "properties": { "method": { "type": "string", @@ -17782,7 +19152,10 @@ "ScaExemptionType": { "type": "string", "description": "SCA Exemptions types available for authentication", - "enum": ["low_value", "transaction_risk_analysis"] + "enum": [ + "low_value", + "transaction_risk_analysis" + ] }, "SdkInformation": { "type": "object", @@ -17829,7 +19202,9 @@ }, "SdkNextAction": { "type": "object", - "required": ["next_action"], + "required": [ + "next_action" + ], "properties": { "next_action": { "$ref": "#/components/schemas/NextActionCall" @@ -17838,7 +19213,9 @@ }, "SdkNextActionData": { "type": "object", - "required": ["next_action"], + "required": [ + "next_action" + ], "properties": { "next_action": { "$ref": "#/components/schemas/NextActionCall" @@ -17851,7 +19228,10 @@ }, "SecretInfoToInitiateSdk": { "type": "object", - "required": ["display", "payment"], + "required": [ + "display", + "payment" + ], "properties": { "display": { "type": "string" @@ -17880,7 +19260,9 @@ }, "SepaBankDebitAdditionalData": { "type": "object", - "required": ["iban"], + "required": [ + "iban" + ], "properties": { "iban": { "type": "string", @@ -17897,7 +19279,10 @@ }, "SepaBankTransfer": { "type": "object", - "required": ["iban", "bic"], + "required": [ + "iban", + "bic" + ], "properties": { "bank_name": { "type": "string", @@ -17934,7 +19319,9 @@ "SepaBankTransferAdditionalData": { "type": "object", "description": "Masked payout method details for sepa bank transfer payout method", - "required": ["iban"], + "required": [ + "iban" + ], "properties": { "iban": { "type": "string", @@ -18009,11 +19396,15 @@ }, { "type": "object", - "required": ["wallet_name"], + "required": [ + "wallet_name" + ], "properties": { "wallet_name": { "type": "string", - "enum": ["google_pay"] + "enum": [ + "google_pay" + ] } } } @@ -18026,11 +19417,15 @@ }, { "type": "object", - "required": ["wallet_name"], + "required": [ + "wallet_name" + ], "properties": { "wallet_name": { "type": "string", - "enum": ["samsung_pay"] + "enum": [ + "samsung_pay" + ] } } } @@ -18043,11 +19438,15 @@ }, { "type": "object", - "required": ["wallet_name"], + "required": [ + "wallet_name" + ], "properties": { "wallet_name": { "type": "string", - "enum": ["klarna"] + "enum": [ + "klarna" + ] } } } @@ -18060,11 +19459,15 @@ }, { "type": "object", - "required": ["wallet_name"], + "required": [ + "wallet_name" + ], "properties": { "wallet_name": { "type": "string", - "enum": ["paypal"] + "enum": [ + "paypal" + ] } } } @@ -18077,11 +19480,15 @@ }, { "type": "object", - "required": ["wallet_name"], + "required": [ + "wallet_name" + ], "properties": { "wallet_name": { "type": "string", - "enum": ["apple_pay"] + "enum": [ + "apple_pay" + ] } } } @@ -18094,11 +19501,15 @@ }, { "type": "object", - "required": ["wallet_name"], + "required": [ + "wallet_name" + ], "properties": { "wallet_name": { "type": "string", - "enum": ["open_banking"] + "enum": [ + "open_banking" + ] } } } @@ -18111,11 +19522,15 @@ }, { "type": "object", - "required": ["wallet_name"], + "required": [ + "wallet_name" + ], "properties": { "wallet_name": { "type": "string", - "enum": ["paze"] + "enum": [ + "paze" + ] } } } @@ -18123,11 +19538,15 @@ }, { "type": "object", - "required": ["wallet_name"], + "required": [ + "wallet_name" + ], "properties": { "wallet_name": { "type": "string", - "enum": ["no_session_token_received"] + "enum": [ + "no_session_token_received" + ] } } } @@ -18192,11 +19611,16 @@ { "type": "object", "title": "Single", - "required": ["type", "data"], + "required": [ + "type", + "data" + ], "properties": { "type": { "type": "string", - "enum": ["single"] + "enum": [ + "single" + ] }, "data": { "$ref": "#/components/schemas/RoutableConnectorChoice" @@ -18206,11 +19630,16 @@ { "type": "object", "title": "Priority", - "required": ["type", "data"], + "required": [ + "type", + "data" + ], "properties": { "type": { "type": "string", - "enum": ["priority"] + "enum": [ + "priority" + ] }, "data": { "type": "array", @@ -18223,11 +19652,16 @@ { "type": "object", "title": "VolumeSplit", - "required": ["type", "data"], + "required": [ + "type", + "data" + ], "properties": { "type": { "type": "string", - "enum": ["volume_split"] + "enum": [ + "volume_split" + ] }, "data": { "type": "array", @@ -18244,11 +19678,17 @@ }, "StripeChargeType": { "type": "string", - "enum": ["direct", "destination"] + "enum": [ + "direct", + "destination" + ] }, "SurchargeCalculationOverride": { "type": "string", - "enum": ["skip", "calculate"] + "enum": [ + "skip", + "calculate" + ] }, "SurchargeDetailsResponse": { "type": "object", @@ -18289,7 +19729,9 @@ }, "SurchargePercentage": { "type": "object", - "required": ["percentage"], + "required": [ + "percentage" + ], "properties": { "percentage": { "type": "number", @@ -18301,11 +19743,16 @@ "oneOf": [ { "type": "object", - "required": ["type", "value"], + "required": [ + "type", + "value" + ], "properties": { "type": { "type": "string", - "enum": ["fixed"] + "enum": [ + "fixed" + ] }, "value": { "$ref": "#/components/schemas/MinorUnit" @@ -18314,11 +19761,16 @@ }, { "type": "object", - "required": ["type", "value"], + "required": [ + "type", + "value" + ], "properties": { "type": { "type": "string", - "enum": ["rate"] + "enum": [ + "rate" + ] }, "value": { "$ref": "#/components/schemas/SurchargePercentage" @@ -18335,11 +19787,16 @@ }, "TaxCalculationOverride": { "type": "string", - "enum": ["skip", "calculate"] + "enum": [ + "skip", + "calculate" + ] }, "ThirdPartySdkSessionResponse": { "type": "object", - "required": ["secrets"], + "required": [ + "secrets" + ], "properties": { "secrets": { "$ref": "#/components/schemas/SecretInfoToInitiateSdk" @@ -18348,7 +19805,11 @@ }, "ThreeDsCompletionIndicator": { "type": "string", - "enum": ["Y", "N", "U"] + "enum": [ + "Y", + "N", + "U" + ] }, "ThreeDsData": { "type": "object", @@ -18410,7 +19871,9 @@ }, "three_ds_method_key": { "type": "string", - "enum": ["threeDSMethodData"] + "enum": [ + "threeDSMethodData" + ] } } } @@ -18422,7 +19885,9 @@ "TimeRange": { "type": "object", "description": "A type representing a range of time for filtering, including a mandatory start time and an optional end time.", - "required": ["start_time"], + "required": [ + "start_time" + ], "properties": { "start_time": { "type": "string", @@ -18439,7 +19904,9 @@ }, "ToggleBlocklistResponse": { "type": "object", - "required": ["blocklist_guard_status"], + "required": [ + "blocklist_guard_status" + ], "properties": { "blocklist_guard_status": { "type": "string" @@ -18448,7 +19915,9 @@ }, "ToggleKVRequest": { "type": "object", - "required": ["kv_enabled"], + "required": [ + "kv_enabled" + ], "properties": { "kv_enabled": { "type": "boolean", @@ -18459,7 +19928,10 @@ }, "ToggleKVResponse": { "type": "object", - "required": ["merchant_id", "kv_enabled"], + "required": [ + "merchant_id", + "kv_enabled" + ], "properties": { "merchant_id": { "type": "string", @@ -18506,15 +19978,30 @@ "TransactionStatus": { "type": "string", "description": "Indicates the transaction status", - "enum": ["Y", "N", "U", "A", "R", "C", "D", "I"] + "enum": [ + "Y", + "N", + "U", + "A", + "R", + "C", + "D", + "I" + ] }, "TransactionType": { "type": "string", - "enum": ["payment", "payout"] + "enum": [ + "payment", + "payout" + ] }, "UIWidgetFormLayout": { "type": "string", - "enum": ["tabs", "journey"] + "enum": [ + "tabs", + "journey" + ] }, "UpdateApiKeyRequest": { "type": "object", @@ -18549,7 +20036,9 @@ "oneOf": [ { "type": "object", - "required": ["upi_collect"], + "required": [ + "upi_collect" + ], "properties": { "upi_collect": { "$ref": "#/components/schemas/UpiCollectAdditionalData" @@ -18558,7 +20047,9 @@ }, { "type": "object", - "required": ["upi_intent"], + "required": [ + "upi_intent" + ], "properties": { "upi_intent": { "$ref": "#/components/schemas/UpiIntentData" @@ -18592,7 +20083,9 @@ "oneOf": [ { "type": "object", - "required": ["upi_collect"], + "required": [ + "upi_collect" + ], "properties": { "upi_collect": { "$ref": "#/components/schemas/UpiCollectData" @@ -18601,7 +20094,9 @@ }, { "type": "object", - "required": ["upi_intent"], + "required": [ + "upi_intent" + ], "properties": { "upi_intent": { "$ref": "#/components/schemas/UpiIntentData" @@ -18632,11 +20127,16 @@ "oneOf": [ { "type": "object", - "required": ["type", "value"], + "required": [ + "type", + "value" + ], "properties": { "type": { "type": "string", - "enum": ["number"] + "enum": [ + "number" + ] }, "value": { "$ref": "#/components/schemas/MinorUnit" @@ -18645,11 +20145,16 @@ }, { "type": "object", - "required": ["type", "value"], + "required": [ + "type", + "value" + ], "properties": { "type": { "type": "string", - "enum": ["enum_variant"] + "enum": [ + "enum_variant" + ] }, "value": { "type": "string", @@ -18659,11 +20164,16 @@ }, { "type": "object", - "required": ["type", "value"], + "required": [ + "type", + "value" + ], "properties": { "type": { "type": "string", - "enum": ["metadata_variant"] + "enum": [ + "metadata_variant" + ] }, "value": { "$ref": "#/components/schemas/MetadataValue" @@ -18672,11 +20182,16 @@ }, { "type": "object", - "required": ["type", "value"], + "required": [ + "type", + "value" + ], "properties": { "type": { "type": "string", - "enum": ["str_value"] + "enum": [ + "str_value" + ] }, "value": { "type": "string", @@ -18686,11 +20201,16 @@ }, { "type": "object", - "required": ["type", "value"], + "required": [ + "type", + "value" + ], "properties": { "type": { "type": "string", - "enum": ["number_array"] + "enum": [ + "number_array" + ] }, "value": { "type": "array", @@ -18703,11 +20223,16 @@ }, { "type": "object", - "required": ["type", "value"], + "required": [ + "type", + "value" + ], "properties": { "type": { "type": "string", - "enum": ["enum_variant_array"] + "enum": [ + "enum_variant_array" + ] }, "value": { "type": "array", @@ -18720,11 +20245,16 @@ }, { "type": "object", - "required": ["type", "value"], + "required": [ + "type", + "value" + ], "properties": { "type": { "type": "string", - "enum": ["number_comparison_array"] + "enum": [ + "number_comparison_array" + ] }, "value": { "type": "array", @@ -18743,7 +20273,9 @@ }, "Venmo": { "type": "object", - "required": ["telephone_number"], + "required": [ + "telephone_number" + ], "properties": { "telephone_number": { "type": "string", @@ -18768,7 +20300,9 @@ "oneOf": [ { "type": "object", - "required": ["boleto"], + "required": [ + "boleto" + ], "properties": { "boleto": { "$ref": "#/components/schemas/BoletoVoucherData" @@ -18777,23 +20311,33 @@ }, { "type": "string", - "enum": ["efecty"] + "enum": [ + "efecty" + ] }, { "type": "string", - "enum": ["pago_efectivo"] + "enum": [ + "pago_efectivo" + ] }, { "type": "string", - "enum": ["red_compra"] + "enum": [ + "red_compra" + ] }, { "type": "string", - "enum": ["red_pagos"] + "enum": [ + "red_pagos" + ] }, { "type": "object", - "required": ["alfamart"], + "required": [ + "alfamart" + ], "properties": { "alfamart": { "$ref": "#/components/schemas/AlfamartVoucherData" @@ -18802,7 +20346,9 @@ }, { "type": "object", - "required": ["indomaret"], + "required": [ + "indomaret" + ], "properties": { "indomaret": { "$ref": "#/components/schemas/IndomaretVoucherData" @@ -18811,11 +20357,15 @@ }, { "type": "string", - "enum": ["oxxo"] + "enum": [ + "oxxo" + ] }, { "type": "object", - "required": ["seven_eleven"], + "required": [ + "seven_eleven" + ], "properties": { "seven_eleven": { "$ref": "#/components/schemas/JCSVoucherData" @@ -18824,7 +20374,9 @@ }, { "type": "object", - "required": ["lawson"], + "required": [ + "lawson" + ], "properties": { "lawson": { "$ref": "#/components/schemas/JCSVoucherData" @@ -18833,7 +20385,9 @@ }, { "type": "object", - "required": ["mini_stop"], + "required": [ + "mini_stop" + ], "properties": { "mini_stop": { "$ref": "#/components/schemas/JCSVoucherData" @@ -18842,7 +20396,9 @@ }, { "type": "object", - "required": ["family_mart"], + "required": [ + "family_mart" + ], "properties": { "family_mart": { "$ref": "#/components/schemas/JCSVoucherData" @@ -18851,7 +20407,9 @@ }, { "type": "object", - "required": ["seicomart"], + "required": [ + "seicomart" + ], "properties": { "seicomart": { "$ref": "#/components/schemas/JCSVoucherData" @@ -18860,7 +20418,9 @@ }, { "type": "object", - "required": ["pay_easy"], + "required": [ + "pay_easy" + ], "properties": { "pay_easy": { "$ref": "#/components/schemas/JCSVoucherData" @@ -18888,7 +20448,9 @@ "oneOf": [ { "type": "object", - "required": ["paypal"], + "required": [ + "paypal" + ], "properties": { "paypal": { "$ref": "#/components/schemas/Paypal" @@ -18897,7 +20459,9 @@ }, { "type": "object", - "required": ["venmo"], + "required": [ + "venmo" + ], "properties": { "venmo": { "$ref": "#/components/schemas/Venmo" @@ -18919,7 +20483,11 @@ }, "WalletAdditionalDataForCard": { "type": "object", - "required": ["last4", "card_network", "type"], + "required": [ + "last4", + "card_network", + "type" + ], "properties": { "last4": { "type": "string", @@ -18939,7 +20507,9 @@ "oneOf": [ { "type": "object", - "required": ["ali_pay_qr"], + "required": [ + "ali_pay_qr" + ], "properties": { "ali_pay_qr": { "$ref": "#/components/schemas/AliPayQr" @@ -18948,7 +20518,9 @@ }, { "type": "object", - "required": ["ali_pay_redirect"], + "required": [ + "ali_pay_redirect" + ], "properties": { "ali_pay_redirect": { "$ref": "#/components/schemas/AliPayRedirection" @@ -18957,7 +20529,9 @@ }, { "type": "object", - "required": ["ali_pay_hk_redirect"], + "required": [ + "ali_pay_hk_redirect" + ], "properties": { "ali_pay_hk_redirect": { "$ref": "#/components/schemas/AliPayHkRedirection" @@ -18966,7 +20540,9 @@ }, { "type": "object", - "required": ["momo_redirect"], + "required": [ + "momo_redirect" + ], "properties": { "momo_redirect": { "$ref": "#/components/schemas/MomoRedirection" @@ -18975,7 +20551,9 @@ }, { "type": "object", - "required": ["kakao_pay_redirect"], + "required": [ + "kakao_pay_redirect" + ], "properties": { "kakao_pay_redirect": { "$ref": "#/components/schemas/KakaoPayRedirection" @@ -18984,7 +20562,9 @@ }, { "type": "object", - "required": ["go_pay_redirect"], + "required": [ + "go_pay_redirect" + ], "properties": { "go_pay_redirect": { "$ref": "#/components/schemas/GoPayRedirection" @@ -18993,7 +20573,9 @@ }, { "type": "object", - "required": ["gcash_redirect"], + "required": [ + "gcash_redirect" + ], "properties": { "gcash_redirect": { "$ref": "#/components/schemas/GcashRedirection" @@ -19002,7 +20584,9 @@ }, { "type": "object", - "required": ["apple_pay"], + "required": [ + "apple_pay" + ], "properties": { "apple_pay": { "$ref": "#/components/schemas/ApplePayWalletData" @@ -19011,7 +20595,9 @@ }, { "type": "object", - "required": ["apple_pay_redirect"], + "required": [ + "apple_pay_redirect" + ], "properties": { "apple_pay_redirect": { "$ref": "#/components/schemas/ApplePayRedirectData" @@ -19020,7 +20606,9 @@ }, { "type": "object", - "required": ["apple_pay_third_party_sdk"], + "required": [ + "apple_pay_third_party_sdk" + ], "properties": { "apple_pay_third_party_sdk": { "$ref": "#/components/schemas/ApplePayThirdPartySdkData" @@ -19029,7 +20617,9 @@ }, { "type": "object", - "required": ["dana_redirect"], + "required": [ + "dana_redirect" + ], "properties": { "dana_redirect": { "type": "object", @@ -19039,7 +20629,9 @@ }, { "type": "object", - "required": ["google_pay"], + "required": [ + "google_pay" + ], "properties": { "google_pay": { "$ref": "#/components/schemas/GooglePayWalletData" @@ -19048,7 +20640,9 @@ }, { "type": "object", - "required": ["google_pay_redirect"], + "required": [ + "google_pay_redirect" + ], "properties": { "google_pay_redirect": { "$ref": "#/components/schemas/GooglePayRedirectData" @@ -19057,7 +20651,9 @@ }, { "type": "object", - "required": ["google_pay_third_party_sdk"], + "required": [ + "google_pay_third_party_sdk" + ], "properties": { "google_pay_third_party_sdk": { "$ref": "#/components/schemas/GooglePayThirdPartySdkData" @@ -19066,7 +20662,9 @@ }, { "type": "object", - "required": ["mb_way_redirect"], + "required": [ + "mb_way_redirect" + ], "properties": { "mb_way_redirect": { "$ref": "#/components/schemas/MbWayRedirection" @@ -19075,7 +20673,9 @@ }, { "type": "object", - "required": ["mobile_pay_redirect"], + "required": [ + "mobile_pay_redirect" + ], "properties": { "mobile_pay_redirect": { "$ref": "#/components/schemas/MobilePayRedirection" @@ -19084,7 +20684,9 @@ }, { "type": "object", - "required": ["paypal_redirect"], + "required": [ + "paypal_redirect" + ], "properties": { "paypal_redirect": { "$ref": "#/components/schemas/PaypalRedirection" @@ -19093,7 +20695,9 @@ }, { "type": "object", - "required": ["paypal_sdk"], + "required": [ + "paypal_sdk" + ], "properties": { "paypal_sdk": { "$ref": "#/components/schemas/PayPalWalletData" @@ -19102,7 +20706,9 @@ }, { "type": "object", - "required": ["paze"], + "required": [ + "paze" + ], "properties": { "paze": { "$ref": "#/components/schemas/PazeWalletData" @@ -19111,7 +20717,9 @@ }, { "type": "object", - "required": ["samsung_pay"], + "required": [ + "samsung_pay" + ], "properties": { "samsung_pay": { "$ref": "#/components/schemas/SamsungPayWalletData" @@ -19120,7 +20728,9 @@ }, { "type": "object", - "required": ["twint_redirect"], + "required": [ + "twint_redirect" + ], "properties": { "twint_redirect": { "type": "object", @@ -19130,7 +20740,9 @@ }, { "type": "object", - "required": ["vipps_redirect"], + "required": [ + "vipps_redirect" + ], "properties": { "vipps_redirect": { "type": "object", @@ -19140,7 +20752,9 @@ }, { "type": "object", - "required": ["touch_n_go_redirect"], + "required": [ + "touch_n_go_redirect" + ], "properties": { "touch_n_go_redirect": { "$ref": "#/components/schemas/TouchNGoRedirection" @@ -19149,7 +20763,9 @@ }, { "type": "object", - "required": ["we_chat_pay_redirect"], + "required": [ + "we_chat_pay_redirect" + ], "properties": { "we_chat_pay_redirect": { "$ref": "#/components/schemas/WeChatPayRedirection" @@ -19158,7 +20774,9 @@ }, { "type": "object", - "required": ["we_chat_pay_qr"], + "required": [ + "we_chat_pay_qr" + ], "properties": { "we_chat_pay_qr": { "$ref": "#/components/schemas/WeChatPayQr" @@ -19167,7 +20785,9 @@ }, { "type": "object", - "required": ["cashapp_qr"], + "required": [ + "cashapp_qr" + ], "properties": { "cashapp_qr": { "$ref": "#/components/schemas/CashappQr" @@ -19176,7 +20796,9 @@ }, { "type": "object", - "required": ["swish_qr"], + "required": [ + "swish_qr" + ], "properties": { "swish_qr": { "$ref": "#/components/schemas/SwishQrData" @@ -19185,7 +20807,9 @@ }, { "type": "object", - "required": ["mifinity"], + "required": [ + "mifinity" + ], "properties": { "mifinity": { "$ref": "#/components/schemas/MifinityData" @@ -19213,7 +20837,9 @@ "oneOf": [ { "type": "object", - "required": ["apple_pay"], + "required": [ + "apple_pay" + ], "properties": { "apple_pay": { "$ref": "#/components/schemas/WalletAdditionalDataForCard" @@ -19222,7 +20848,9 @@ }, { "type": "object", - "required": ["google_pay"], + "required": [ + "google_pay" + ], "properties": { "google_pay": { "$ref": "#/components/schemas/WalletAdditionalDataForCard" @@ -19243,7 +20871,11 @@ }, "WebhookDeliveryAttempt": { "type": "string", - "enum": ["initial_attempt", "automatic_retry", "manual_retry"] + "enum": [ + "initial_attempt", + "automatic_retry", + "manual_retry" + ] }, "WebhookDetails": { "type": "object", @@ -19382,4 +21014,4 @@ "description": "Manage events" } ] -} +} \ No newline at end of file From ed9d2b0f5007752bb074534d3208f2f61b30faf5 Mon Sep 17 00:00:00 2001 From: Narayan Bhat Date: Thu, 5 Dec 2024 11:56:48 +0530 Subject: [PATCH 08/12] chore: cargo clippy_v2 --- crates/router/src/core/payments.rs | 2 +- .../payments/operations/payment_capture_v2.rs | 43 ++++++++----------- 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs index eb7ab3d6c9ff..054f293460b9 100644 --- a/crates/router/src/core/payments.rs +++ b/crates/router/src/core/payments.rs @@ -7724,7 +7724,7 @@ impl OperationSessionGetters for PaymentCaptureData { todo!() } - fn get_billing_address(&self) -> Option { + fn get_billing_address(&self) -> Option { todo!() } diff --git a/crates/router/src/core/payments/operations/payment_capture_v2.rs b/crates/router/src/core/payments/operations/payment_capture_v2.rs index db414fe261bb..6a9e35c1bb50 100644 --- a/crates/router/src/core/payments/operations/payment_capture_v2.rs +++ b/crates/router/src/core/payments/operations/payment_capture_v2.rs @@ -8,22 +8,15 @@ use super::{Domain, GetTracker, Operation, UpdateTracker, ValidateRequest}; use crate::{ core::{ errors::{self, CustomResult, RouterResult, StorageErrorExt}, - payments::{ - self, helpers, - operations::{self, ValidateStatusForOperation}, - populate_surcharge_details, CustomerDetails, PaymentAddress, PaymentData, - }, - utils as core_utils, + payments::operations::{self, ValidateStatusForOperation}, }, routes::{app::ReqState, SessionState}, - services, types::{ - self, - api::{self, ConnectorCallType, PaymentIdTypeExt}, + api::{self, ConnectorCallType}, domain::{self}, storage::{self, enums as storage_enums}, }, - utils::{self, OptionExt}, + utils::OptionExt, }; #[derive(Debug, Clone, Copy)] @@ -148,7 +141,7 @@ impl GetTracker, PaymentsCaptureReques merchant_account: &domain::MerchantAccount, _profile: &domain::Profile, key_store: &domain::MerchantKeyStore, - header_payload: &hyperswitch_domain_models::payments::HeaderPayload, + _header_payload: &hyperswitch_domain_models::payments::HeaderPayload, ) -> RouterResult>> { let db = &*state.store; let key_manager_state = &state.into(); @@ -240,12 +233,12 @@ impl Domain> f #[instrument(skip_all)] async fn make_pm_data<'a>( &'a self, - state: &'a SessionState, - payment_data: &mut PaymentCaptureData, - storage_scheme: storage_enums::MerchantStorageScheme, - key_store: &domain::MerchantKeyStore, - customer: &Option, - business_profile: &domain::Profile, + _state: &'a SessionState, + _payment_data: &mut PaymentCaptureData, + _storage_scheme: storage_enums::MerchantStorageScheme, + _key_store: &domain::MerchantKeyStore, + _customer: &Option, + _business_profile: &domain::Profile, ) -> RouterResult<( BoxedConfirmOperation<'a, F>, Option, @@ -257,12 +250,12 @@ impl Domain> f #[instrument(skip_all)] async fn perform_routing<'a>( &'a self, - merchant_account: &domain::MerchantAccount, - business_profile: &domain::Profile, + _merchant_account: &domain::MerchantAccount, + _business_profile: &domain::Profile, state: &SessionState, // TODO: do not take the whole payment data here payment_data: &mut PaymentCaptureData, - mechant_key_store: &domain::MerchantKeyStore, + _mechant_key_store: &domain::MerchantKeyStore, ) -> CustomResult { let payment_attempt = &payment_data.payment_attempt; let connector = payment_attempt @@ -298,14 +291,14 @@ impl UpdateTracker, PaymentsCaptureRequest> f async fn update_trackers<'b>( &'b self, state: &'b SessionState, - req_state: ReqState, + _req_state: ReqState, mut payment_data: PaymentCaptureData, - customer: Option, + _customer: Option, storage_scheme: storage_enums::MerchantStorageScheme, - updated_customer: Option, + _updated_customer: Option, key_store: &domain::MerchantKeyStore, - frm_suggestion: Option, - header_payload: hyperswitch_domain_models::payments::HeaderPayload, + _frm_suggestion: Option, + _header_payload: hyperswitch_domain_models::payments::HeaderPayload, ) -> RouterResult<(BoxedConfirmOperation<'b, F>, PaymentCaptureData)> where F: 'b + Send, From 2ef4a383cecd653594de5206c2ccd5e84b0f8ed8 Mon Sep 17 00:00:00 2001 From: Narayan Bhat Date: Fri, 6 Dec 2024 15:59:52 +0530 Subject: [PATCH 09/12] chore: change field order in response --- crates/api_models/src/payments.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index 26040518b99d..3fddeb51770f 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -3932,12 +3932,12 @@ pub struct PaymentsCaptureResponse { /// The unique identifier for the payment pub id: id_type::GlobalPaymentId, - /// Amount details related to the payment - pub amount: PaymentAmountDetailsResponse, - /// Status of the payment #[schema(value_type = IntentStatus, example = "succeeded")] pub status: common_enums::IntentStatus, + + /// Amount details related to the payment + pub amount: PaymentAmountDetailsResponse, } #[derive(Default, Clone, Debug, Eq, PartialEq, serde::Serialize)] From 3e17fe2c2caa5240664d16d94c9bf3f1c11f4c15 Mon Sep 17 00:00:00 2001 From: Narayanbhat166 Date: Thu, 19 Dec 2024 01:10:13 +0530 Subject: [PATCH 10/12] chore: cargo clippy --- .../router/src/core/payments/operations/payment_capture_v2.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/router/src/core/payments/operations/payment_capture_v2.rs b/crates/router/src/core/payments/operations/payment_capture_v2.rs index 6a9e35c1bb50..0ee62ea73c1f 100644 --- a/crates/router/src/core/payments/operations/payment_capture_v2.rs +++ b/crates/router/src/core/payments/operations/payment_capture_v2.rs @@ -217,7 +217,7 @@ impl Domain> f .store .find_customer_by_global_id( &state.into(), - id.get_string_repr(), + &id, &payment_data.payment_intent.merchant_id, merchant_key_store, storage_scheme, From f1d2447e3518fa2bed66ea69e81ac81c24ad112a Mon Sep 17 00:00:00 2001 From: Narayanbhat166 Date: Thu, 19 Dec 2024 11:38:04 +0530 Subject: [PATCH 11/12] chore: fix typo --- crates/hyperswitch_domain_models/src/router_data.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/hyperswitch_domain_models/src/router_data.rs b/crates/hyperswitch_domain_models/src/router_data.rs index c0085bd61c75..f69c1db0e10b 100644 --- a/crates/hyperswitch_domain_models/src/router_data.rs +++ b/crates/hyperswitch_domain_models/src/router_data.rs @@ -567,7 +567,7 @@ impl &self, _payment_data: &payments::PaymentConfirmData, ) -> common_enums::AttemptStatus { - // For this step, consider whatever status was given by the connector moudle + // For this step, consider whatever status was given by the connector module // We do not need to check for amount captured or amount capturable here because we are authorizing the whole amount self.status } From 92f2034543ec0dbd83f2ff68f28212742a4229a4 Mon Sep 17 00:00:00 2001 From: Narayanbhat166 Date: Thu, 19 Dec 2024 15:24:49 +0530 Subject: [PATCH 12/12] chore: cargo clippy_v2 --- crates/router/src/core/payments/transformers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index 779b19db468e..dc9d2f977817 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -256,7 +256,7 @@ pub async fn construct_payment_router_data_for_authorize<'a>( .amount_details .get_net_amount() .get_amount_as_i64(), - minor_amount: payment_data.payment_attempt.amount_details.get_net_amount(),s + minor_amount: payment_data.payment_attempt.amount_details.get_net_amount(), order_tax_amount: None, currency: payment_data.payment_intent.amount_details.currency, browser_info: None,