Skip to content

Commit

Permalink
feat(router): add payments incremental authorization api (#3038)
Browse files Browse the repository at this point in the history
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
  • Loading branch information
1 parent 9274cef commit a0cfdd3
Show file tree
Hide file tree
Showing 60 changed files with 1,792 additions and 22 deletions.
13 changes: 11 additions & 2 deletions crates/api_models/src/events/payment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ use crate::{
payments::{
PaymentIdType, PaymentListConstraints, PaymentListFilterConstraints, PaymentListFilters,
PaymentListResponse, PaymentListResponseV2, PaymentsApproveRequest, PaymentsCancelRequest,
PaymentsCaptureRequest, PaymentsRejectRequest, PaymentsRequest, PaymentsResponse,
PaymentsRetrieveRequest, PaymentsStartRequest, RedirectionResponse,
PaymentsCaptureRequest, PaymentsIncrementalAuthorizationRequest, PaymentsRejectRequest,
PaymentsRequest, PaymentsResponse, PaymentsRetrieveRequest, PaymentsStartRequest,
RedirectionResponse,
},
};
impl ApiEventMetric for PaymentsRetrieveRequest {
Expand Down Expand Up @@ -149,3 +150,11 @@ impl ApiEventMetric for PaymentListResponseV2 {
}

impl ApiEventMetric for RedirectionResponse {}

impl ApiEventMetric for PaymentsIncrementalAuthorizationRequest {
fn get_api_event_type(&self) -> Option<ApiEventsType> {
Some(ApiEventsType::Payment {
payment_id: self.payment_id.clone(),
})
}
}
36 changes: 36 additions & 0 deletions crates/api_models/src/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2209,6 +2209,12 @@ pub struct PaymentsResponse {

/// If true incremental authorization can be performed on this payment
pub incremental_authorization_allowed: Option<bool>,

/// Total number of authorizations happened in an incremental_authorization payment
pub authorization_count: Option<i32>,

/// List of incremental authorizations happened to the payment
pub incremental_authorizations: Option<Vec<IncrementalAuthorizationResponse>>,
}

#[derive(Clone, Debug, serde::Deserialize, ToSchema, serde::Serialize)]
Expand Down Expand Up @@ -2277,6 +2283,24 @@ pub struct PaymentListResponse {
// The list of payments response objects
pub data: Vec<PaymentsResponse>,
}

#[derive(Setter, Clone, Default, Debug, PartialEq, serde::Serialize, ToSchema)]
pub struct IncrementalAuthorizationResponse {
/// The unique identifier of authorization
pub authorization_id: String,
/// Amount the authorization has been made for
pub amount: i64,
#[schema(value_type= AuthorizationStatus)]
/// The status of the authorization
pub status: common_enums::AuthorizationStatus,
/// Error code sent by the connector for authorization
pub error_code: Option<String>,
/// Error message sent by the connector for authorization
pub error_message: Option<String>,
/// Previously authorized amount for the payment
pub previously_authorized_amount: i64,
}

#[derive(Clone, Debug, serde::Serialize)]
pub struct PaymentListResponseV2 {
/// The number of payments included in the list for given constraints
Expand Down Expand Up @@ -2985,6 +3009,18 @@ pub struct PaymentsCancelRequest {
pub merchant_connector_details: Option<admin::MerchantConnectorDetailsWrap>,
}

#[derive(Default, Debug, serde::Serialize, serde::Deserialize, Clone, ToSchema)]
pub struct PaymentsIncrementalAuthorizationRequest {
/// The identifier for the payment
#[serde(skip)]
pub payment_id: String,
/// The total amount including previously authorized amount and additional amount
#[schema(value_type = i64, example = 6540)]
pub amount: i64,
/// Reason for incremental authorization
pub reason: Option<String>,
}

#[derive(Default, Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema)]
pub struct PaymentsApproveRequest {
/// The identifier for the payment
Expand Down
26 changes: 26 additions & 0 deletions crates/common_enums/src/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,32 @@ pub enum CaptureStatus {
Failed,
}

#[derive(
Default,
Clone,
Debug,
Eq,
PartialEq,
serde::Deserialize,
serde::Serialize,
strum::Display,
strum::EnumString,
ToSchema,
Hash,
)]
#[router_derive::diesel_enum(storage_type = "text")]
#[serde(rename_all = "snake_case")]
#[strum(serialize_all = "snake_case")]
pub enum AuthorizationStatus {
Success,
Failure,
// Processing state is before calling connector
#[default]
Processing,
// Requires merchant action
Unresolved,
}

#[derive(
Clone,
Copy,
Expand Down
1 change: 1 addition & 0 deletions crates/common_utils/src/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub enum Method {
Post,
Put,
Delete,
Patch,
}

#[derive(Deserialize, Serialize, Debug)]
Expand Down
1 change: 1 addition & 0 deletions crates/data_models/src/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,5 @@ pub struct PaymentIntent {
pub surcharge_applicable: Option<bool>,
pub request_incremental_authorization: storage_enums::RequestIncrementalAuthorization,
pub incremental_authorization_allowed: Option<bool>,
pub authorization_count: Option<i32>,
}
4 changes: 4 additions & 0 deletions crates/data_models/src/payments/payment_attempt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,10 @@ pub enum PaymentAttemptUpdate {
connector: Option<String>,
updated_by: String,
},
IncrementalAuthorizationAmountUpdate {
amount: i64,
amount_capturable: i64,
},
}

impl ForeignIDRef for PaymentAttempt {
Expand Down
18 changes: 18 additions & 0 deletions crates/data_models/src/payments/payment_intent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ pub struct PaymentIntentNew {
pub surcharge_applicable: Option<bool>,
pub request_incremental_authorization: storage_enums::RequestIncrementalAuthorization,
pub incremental_authorization_allowed: Option<bool>,
pub authorization_count: Option<i32>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down Expand Up @@ -186,6 +187,12 @@ pub enum PaymentIntentUpdate {
surcharge_applicable: bool,
updated_by: String,
},
IncrementalAuthorizationAmountUpdate {
amount: i64,
},
AuthorizationCountUpdate {
authorization_count: i32,
},
}

#[derive(Clone, Debug, Default)]
Expand Down Expand Up @@ -218,6 +225,7 @@ pub struct PaymentIntentUpdateInternal {
pub updated_by: String,
pub surcharge_applicable: Option<bool>,
pub incremental_authorization_allowed: Option<bool>,
pub authorization_count: Option<i32>,
}

impl From<PaymentIntentUpdate> for PaymentIntentUpdateInternal {
Expand Down Expand Up @@ -381,6 +389,16 @@ impl From<PaymentIntentUpdate> for PaymentIntentUpdateInternal {
updated_by,
..Default::default()
},
PaymentIntentUpdate::IncrementalAuthorizationAmountUpdate { amount } => Self {
amount: Some(amount),
..Default::default()
},
PaymentIntentUpdate::AuthorizationCountUpdate {
authorization_count,
} => Self {
authorization_count: Some(authorization_count),
..Default::default()
},
}
}
}
Expand Down
78 changes: 78 additions & 0 deletions crates/diesel_models/src/authorization.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
use diesel::{AsChangeset, Identifiable, Insertable, Queryable};
use serde::{Deserialize, Serialize};
use time::PrimitiveDateTime;

