mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 00:49:42 +08:00
feat(events): add extracted fields based on req/res types (#2795)
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1503,7 +1503,6 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
||||
name = "common_enums"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"common_utils",
|
||||
"diesel",
|
||||
"router_derive",
|
||||
"serde",
|
||||
@ -1519,6 +1518,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"common_enums",
|
||||
"diesel",
|
||||
"error-stack",
|
||||
"fake",
|
||||
|
||||
@ -893,6 +893,8 @@ pub struct ToggleKVResponse {
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||
pub struct ToggleKVRequest {
|
||||
#[serde(skip_deserializing)]
|
||||
pub merchant_id: String,
|
||||
/// Status of KV for the specific merchant
|
||||
#[schema(example = true)]
|
||||
pub kv_enabled: bool,
|
||||
|
||||
@ -129,6 +129,12 @@ pub struct UpdateApiKeyRequest {
|
||||
/// rotating your keys once every 6 months.
|
||||
#[schema(example = "2022-09-10T10:11:12Z")]
|
||||
pub expiration: Option<ApiKeyExpiration>,
|
||||
|
||||
#[serde(skip_deserializing)]
|
||||
pub key_id: String,
|
||||
|
||||
#[serde(skip_deserializing)]
|
||||
pub merchant_id: String,
|
||||
}
|
||||
|
||||
/// The response body for revoking an API Key.
|
||||
|
||||
74
crates/api_models/src/events.rs
Normal file
74
crates/api_models/src/events.rs
Normal file
@ -0,0 +1,74 @@
|
||||
pub mod customer;
|
||||
pub mod payment;
|
||||
#[cfg(feature = "payouts")]
|
||||
pub mod payouts;
|
||||
pub mod refund;
|
||||
pub mod routing;
|
||||
|
||||
use common_utils::{
|
||||
events::{ApiEventMetric, ApiEventsType},
|
||||
impl_misc_api_event_type,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
admin::*, api_keys::*, cards_info::*, disputes::*, files::*, mandates::*, payment_methods::*,
|
||||
payments::*, verifications::*,
|
||||
};
|
||||
|
||||
impl ApiEventMetric for TimeRange {}
|
||||
|
||||
impl_misc_api_event_type!(
|
||||
PaymentMethodId,
|
||||
PaymentsSessionResponse,
|
||||
PaymentMethodListResponse,
|
||||
PaymentMethodCreate,
|
||||
PaymentLinkInitiateRequest,
|
||||
RetrievePaymentLinkResponse,
|
||||
MandateListConstraints,
|
||||
CreateFileResponse,
|
||||
DisputeResponse,
|
||||
SubmitEvidenceRequest,
|
||||
MerchantConnectorResponse,
|
||||
MerchantConnectorId,
|
||||
MandateResponse,
|
||||
MandateRevokedResponse,
|
||||
RetrievePaymentLinkRequest,
|
||||
MandateId,
|
||||
DisputeListConstraints,
|
||||
RetrieveApiKeyResponse,
|
||||
BusinessProfileResponse,
|
||||
BusinessProfileUpdate,
|
||||
BusinessProfileCreate,
|
||||
RevokeApiKeyResponse,
|
||||
ToggleKVResponse,
|
||||
ToggleKVRequest,
|
||||
MerchantAccountDeleteResponse,
|
||||
MerchantAccountUpdate,
|
||||
CardInfoResponse,
|
||||
CreateApiKeyResponse,
|
||||
CreateApiKeyRequest,
|
||||
MerchantConnectorDeleteResponse,
|
||||
MerchantConnectorUpdate,
|
||||
MerchantConnectorCreate,
|
||||
MerchantId,
|
||||
CardsInfoRequest,
|
||||
MerchantAccountResponse,
|
||||
MerchantAccountListRequest,
|
||||
MerchantAccountCreate,
|
||||
PaymentsSessionRequest,
|
||||
ApplepayMerchantVerificationRequest,
|
||||
ApplepayMerchantResponse,
|
||||
ApplepayVerifiedDomainsResponse,
|
||||
UpdateApiKeyRequest
|
||||
);
|
||||
|
||||
#[cfg(feature = "stripe")]
|
||||
impl_misc_api_event_type!(
|
||||
StripeSetupIntentResponse,
|
||||
StripeRefundResponse,
|
||||
StripePaymentIntentListResponse,
|
||||
StripePaymentIntentResponse,
|
||||
CustomerDeleteResponse,
|
||||
CustomerPaymentMethodListResponse,
|
||||
CreateCustomerResponse
|
||||
);
|
||||
35
crates/api_models/src/events/customer.rs
Normal file
35
crates/api_models/src/events/customer.rs
Normal file
@ -0,0 +1,35 @@
|
||||
use common_utils::events::{ApiEventMetric, ApiEventsType};
|
||||
|
||||
use crate::customers::{CustomerDeleteResponse, CustomerId, CustomerRequest, CustomerResponse};
|
||||
|
||||
impl ApiEventMetric for CustomerDeleteResponse {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Customer {
|
||||
customer_id: self.customer_id.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for CustomerRequest {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Customer {
|
||||
customer_id: self.customer_id.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for CustomerResponse {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Customer {
|
||||
customer_id: self.customer_id.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for CustomerId {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Customer {
|
||||
customer_id: self.customer_id.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
151
crates/api_models/src/events/payment.rs
Normal file
151
crates/api_models/src/events/payment.rs
Normal file
@ -0,0 +1,151 @@
|
||||
use common_utils::events::{ApiEventMetric, ApiEventsType};
|
||||
|
||||
use crate::{
|
||||
payment_methods::{
|
||||
CustomerPaymentMethodsListResponse, PaymentMethodDeleteResponse, PaymentMethodListRequest,
|
||||
PaymentMethodResponse, PaymentMethodUpdate,
|
||||
},
|
||||
payments::{
|
||||
PaymentIdType, PaymentListConstraints, PaymentListFilterConstraints, PaymentListFilters,
|
||||
PaymentListResponse, PaymentListResponseV2, PaymentsApproveRequest, PaymentsCancelRequest,
|
||||
PaymentsCaptureRequest, PaymentsRejectRequest, PaymentsRequest, PaymentsResponse,
|
||||
PaymentsRetrieveRequest, PaymentsStartRequest, RedirectionResponse,
|
||||
},
|
||||
};
|
||||
impl ApiEventMetric for PaymentsRetrieveRequest {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
match self.resource_id {
|
||||
PaymentIdType::PaymentIntentId(ref id) => Some(ApiEventsType::Payment {
|
||||
payment_id: id.clone(),
|
||||
}),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for PaymentsStartRequest {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Payment {
|
||||
payment_id: self.payment_id.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for PaymentsCaptureRequest {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Payment {
|
||||
payment_id: self.payment_id.to_owned(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for PaymentsCancelRequest {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Payment {
|
||||
payment_id: self.payment_id.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for PaymentsApproveRequest {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Payment {
|
||||
payment_id: self.payment_id.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for PaymentsRejectRequest {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Payment {
|
||||
payment_id: self.payment_id.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for PaymentsRequest {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
match self.payment_id {
|
||||
Some(PaymentIdType::PaymentIntentId(ref id)) => Some(ApiEventsType::Payment {
|
||||
payment_id: id.clone(),
|
||||
}),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for PaymentsResponse {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
self.payment_id
|
||||
.clone()
|
||||
.map(|payment_id| ApiEventsType::Payment { payment_id })
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for PaymentMethodResponse {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::PaymentMethod {
|
||||
payment_method_id: self.payment_method_id.clone(),
|
||||
payment_method: Some(self.payment_method),
|
||||
payment_method_type: self.payment_method_type,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for PaymentMethodUpdate {}
|
||||
|
||||
impl ApiEventMetric for PaymentMethodDeleteResponse {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::PaymentMethod {
|
||||
payment_method_id: self.payment_method_id.clone(),
|
||||
payment_method: None,
|
||||
payment_method_type: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for CustomerPaymentMethodsListResponse {}
|
||||
|
||||
impl ApiEventMetric for PaymentMethodListRequest {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::PaymentMethodList {
|
||||
payment_id: self
|
||||
.client_secret
|
||||
.as_ref()
|
||||
.and_then(|cs| cs.rsplit_once("_secret_"))
|
||||
.map(|(pid, _)| pid.to_string()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for PaymentListFilterConstraints {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::ResourceListAPI)
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for PaymentListFilters {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::ResourceListAPI)
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for PaymentListConstraints {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::ResourceListAPI)
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for PaymentListResponse {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::ResourceListAPI)
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for PaymentListResponseV2 {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::ResourceListAPI)
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for RedirectionResponse {}
|
||||
29
crates/api_models/src/events/payouts.rs
Normal file
29
crates/api_models/src/events/payouts.rs
Normal file
@ -0,0 +1,29 @@
|
||||
use common_utils::events::{ApiEventMetric, ApiEventsType};
|
||||
|
||||
use crate::payouts::{
|
||||
PayoutActionRequest, PayoutCreateRequest, PayoutCreateResponse, PayoutRetrieveRequest,
|
||||
};
|
||||
|
||||
impl ApiEventMetric for PayoutRetrieveRequest {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Payout)
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for PayoutCreateRequest {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Payout)
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for PayoutCreateResponse {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Payout)
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for PayoutActionRequest {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Payout)
|
||||
}
|
||||
}
|
||||
63
crates/api_models/src/events/refund.rs
Normal file
63
crates/api_models/src/events/refund.rs
Normal file
@ -0,0 +1,63 @@
|
||||
use common_utils::events::{ApiEventMetric, ApiEventsType};
|
||||
|
||||
use crate::refunds::{
|
||||
RefundListMetaData, RefundListRequest, RefundListResponse, RefundRequest, RefundResponse,
|
||||
RefundUpdateRequest, RefundsRetrieveRequest,
|
||||
};
|
||||
|
||||
impl ApiEventMetric for RefundRequest {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
let payment_id = self.payment_id.clone();
|
||||
self.refund_id
|
||||
.clone()
|
||||
.map(|refund_id| ApiEventsType::Refund {
|
||||
payment_id: Some(payment_id),
|
||||
refund_id,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for RefundResponse {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Refund {
|
||||
payment_id: Some(self.payment_id.clone()),
|
||||
refund_id: self.refund_id.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for RefundsRetrieveRequest {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Refund {
|
||||
payment_id: None,
|
||||
refund_id: self.refund_id.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for RefundUpdateRequest {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Refund {
|
||||
payment_id: None,
|
||||
refund_id: self.refund_id.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for RefundListRequest {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::ResourceListAPI)
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for RefundListResponse {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::ResourceListAPI)
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for RefundListMetaData {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::ResourceListAPI)
|
||||
}
|
||||
}
|
||||
58
crates/api_models/src/events/routing.rs
Normal file
58
crates/api_models/src/events/routing.rs
Normal file
@ -0,0 +1,58 @@
|
||||
use common_utils::events::{ApiEventMetric, ApiEventsType};
|
||||
|
||||
use crate::routing::{
|
||||
LinkedRoutingConfigRetrieveResponse, MerchantRoutingAlgorithm, RoutingAlgorithmId,
|
||||
RoutingConfigRequest, RoutingDictionaryRecord, RoutingKind,
|
||||
};
|
||||
#[cfg(feature = "business_profile_routing")]
|
||||
use crate::routing::{RoutingRetrieveLinkQuery, RoutingRetrieveQuery};
|
||||
|
||||
impl ApiEventMetric for RoutingKind {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Routing)
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for MerchantRoutingAlgorithm {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Routing)
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for RoutingAlgorithmId {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Routing)
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for RoutingDictionaryRecord {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Routing)
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for LinkedRoutingConfigRetrieveResponse {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Routing)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "business_profile_routing")]
|
||||
impl ApiEventMetric for RoutingRetrieveQuery {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Routing)
|
||||
}
|
||||
}
|
||||
|
||||
impl ApiEventMetric for RoutingConfigRequest {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Routing)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "business_profile_routing")]
|
||||
impl ApiEventMetric for RoutingRetrieveLinkQuery {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Routing)
|
||||
}
|
||||
}
|
||||
@ -9,6 +9,7 @@ pub mod enums;
|
||||
pub mod ephemeral_key;
|
||||
#[cfg(feature = "errors")]
|
||||
pub mod errors;
|
||||
pub mod events;
|
||||
pub mod files;
|
||||
pub mod mandates;
|
||||
pub mod organization;
|
||||
|
||||
@ -12,7 +12,9 @@ use utoipa::ToSchema;
|
||||
#[cfg(feature = "payouts")]
|
||||
use crate::payouts;
|
||||
use crate::{
|
||||
admin, enums as api_enums,
|
||||
admin,
|
||||
customers::CustomerId,
|
||||
enums as api_enums,
|
||||
payments::{self, BankCodeResponse},
|
||||
};
|
||||
|
||||
@ -476,6 +478,8 @@ pub struct RequestPaymentMethodTypes {
|
||||
#[derive(Debug, Clone, serde::Serialize, Default, ToSchema)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct PaymentMethodListRequest {
|
||||
#[serde(skip_deserializing)]
|
||||
pub customer_id: Option<CustomerId>,
|
||||
/// This is a 15 minute expiry token which shall be used from the client to authenticate and perform sessions from the SDK
|
||||
#[schema(max_length = 30, min_length = 30, example = "secret_k2uj3he2893ein2d")]
|
||||
pub client_secret: Option<String>,
|
||||
|
||||
@ -2232,7 +2232,9 @@ pub struct PaymentListFilters {
|
||||
pub authentication_type: Vec<enums::AuthenticationType>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize, PartialEq, Eq, Hash)]
|
||||
#[derive(
|
||||
Debug, Clone, Copy, serde::Serialize, serde::Deserialize, PartialEq, Eq, Hash, ToSchema,
|
||||
)]
|
||||
pub struct TimeRange {
|
||||
/// The start time to filter payments list or to get list of filters. To get list of filters start time is needed to be passed
|
||||
#[serde(with = "common_utils::custom_serde::iso8601")]
|
||||
|
||||
@ -3,6 +3,7 @@ use serde::{Deserialize, Serialize};
|
||||
use time::PrimitiveDateTime;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
use super::payments::TimeRange;
|
||||
use crate::{admin, enums};
|
||||
|
||||
#[derive(Default, Debug, ToSchema, Clone, Deserialize, Serialize)]
|
||||
@ -75,6 +76,8 @@ pub struct RefundsRetrieveRequest {
|
||||
#[derive(Default, Debug, ToSchema, Clone, Deserialize, Serialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct RefundUpdateRequest {
|
||||
#[serde(skip)]
|
||||
pub refund_id: String,
|
||||
/// An arbitrary string attached to the object. Often useful for displaying to users and your customer support executive
|
||||
#[schema(max_length = 255, example = "Customer returned the product")]
|
||||
pub reason: Option<String>,
|
||||
@ -152,16 +155,6 @@ pub struct RefundListRequest {
|
||||
pub refund_status: Option<Vec<enums::RefundStatus>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash, ToSchema)]
|
||||
pub struct TimeRange {
|
||||
/// The start time to filter refunds list or to get list of filters. To get list of filters start time is needed to be passed
|
||||
#[serde(with = "common_utils::custom_serde::iso8601")]
|
||||
pub start_time: PrimitiveDateTime,
|
||||
/// The end time to filter refunds list or to get list of filters. If not passed the default time is now
|
||||
#[serde(default, with = "common_utils::custom_serde::iso8601::option")]
|
||||
pub end_time: Option<PrimitiveDateTime>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize, ToSchema)]
|
||||
pub struct RefundListResponse {
|
||||
/// The number of refunds included in the list
|
||||
|
||||
@ -592,3 +592,8 @@ pub enum RoutingKind {
|
||||
Config(RoutingDictionary),
|
||||
RoutingAlgorithm(Vec<RoutingDictionaryRecord>),
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug)]
|
||||
#[serde(transparent)]
|
||||
pub struct RoutingAlgorithmId(pub String);
|
||||
|
||||
@ -19,7 +19,6 @@ time = { version = "0.3.21", features = ["serde", "serde-well-known", "std"] }
|
||||
utoipa = { version = "3.3.0", features = ["preserve_order"] }
|
||||
|
||||
# First party crates
|
||||
common_utils = { version = "0.1.0", path = "../common_utils" }
|
||||
router_derive = { version = "0.1.0", path = "../router_derive" }
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
@ -42,6 +42,7 @@ phonenumber = "0.3.3"
|
||||
# First party crates
|
||||
masking = { version = "0.1.0", path = "../masking" }
|
||||
router_env = { version = "0.1.0", path = "../router_env", features = ["log_extra_implicit_fields", "log_custom_entries_to_extra"], optional = true }
|
||||
common_enums = { version = "0.1.0", path = "../common_enums" }
|
||||
|
||||
[target.'cfg(not(target_os = "windows"))'.dependencies]
|
||||
signal-hook-tokio = { version = "0.3.1", features = ["futures-v0_3"], optional = true }
|
||||
|
||||
91
crates/common_utils/src/events.rs
Normal file
91
crates/common_utils/src/events.rs
Normal file
@ -0,0 +1,91 @@
|
||||
use common_enums::{PaymentMethod, PaymentMethodType};
|
||||
use serde::Serialize;
|
||||
|
||||
pub trait ApiEventMetric {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
#[serde(tag = "flow_type")]
|
||||
pub enum ApiEventsType {
|
||||
Payout,
|
||||
Payment {
|
||||
payment_id: String,
|
||||
},
|
||||
Refund {
|
||||
payment_id: Option<String>,
|
||||
refund_id: String,
|
||||
},
|
||||
PaymentMethod {
|
||||
payment_method_id: String,
|
||||
payment_method: Option<PaymentMethod>,
|
||||
payment_method_type: Option<PaymentMethodType>,
|
||||
},
|
||||
Customer {
|
||||
customer_id: String,
|
||||
},
|
||||
User {
|
||||
//specified merchant_id will overridden on global defined
|
||||
merchant_id: String,
|
||||
user_id: String,
|
||||
},
|
||||
PaymentMethodList {
|
||||
payment_id: Option<String>,
|
||||
},
|
||||
Webhooks {
|
||||
connector: String,
|
||||
payment_id: Option<String>,
|
||||
},
|
||||
Routing,
|
||||
ResourceListAPI,
|
||||
PaymentRedirectionResponse,
|
||||
// TODO: This has to be removed once the corresponding apiEventTypes are created
|
||||
Miscellaneous,
|
||||
}
|
||||
|
||||
impl ApiEventMetric for serde_json::Value {}
|
||||
impl ApiEventMetric for () {}
|
||||
|
||||
impl<Q: ApiEventMetric, E> ApiEventMetric for Result<Q, E> {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
match self {
|
||||
Ok(q) => q.get_api_event_type(),
|
||||
Err(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Ideally all these types should be replaced by newtype responses
|
||||
impl<T> ApiEventMetric for Vec<T> {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Miscellaneous)
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_misc_api_event_type {
|
||||
($($type:ty),+) => {
|
||||
$(
|
||||
impl ApiEventMetric for $type {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
Some(ApiEventsType::Miscellaneous)
|
||||
}
|
||||
}
|
||||
)+
|
||||
};
|
||||
}
|
||||
|
||||
impl_misc_api_event_type!(
|
||||
String,
|
||||
(&String, &String),
|
||||
(Option<i64>, Option<i64>, String),
|
||||
bool
|
||||
);
|
||||
|
||||
impl<T: ApiEventMetric> ApiEventMetric for &T {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
T::get_api_event_type(self)
|
||||
}
|
||||
}
|
||||
@ -6,6 +6,8 @@ pub mod consts;
|
||||
pub mod crypto;
|
||||
pub mod custom_serde;
|
||||
pub mod errors;
|
||||
#[allow(missing_docs)] // Todo: add docs
|
||||
pub mod events;
|
||||
pub mod ext_traits;
|
||||
pub mod fp_utils;
|
||||
pub mod pii;
|
||||
|
||||
@ -14,3 +14,9 @@ pub struct EphemeralKey {
|
||||
pub expires: i64,
|
||||
pub secret: String,
|
||||
}
|
||||
|
||||
impl common_utils::events::ApiEventMetric for EphemeralKey {
|
||||
fn get_api_event_type(&self) -> Option<common_utils::events::ApiEventsType> {
|
||||
Some(common_utils::events::ApiEventsType::Miscellaneous)
|
||||
}
|
||||
}
|
||||
|
||||
@ -227,3 +227,12 @@ pub struct RefundCoreWorkflow {
|
||||
pub merchant_id: String,
|
||||
pub payment_id: String,
|
||||
}
|
||||
|
||||
impl common_utils::events::ApiEventMetric for Refund {
|
||||
fn get_api_event_type(&self) -> Option<common_utils::events::ApiEventsType> {
|
||||
Some(common_utils::events::ApiEventsType::Refund {
|
||||
payment_id: Some(self.payment_id.clone()),
|
||||
refund_id: self.refund_id.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,8 +149,8 @@ pub async fn refund_update(
|
||||
path: web::Path<String>,
|
||||
form_payload: web::Form<types::StripeUpdateRefundRequest>,
|
||||
) -> HttpResponse {
|
||||
let refund_id = path.into_inner();
|
||||
let payload = form_payload.into_inner();
|
||||
let mut payload = form_payload.into_inner();
|
||||
payload.refund_id = path.into_inner();
|
||||
let create_refund_update_req: refund_types::RefundUpdateRequest = payload.into();
|
||||
let flow = Flow::RefundsUpdate;
|
||||
|
||||
@ -169,9 +169,7 @@ pub async fn refund_update(
|
||||
state.into_inner(),
|
||||
&req,
|
||||
create_refund_update_req,
|
||||
|state, auth, req| {
|
||||
refunds::refund_update_core(state, auth.merchant_account, &refund_id, req)
|
||||
},
|
||||
|state, auth, req| refunds::refund_update_core(state, auth.merchant_account, req),
|
||||
&auth::ApiKeyAuth,
|
||||
api_locking::LockAction::NotApplicable,
|
||||
))
|
||||
|
||||
@ -17,6 +17,8 @@ pub struct StripeCreateRefundRequest {
|
||||
|
||||
#[derive(Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct StripeUpdateRefundRequest {
|
||||
#[serde(skip)]
|
||||
pub refund_id: String,
|
||||
pub metadata: Option<pii::SecretSerdeValue>,
|
||||
}
|
||||
|
||||
@ -58,6 +60,7 @@ impl From<StripeCreateRefundRequest> for refunds::RefundRequest {
|
||||
impl From<StripeUpdateRefundRequest> for refunds::RefundUpdateRequest {
|
||||
fn from(req: StripeUpdateRefundRequest) -> Self {
|
||||
Self {
|
||||
refund_id: req.refund_id,
|
||||
metadata: req.metadata,
|
||||
reason: None,
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ use serde::Serialize;
|
||||
|
||||
use crate::{
|
||||
core::{api_locking, errors},
|
||||
events::api_logs::ApiEventMetric,
|
||||
routes::{app::AppStateInfo, metrics},
|
||||
services::{self, api, authentication as auth, logger},
|
||||
};
|
||||
@ -25,12 +26,12 @@ where
|
||||
F: Fn(A, U, T) -> Fut,
|
||||
Fut: Future<Output = CustomResult<api::ApplicationResponse<Q>, E2>>,
|
||||
E2: ErrorSwitch<E> + std::error::Error + Send + Sync + 'static,
|
||||
Q: Serialize + std::fmt::Debug + 'a,
|
||||
Q: Serialize + std::fmt::Debug + 'a + ApiEventMetric,
|
||||
S: TryFrom<Q> + Serialize,
|
||||
E: Serialize + error_stack::Context + actix_web::ResponseError + Clone,
|
||||
error_stack::Report<E>: services::EmbedError,
|
||||
errors::ApiErrorResponse: ErrorSwitch<E>,
|
||||
T: std::fmt::Debug + Serialize,
|
||||
T: std::fmt::Debug + Serialize + ApiEventMetric,
|
||||
A: AppStateInfo + Clone,
|
||||
{
|
||||
let request_method = request.method().as_str();
|
||||
|
||||
@ -294,10 +294,10 @@ pub async fn retrieve_api_key(
|
||||
#[instrument(skip_all)]
|
||||
pub async fn update_api_key(
|
||||
state: AppState,
|
||||
merchant_id: &str,
|
||||
key_id: &str,
|
||||
api_key: api::UpdateApiKeyRequest,
|
||||
) -> RouterResponse<api::RetrieveApiKeyResponse> {
|
||||
let merchant_id = api_key.merchant_id.clone();
|
||||
let key_id = api_key.key_id.clone();
|
||||
let store = state.store.as_ref();
|
||||
|
||||
let api_key = store
|
||||
@ -313,7 +313,7 @@ pub async fn update_api_key(
|
||||
{
|
||||
let expiry_reminder_days = state.conf.api_keys.expiry_reminder_days.clone();
|
||||
|
||||
let task_id = generate_task_id_for_api_key_expiry_workflow(key_id);
|
||||
let task_id = generate_task_id_for_api_key_expiry_workflow(&key_id);
|
||||
// In order to determine how to update the existing process in the process_tracker table,
|
||||
// we need access to the current entry in the table.
|
||||
let existing_process_tracker_task = store
|
||||
@ -339,7 +339,7 @@ pub async fn update_api_key(
|
||||
// If an expiry is set to 'never'
|
||||
else {
|
||||
// Process exist in process, revoke it
|
||||
revoke_api_key_expiry_task(store, key_id)
|
||||
revoke_api_key_expiry_task(store, &key_id)
|
||||
.await
|
||||
.into_report()
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
|
||||
@ -476,14 +476,13 @@ pub async fn sync_refund_with_gateway(
|
||||
pub async fn refund_update_core(
|
||||
state: AppState,
|
||||
merchant_account: domain::MerchantAccount,
|
||||
refund_id: &str,
|
||||
req: refunds::RefundUpdateRequest,
|
||||
) -> RouterResponse<refunds::RefundResponse> {
|
||||
let db = state.store.as_ref();
|
||||
let refund = db
|
||||
.find_refund_by_merchant_id_refund_id(
|
||||
&merchant_account.merchant_id,
|
||||
refund_id,
|
||||
&req.refund_id,
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
@ -501,7 +500,9 @@ pub async fn refund_update_core(
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable_lazy(|| format!("Unable to update refund with refund_id: {refund_id}"))?;
|
||||
.attach_printable_lazy(|| {
|
||||
format!("Unable to update refund with refund_id: {}", req.refund_id)
|
||||
})?;
|
||||
|
||||
Ok(services::ApplicationResponse::Json(response.foreign_into()))
|
||||
}
|
||||
@ -698,7 +699,7 @@ pub async fn refund_list(
|
||||
pub async fn refund_filter_list(
|
||||
state: AppState,
|
||||
merchant_account: domain::MerchantAccount,
|
||||
req: api_models::refunds::TimeRange,
|
||||
req: api_models::payments::TimeRange,
|
||||
) -> RouterResponse<api_models::refunds::RefundListMetaData> {
|
||||
let db = state.store;
|
||||
let filter_list = db
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
pub mod helpers;
|
||||
pub mod transformers;
|
||||
|
||||
use api_models::routing as routing_types;
|
||||
use api_models::routing::{self as routing_types, RoutingAlgorithmId};
|
||||
#[cfg(feature = "business_profile_routing")]
|
||||
use api_models::routing::{RoutingRetrieveLinkQuery, RoutingRetrieveQuery};
|
||||
#[cfg(not(feature = "business_profile_routing"))]
|
||||
@ -319,14 +319,14 @@ pub async fn link_routing_config(
|
||||
pub async fn retrieve_routing_config(
|
||||
state: AppState,
|
||||
merchant_account: domain::MerchantAccount,
|
||||
algorithm_id: String,
|
||||
algorithm_id: RoutingAlgorithmId,
|
||||
) -> RouterResponse<routing_types::MerchantRoutingAlgorithm> {
|
||||
let db = state.store.as_ref();
|
||||
#[cfg(feature = "business_profile_routing")]
|
||||
{
|
||||
let routing_algorithm = db
|
||||
.find_routing_algorithm_by_algorithm_id_merchant_id(
|
||||
&algorithm_id,
|
||||
&algorithm_id.0,
|
||||
&merchant_account.merchant_id,
|
||||
)
|
||||
.await
|
||||
@ -356,13 +356,13 @@ pub async fn retrieve_routing_config(
|
||||
let record = merchant_dictionary
|
||||
.records
|
||||
.into_iter()
|
||||
.find(|rec| rec.id == algorithm_id)
|
||||
.find(|rec| rec.id == algorithm_id.0)
|
||||
.ok_or(errors::ApiErrorResponse::ResourceIdNotFound)
|
||||
.into_report()
|
||||
.attach_printable("Algorithm with the given ID not found in the merchant dictionary")?;
|
||||
|
||||
let algorithm_config = db
|
||||
.find_config_by_key(&algorithm_id)
|
||||
.find_config_by_key(&algorithm_id.0)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::ResourceIdNotFound)
|
||||
.attach_printable("Routing config not found in DB")?;
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
pub mod utils;
|
||||
use actix_web::web;
|
||||
use api_models::verifications::{self, ApplepayMerchantResponse};
|
||||
use common_utils::{errors::CustomResult, ext_traits::Encode};
|
||||
use error_stack::ResultExt;
|
||||
@ -18,7 +17,7 @@ const APPLEPAY_INTERNAL_MERCHANT_NAME: &str = "Applepay_merchant";
|
||||
pub async fn verify_merchant_creds_for_applepay(
|
||||
state: AppState,
|
||||
_req: &actix_web::HttpRequest,
|
||||
body: web::Json<verifications::ApplepayMerchantVerificationRequest>,
|
||||
body: verifications::ApplepayMerchantVerificationRequest,
|
||||
kms_config: &kms::KmsConfig,
|
||||
merchant_id: String,
|
||||
) -> CustomResult<
|
||||
|
||||
@ -78,7 +78,7 @@ pub trait RefundInterface {
|
||||
async fn filter_refund_by_meta_constraints(
|
||||
&self,
|
||||
merchant_id: &str,
|
||||
refund_details: &api_models::refunds::TimeRange,
|
||||
refund_details: &api_models::payments::TimeRange,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<api_models::refunds::RefundListMetaData, errors::StorageError>;
|
||||
|
||||
@ -232,7 +232,7 @@ mod storage {
|
||||
async fn filter_refund_by_meta_constraints(
|
||||
&self,
|
||||
merchant_id: &str,
|
||||
refund_details: &api_models::refunds::TimeRange,
|
||||
refund_details: &api_models::payments::TimeRange,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<api_models::refunds::RefundListMetaData, errors::StorageError> {
|
||||
let conn = connection::pg_connection_read(self).await?;
|
||||
@ -707,7 +707,7 @@ mod storage {
|
||||
async fn filter_refund_by_meta_constraints(
|
||||
&self,
|
||||
merchant_id: &str,
|
||||
refund_details: &api_models::refunds::TimeRange,
|
||||
refund_details: &api_models::payments::TimeRange,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<api_models::refunds::RefundListMetaData, errors::StorageError> {
|
||||
let conn = connection::pg_connection_read(self).await?;
|
||||
@ -979,7 +979,7 @@ impl RefundInterface for MockDb {
|
||||
async fn filter_refund_by_meta_constraints(
|
||||
&self,
|
||||
_merchant_id: &str,
|
||||
refund_details: &api_models::refunds::TimeRange,
|
||||
refund_details: &api_models::payments::TimeRange,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
) -> CustomResult<api_models::refunds::RefundListMetaData, errors::StorageError> {
|
||||
let refunds = self.refunds.lock().await;
|
||||
|
||||
@ -1,10 +1,25 @@
|
||||
use actix_web::HttpRequest;
|
||||
pub use common_utils::events::{ApiEventMetric, ApiEventsType};
|
||||
use common_utils::impl_misc_api_event_type;
|
||||
use router_env::{tracing_actix_web::RequestId, types::FlowMetric};
|
||||
use serde::Serialize;
|
||||
use time::OffsetDateTime;
|
||||
|
||||
use super::{EventType, RawEvent};
|
||||
use crate::services::authentication::AuthenticationType;
|
||||
#[cfg(feature = "dummy_connector")]
|
||||
use crate::routes::dummy_connector::types::{
|
||||
DummyConnectorPaymentCompleteRequest, DummyConnectorPaymentConfirmRequest,
|
||||
DummyConnectorPaymentRequest, DummyConnectorPaymentResponse,
|
||||
DummyConnectorPaymentRetrieveRequest, DummyConnectorRefundRequest,
|
||||
DummyConnectorRefundResponse, DummyConnectorRefundRetrieveRequest,
|
||||
};
|
||||
use crate::{
|
||||
core::payments::PaymentsRedirectResponseData,
|
||||
services::{authentication::AuthenticationType, ApplicationResponse, PaymentLinkFormData},
|
||||
types::api::{
|
||||
AttachEvidenceRequest, Config, ConfigUpdate, CreateFileRequest, DisputeId, FileId,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct ApiEvent {
|
||||
@ -20,6 +35,8 @@ pub struct ApiEvent {
|
||||
ip_addr: Option<String>,
|
||||
url_path: String,
|
||||
response: Option<serde_json::Value>,
|
||||
#[serde(flatten)]
|
||||
event_type: ApiEventsType,
|
||||
}
|
||||
|
||||
impl ApiEvent {
|
||||
@ -32,6 +49,7 @@ impl ApiEvent {
|
||||
request: serde_json::Value,
|
||||
response: Option<serde_json::Value>,
|
||||
auth_type: AuthenticationType,
|
||||
event_type: ApiEventsType,
|
||||
http_req: &HttpRequest,
|
||||
) -> Self {
|
||||
Self {
|
||||
@ -52,6 +70,7 @@ impl ApiEvent {
|
||||
.get("user-agent")
|
||||
.and_then(|user_agent_value| user_agent_value.to_str().ok().map(ToOwned::to_owned)),
|
||||
url_path: http_req.path().to_string(),
|
||||
event_type,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -67,3 +86,35 @@ impl TryFrom<ApiEvent> for RawEvent {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ApiEventMetric> ApiEventMetric for ApplicationResponse<T> {
|
||||
fn get_api_event_type(&self) -> Option<ApiEventsType> {
|
||||
match self {
|
||||
Self::Json(r) => r.get_api_event_type(),
|
||||
Self::JsonWithHeaders((r, _)) => r.get_api_event_type(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl_misc_api_event_type!(
|
||||
Config,
|
||||
CreateFileRequest,
|
||||
FileId,
|
||||
AttachEvidenceRequest,
|
||||
DisputeId,
|
||||
PaymentLinkFormData,
|
||||
PaymentsRedirectResponseData,
|
||||
ConfigUpdate
|
||||
);
|
||||
|
||||
#[cfg(feature = "dummy_connector")]
|
||||
impl_misc_api_event_type!(
|
||||
DummyConnectorPaymentCompleteRequest,
|
||||
DummyConnectorPaymentRequest,
|
||||
DummyConnectorPaymentResponse,
|
||||
DummyConnectorPaymentRetrieveRequest,
|
||||
DummyConnectorPaymentConfirmRequest,
|
||||
DummyConnectorRefundRetrieveRequest,
|
||||
DummyConnectorRefundResponse,
|
||||
DummyConnectorRefundRequest
|
||||
);
|
||||
|
||||
@ -305,7 +305,7 @@ Never share your secret api keys. Keep them guarded and secure.
|
||||
api_models::payment_methods::RequiredFieldInfo,
|
||||
api_models::refunds::RefundListRequest,
|
||||
api_models::refunds::RefundListResponse,
|
||||
api_models::refunds::TimeRange,
|
||||
api_models::payments::TimeRange,
|
||||
api_models::mandates::MandateRevokedResponse,
|
||||
api_models::mandates::MandateResponse,
|
||||
api_models::mandates::MandateCardDetails,
|
||||
|
||||
@ -388,15 +388,15 @@ pub async fn merchant_account_toggle_kv(
|
||||
json_payload: web::Json<admin::ToggleKVRequest>,
|
||||
) -> HttpResponse {
|
||||
let flow = Flow::ConfigKeyUpdate;
|
||||
let payload = json_payload.into_inner();
|
||||
let merchant_id = path.into_inner();
|
||||
let mut payload = json_payload.into_inner();
|
||||
payload.merchant_id = path.into_inner();
|
||||
|
||||
api::server_wrap(
|
||||
flow,
|
||||
state,
|
||||
&req,
|
||||
(merchant_id, payload),
|
||||
|state, _, (merchant_id, payload)| kv_for_merchant(state, merchant_id, payload.kv_enabled),
|
||||
payload,
|
||||
|state, _, payload| kv_for_merchant(state, payload.merchant_id, payload.kv_enabled),
|
||||
&auth::AdminApiAuth,
|
||||
api_locking::LockAction::NotApplicable,
|
||||
)
|
||||
|
||||
@ -124,16 +124,16 @@ pub async fn api_key_update(
|
||||
) -> impl Responder {
|
||||
let flow = Flow::ApiKeyUpdate;
|
||||
let (merchant_id, key_id) = path.into_inner();
|
||||
let payload = json_payload.into_inner();
|
||||
let mut payload = json_payload.into_inner();
|
||||
payload.key_id = key_id;
|
||||
payload.merchant_id = merchant_id;
|
||||
|
||||
api::server_wrap(
|
||||
flow,
|
||||
state,
|
||||
&req,
|
||||
(&merchant_id, &key_id, payload),
|
||||
|state, _, (merchant_id, key_id, payload)| {
|
||||
api_keys::update_api_key(state, merchant_id, key_id, payload)
|
||||
},
|
||||
payload,
|
||||
|state, _, payload| api_keys::update_api_key(state, payload),
|
||||
&auth::AdminApiAuth,
|
||||
api_locking::LockAction::NotApplicable,
|
||||
)
|
||||
|
||||
@ -10,7 +10,7 @@ use crate::{
|
||||
mod consts;
|
||||
mod core;
|
||||
mod errors;
|
||||
mod types;
|
||||
pub mod types;
|
||||
mod utils;
|
||||
|
||||
#[instrument(skip_all, fields(flow = ?types::Flow::DummyPaymentCreate))]
|
||||
|
||||
@ -161,13 +161,14 @@ pub async fn refunds_update(
|
||||
path: web::Path<String>,
|
||||
) -> HttpResponse {
|
||||
let flow = Flow::RefundsUpdate;
|
||||
let refund_id = path.into_inner();
|
||||
let mut refund_update_req = json_payload.into_inner();
|
||||
refund_update_req.refund_id = path.into_inner();
|
||||
api::server_wrap(
|
||||
flow,
|
||||
state,
|
||||
&req,
|
||||
json_payload.into_inner(),
|
||||
|state, auth, req| refund_update_core(state, auth.merchant_account, &refund_id, req),
|
||||
refund_update_req,
|
||||
|state, auth, req| refund_update_core(state, auth.merchant_account, req),
|
||||
&auth::ApiKeyAuth,
|
||||
api_locking::LockAction::NotApplicable,
|
||||
)
|
||||
@ -225,7 +226,7 @@ pub async fn refunds_list(
|
||||
pub async fn refunds_filter_list(
|
||||
state: web::Data<AppState>,
|
||||
req: HttpRequest,
|
||||
payload: web::Json<api_models::refunds::TimeRange>,
|
||||
payload: web::Json<api_models::payments::TimeRange>,
|
||||
) -> HttpResponse {
|
||||
let flow = Flow::RefundsList;
|
||||
api::server_wrap(
|
||||
|
||||
@ -47,7 +47,7 @@ pub async fn routing_create_config(
|
||||
pub async fn routing_link_config(
|
||||
state: web::Data<AppState>,
|
||||
req: HttpRequest,
|
||||
path: web::Path<String>,
|
||||
path: web::Path<routing_types::RoutingAlgorithmId>,
|
||||
) -> impl Responder {
|
||||
let flow = Flow::RoutingLinkConfig;
|
||||
Box::pin(oss_api::server_wrap(
|
||||
@ -61,7 +61,7 @@ pub async fn routing_link_config(
|
||||
auth.merchant_account,
|
||||
#[cfg(not(feature = "business_profile_routing"))]
|
||||
auth.key_store,
|
||||
algorithm_id,
|
||||
algorithm_id.0,
|
||||
)
|
||||
},
|
||||
#[cfg(not(feature = "release"))]
|
||||
@ -78,7 +78,7 @@ pub async fn routing_link_config(
|
||||
pub async fn routing_retrieve_config(
|
||||
state: web::Data<AppState>,
|
||||
req: HttpRequest,
|
||||
path: web::Path<String>,
|
||||
path: web::Path<routing_types::RoutingAlgorithmId>,
|
||||
) -> impl Responder {
|
||||
let algorithm_id = path.into_inner();
|
||||
let flow = Flow::RoutingRetrieveConfig;
|
||||
|
||||
@ -22,7 +22,7 @@ pub async fn apple_pay_merchant_registration(
|
||||
flow,
|
||||
state,
|
||||
&req,
|
||||
json_payload,
|
||||
json_payload.into_inner(),
|
||||
|state, _, body| {
|
||||
verification::verify_merchant_creds_for_applepay(
|
||||
state.clone(),
|
||||
|
||||
@ -34,7 +34,7 @@ use crate::{
|
||||
errors::{self, CustomResult},
|
||||
payments,
|
||||
},
|
||||
events::api_logs::ApiEvent,
|
||||
events::api_logs::{ApiEvent, ApiEventMetric, ApiEventsType},
|
||||
logger,
|
||||
routes::{
|
||||
app::AppStateInfo,
|
||||
@ -769,8 +769,8 @@ where
|
||||
F: Fn(A, U, T) -> Fut,
|
||||
'b: 'a,
|
||||
Fut: Future<Output = CustomResult<ApplicationResponse<Q>, E>>,
|
||||
Q: Serialize + Debug + 'a,
|
||||
T: Debug + Serialize,
|
||||
Q: Serialize + Debug + 'a + ApiEventMetric,
|
||||
T: Debug + Serialize + ApiEventMetric,
|
||||
A: AppStateInfo + Clone,
|
||||
E: ErrorSwitch<OErr> + error_stack::Context,
|
||||
OErr: ResponseError + error_stack::Context,
|
||||
@ -791,6 +791,8 @@ where
|
||||
.attach_printable("Failed to serialize json request")
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError.switch())?;
|
||||
|
||||
let mut event_type = payload.get_api_event_type();
|
||||
|
||||
// Currently auth failures are not recorded as API events
|
||||
let (auth_out, auth_type) = api_auth
|
||||
.authenticate_and_fetch(request.headers(), &request_state)
|
||||
@ -838,6 +840,7 @@ where
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError.switch())?,
|
||||
);
|
||||
}
|
||||
event_type = res.get_api_event_type().or(event_type);
|
||||
|
||||
metrics::request::track_response_status_code(res)
|
||||
}
|
||||
@ -852,6 +855,7 @@ where
|
||||
serialized_request,
|
||||
serialized_response,
|
||||
auth_type,
|
||||
event_type.unwrap_or(ApiEventsType::Miscellaneous),
|
||||
request,
|
||||
);
|
||||
match api_event.clone().try_into() {
|
||||
@ -884,8 +888,8 @@ pub async fn server_wrap<'a, A, T, U, Q, F, Fut, E>(
|
||||
where
|
||||
F: Fn(A, U, T) -> Fut,
|
||||
Fut: Future<Output = CustomResult<ApplicationResponse<Q>, E>>,
|
||||
Q: Serialize + Debug + 'a,
|
||||
T: Debug + Serialize,
|
||||
Q: Serialize + Debug + ApiEventMetric + 'a,
|
||||
T: Debug + Serialize + ApiEventMetric,
|
||||
A: AppStateInfo + Clone,
|
||||
ApplicationResponse<Q>: Debug,
|
||||
E: ErrorSwitch<api_models::errors::types::ApiErrorResponse> + error_stack::Context,
|
||||
|
||||
@ -10,6 +10,12 @@ newtype!(
|
||||
derives = (Debug, Clone, Serialize)
|
||||
);
|
||||
|
||||
impl common_utils::events::ApiEventMetric for CustomerResponse {
|
||||
fn get_api_event_type(&self) -> Option<common_utils::events::ApiEventsType> {
|
||||
self.0.get_api_event_type()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) trait CustomerRequestExt: Sized {
|
||||
fn validate(self) -> RouterResult<Self>;
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ pub trait RefundDbExt: Sized {
|
||||
async fn filter_by_meta_constraints(
|
||||
conn: &PgPooledConn,
|
||||
merchant_id: &str,
|
||||
refund_list_details: &api_models::refunds::TimeRange,
|
||||
refund_list_details: &api_models::payments::TimeRange,
|
||||
) -> CustomResult<api_models::refunds::RefundListMetaData, errors::DatabaseError>;
|
||||
|
||||
async fn get_refunds_count(
|
||||
@ -114,7 +114,7 @@ impl RefundDbExt for Refund {
|
||||
async fn filter_by_meta_constraints(
|
||||
conn: &PgPooledConn,
|
||||
merchant_id: &str,
|
||||
refund_list_details: &api_models::refunds::TimeRange,
|
||||
refund_list_details: &api_models::payments::TimeRange,
|
||||
) -> CustomResult<api_models::refunds::RefundListMetaData, errors::DatabaseError> {
|
||||
let start_time = refund_list_details.start_time;
|
||||
|
||||
|
||||
@ -11218,12 +11218,12 @@
|
||||
"start_time": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "The start time to filter refunds list or to get list of filters. To get list of filters start time is needed to be passed"
|
||||
"description": "The start time to filter payments list or to get list of filters. To get list of filters start time is needed to be passed"
|
||||
},
|
||||
"end_time": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "The end time to filter refunds list or to get list of filters. If not passed the default time is now",
|
||||
"description": "The end time to filter payments list or to get list of filters. If not passed the default time is now",
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user