use crate::{enums as storage_enums, schema::incremental_authorization};

#[derive(Clone, Debug, Eq, PartialEq, Identifiable, Queryable, Serialize, Deserialize, Hash)]
#[diesel(table_name = incremental_authorization)]
#[diesel(primary_key(authorization_id, merchant_id))]
pub struct Authorization {
pub authorization_id: String,
pub merchant_id: String,
pub payment_id: String,
pub amount: i64,
#[serde(with = "common_utils::custom_serde::iso8601")]
pub created_at: PrimitiveDateTime,
#[serde(with = "common_utils::custom_serde::iso8601")]
pub modified_at: PrimitiveDateTime,
pub status: storage_enums::AuthorizationStatus,
pub error_code: Option<String>,
pub error_message: Option<String>,
pub connector_authorization_id: Option<String>,
pub previously_authorized_amount: i64,
}

#[derive(Clone, Debug, Insertable, router_derive::DebugAsDisplay, Serialize, Deserialize)]
#[diesel(table_name = incremental_authorization)]
pub struct AuthorizationNew {
pub authorization_id: String,
pub merchant_id: String,
pub payment_id: String,
pub amount: i64,
pub status: storage_enums::AuthorizationStatus,
pub error_code: Option<String>,
pub error_message: Option<String>,
pub connector_authorization_id: Option<String>,
pub previously_authorized_amount: i64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum AuthorizationUpdate {
StatusUpdate {
status: storage_enums::AuthorizationStatus,
error_code: Option<String>,
error_message: Option<String>,
connector_authorization_id: Option<String>,
},
}

#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)]
#[diesel(table_name = incremental_authorization)]
pub struct AuthorizationUpdateInternal {
pub status: Option<storage_enums::AuthorizationStatus>,
pub error_code: Option<String>,
pub error_message: Option<String>,
pub modified_at: Option<PrimitiveDateTime>,
pub connector_authorization_id: Option<String>,
}

impl From<AuthorizationUpdate> for AuthorizationUpdateInternal {
fn from(authorization_child_update: AuthorizationUpdate) -> Self {
let now = Some(common_utils::date_time::now());
match authorization_child_update {
AuthorizationUpdate::StatusUpdate {
status,
error_code,
error_message,
connector_authorization_id,
} => Self {
status: Some(status),
error_code,
error_message,
connector_authorization_id,
modified_at: now,
},
}
}
}
1 change: 1 addition & 0 deletions crates/diesel_models/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod capture;
pub mod cards_info;
pub mod configs;

pub mod authorization;
pub mod customers;
pub mod dispute;
pub mod encryption;
Expand Down
12 changes: 12 additions & 0 deletions crates/diesel_models/src/payment_attempt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,10 @@ pub enum PaymentAttemptUpdate {
connector: Option<String>,
updated_by: String,
},
IncrementalAuthorizationAmountUpdate {
amount: i64,
amount_capturable: i64,
},
}

#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)]
Expand Down Expand Up @@ -679,6 +683,14 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
updated_by,
..Default::default()
},
PaymentAttemptUpdate::IncrementalAuthorizationAmountUpdate {
amount,
amount_capturable,
} => Self {
amount: Some(amount),
amount_capturable: Some(amount_capturable),
..Default::default()
},
}
}
}
21 changes: 21 additions & 0 deletions crates/diesel_models/src/payment_intent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pub struct PaymentIntent {
pub surcharge_applicable: Option<bool>,
pub request_incremental_authorization: RequestIncrementalAuthorization,
pub incremental_authorization_allowed: Option<bool>,
pub authorization_count: Option<i32>,
}

#[derive(
Expand Down Expand Up @@ -110,6 +111,7 @@ pub struct PaymentIntentNew {
pub surcharge_applicable: Option<bool>,
pub request_incremental_authorization: RequestIncrementalAuthorization,
pub incremental_authorization_allowed: Option<bool>,
pub authorization_count: Option<i32>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand Down Expand Up @@ -187,6 +189,12 @@ pub enum PaymentIntentUpdate {
surcharge_applicable: Option<bool>,
updated_by: String,
},
IncrementalAuthorizationAmountUpdate {
amount: i64,
},
AuthorizationCountUpdate {
authorization_count: i32,
},
}

#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)]
Expand Down Expand Up @@ -220,6 +228,7 @@ pub struct PaymentIntentUpdateInternal {
pub updated_by: String,
pub surcharge_applicable: Option<bool>,
pub incremental_authorization_allowed: Option<bool>,
pub authorization_count: Option<i32>,
}

impl PaymentIntentUpdate {
Expand Down Expand Up @@ -251,6 +260,7 @@ impl PaymentIntentUpdate {
updated_by,
surcharge_applicable,
incremental_authorization_allowed,
authorization_count,
} = self.into();
PaymentIntent {
amount: amount.unwrap_or(source.amount),
Expand Down Expand Up @@ -282,6 +292,7 @@ impl PaymentIntentUpdate {
surcharge_applicable: surcharge_applicable.or(source.surcharge_applicable),

incremental_authorization_allowed,
authorization_count,
..source
}
}
Expand Down Expand Up @@ -448,6 +459,16 @@ impl From<PaymentIntentUpdate> for PaymentIntentUpdateInternal {
updated_by,
..Default::default()
},
PaymentIntentUpdate::IncrementalAuthorizationAmountUpdate { amount } => Self {
amount: Some(amount),
..Default::default()
},
PaymentIntentUpdate::AuthorizationCountUpdate {
authorization_count,
} => Self {
authorization_count: Some(authorization_count),
..Default::default()
},
}
}
}
1 change: 1 addition & 0 deletions crates/diesel_models/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod capture;
pub mod cards_info;
pub mod configs;

pub mod authorization;
pub mod customers;
pub mod dashboard_metadata;
pub mod dispute;
Expand Down
Loading

0 comments on commit a0cfdd3

Please sign in to comment.