diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0aa00381bf62..412b42afc2eb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,25 @@ All notable changes to HyperSwitch will be documented here.
- - -
+## 1.75.0 (2023-11-09)
+
+### Features
+
+- **events:** Add extracted fields based on req/res types ([#2795](https://github.com/juspay/hyperswitch/pull/2795)) ([`8985794`](https://github.com/juspay/hyperswitch/commit/89857941b09c5fbe0f3e7d5b4f908bb144ae162d))
+- **router:**
+ - Added merchant custom name support for payment link ([#2685](https://github.com/juspay/hyperswitch/pull/2685)) ([`8b15189`](https://github.com/juspay/hyperswitch/commit/8b151898dc0d8eefe5ed2bbdafe59e8f58b4698c))
+ - Add `gateway_status_map` CRUD APIs ([#2809](https://github.com/juspay/hyperswitch/pull/2809)) ([`5c9e235`](https://github.com/juspay/hyperswitch/commit/5c9e235bd30dd3e03d086a83613edfcc62b2ead2))
+
+### Bug Fixes
+
+- **analytics:** Added hs latency to api event for paymentconfirm call ([#2787](https://github.com/juspay/hyperswitch/pull/2787)) ([`aab8f60`](https://github.com/juspay/hyperswitch/commit/aab8f6035c16ca19009f8f1e0db688c17bc0b2b6))
+- [mollie] locale validation irrespective of auth type ([#2814](https://github.com/juspay/hyperswitch/pull/2814)) ([`25a73c2`](https://github.com/juspay/hyperswitch/commit/25a73c29a4c4715a54862dd6a28c875fd3752f63))
+
+**Full Changelog:** [`v1.74.0...v1.75.0`](https://github.com/juspay/hyperswitch/compare/v1.74.0...v1.75.0)
+
+- - -
+
+
## 1.74.0 (2023-11-08)
### Features
diff --git a/README.md b/README.md
index e6e9baa07f7d..129a0512d4a0 100644
--- a/README.md
+++ b/README.md
@@ -64,13 +64,16 @@ The fastest and easiest way to try hyperswitch is via our CDK scripts
1. Click on the following button for a quick standalone deployment on AWS, suitable for prototyping.
No code or setup is required in your system and the deployment is covered within the AWS free-tier setup.
-
+ Click here if you have not bootstrapped your region before deploying
+
+
+
2. Sign-in to your AWS console.
3. Follow the instructions provided on the console to successfully deploy Hyperswitch
-For an early access to the production-ready setup fill this Early Access Form
+For an early access to the production-ready setup fill this Early Access Form
🔌 Fast Integration for Stripe Users
diff --git a/crates/api_models/src/events.rs b/crates/api_models/src/events.rs
index 78f34b4b87fa..23e7c9dc706a 100644
--- a/crates/api_models/src/events.rs
+++ b/crates/api_models/src/events.rs
@@ -1,4 +1,5 @@
pub mod customer;
+pub mod gsm;
pub mod payment;
#[cfg(feature = "payouts")]
pub mod payouts;
diff --git a/crates/api_models/src/events/gsm.rs b/crates/api_models/src/events/gsm.rs
new file mode 100644
index 000000000000..d984ae1ff698
--- /dev/null
+++ b/crates/api_models/src/events/gsm.rs
@@ -0,0 +1,33 @@
+use common_utils::events::{ApiEventMetric, ApiEventsType};
+
+use crate::gsm;
+
+impl ApiEventMetric for gsm::GsmCreateRequest {
+ fn get_api_event_type(&self) -> Option {
+ Some(ApiEventsType::Gsm)
+ }
+}
+
+impl ApiEventMetric for gsm::GsmUpdateRequest {
+ fn get_api_event_type(&self) -> Option {
+ Some(ApiEventsType::Gsm)
+ }
+}
+
+impl ApiEventMetric for gsm::GsmRetrieveRequest {
+ fn get_api_event_type(&self) -> Option {
+ Some(ApiEventsType::Gsm)
+ }
+}
+
+impl ApiEventMetric for gsm::GsmDeleteRequest {
+ fn get_api_event_type(&self) -> Option {
+ Some(ApiEventsType::Gsm)
+ }
+}
+
+impl ApiEventMetric for gsm::GsmDeleteResponse {
+ fn get_api_event_type(&self) -> Option {
+ Some(ApiEventsType::Gsm)
+ }
+}
diff --git a/crates/api_models/src/gsm.rs b/crates/api_models/src/gsm.rs
new file mode 100644
index 000000000000..6bd8fd99dd93
--- /dev/null
+++ b/crates/api_models/src/gsm.rs
@@ -0,0 +1,75 @@
+use crate::enums;
+
+#[derive(Debug, serde::Deserialize, serde::Serialize)]
+pub struct GsmCreateRequest {
+ pub connector: enums::Connector,
+ pub flow: String,
+ pub sub_flow: String,
+ pub code: String,
+ pub message: String,
+ pub status: String,
+ pub router_error: Option,
+ pub decision: GsmDecision,
+ pub step_up_possible: bool,
+}
+
+#[derive(Debug, serde::Deserialize, serde::Serialize)]
+pub struct GsmRetrieveRequest {
+ pub connector: enums::Connector,
+ pub flow: String,
+ pub sub_flow: String,
+ pub code: String,
+ pub message: String,
+}
+
+#[derive(
+ Default,
+ Clone,
+ Copy,
+ Debug,
+ strum::Display,
+ PartialEq,
+ Eq,
+ serde::Serialize,
+ serde::Deserialize,
+ strum::EnumString,
+)]
+#[serde(rename_all = "snake_case")]
+#[strum(serialize_all = "snake_case")]
+pub enum GsmDecision {
+ Retry,
+ Requeue,
+ #[default]
+ DoDefault,
+}
+
+#[derive(Debug, serde::Deserialize, serde::Serialize)]
+pub struct GsmUpdateRequest {
+ pub connector: String,
+ pub flow: String,
+ pub sub_flow: String,
+ pub code: String,
+ pub message: String,
+ pub status: Option,
+ pub router_error: Option,
+ pub decision: Option,
+ pub step_up_possible: Option,
+}
+
+#[derive(Debug, serde::Deserialize, serde::Serialize)]
+pub struct GsmDeleteRequest {
+ pub connector: String,
+ pub flow: String,
+ pub sub_flow: String,
+ pub code: String,
+ pub message: String,
+}
+
+#[derive(Debug, serde::Serialize)]
+pub struct GsmDeleteResponse {
+ pub gsm_rule_delete: bool,
+ pub connector: String,
+ pub flow: String,
+ pub sub_flow: String,
+ pub code: String,
+}
diff --git a/crates/api_models/src/lib.rs b/crates/api_models/src/lib.rs
index 9fff344b9ff7..5da916b14817 100644
--- a/crates/api_models/src/lib.rs
+++ b/crates/api_models/src/lib.rs
@@ -11,6 +11,7 @@ pub mod ephemeral_key;
pub mod errors;
pub mod events;
pub mod files;
+pub mod gsm;
pub mod mandates;
pub mod organization;
pub mod payment_methods;
diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs
index c1880d58ad19..196dd108333b 100644
--- a/crates/api_models/src/payments.rs
+++ b/crates/api_models/src/payments.rs
@@ -3100,6 +3100,8 @@ pub struct PaymentLinkObject {
#[serde(default, with = "common_utils::custom_serde::iso8601::option")]
pub link_expiry: Option,
pub merchant_custom_domain_name: Option,
+ /// Custom merchant name for payment link
+ pub custom_merchant_name: Option,
}
#[derive(Default, Debug, serde::Deserialize, Clone, ToSchema, serde::Serialize)]
@@ -3143,11 +3145,11 @@ pub struct PaymentLinkDetails {
pub pub_key: String,
pub client_secret: String,
pub payment_id: String,
- #[serde(with = "common_utils::custom_serde::iso8601")]
- pub expiry: PrimitiveDateTime,
+ #[serde(with = "common_utils::custom_serde::iso8601::option")]
+ pub expiry: Option,
pub merchant_logo: String,
pub return_url: String,
- pub merchant_name: crypto::OptionalEncryptableName,
+ pub merchant_name: String,
pub order_details: Vec,
pub max_items_visible_after_collapse: i8,
}
diff --git a/crates/common_utils/src/events.rs b/crates/common_utils/src/events.rs
index 1d487364031d..8c52f6c36d63 100644
--- a/crates/common_utils/src/events.rs
+++ b/crates/common_utils/src/events.rs
@@ -41,6 +41,7 @@ pub enum ApiEventsType {
Routing,
ResourceListAPI,
PaymentRedirectionResponse,
+ Gsm,
// TODO: This has to be removed once the corresponding apiEventTypes are created
Miscellaneous,
}
diff --git a/crates/data_models/src/payments/payment_attempt.rs b/crates/data_models/src/payments/payment_attempt.rs
index 734de8fe4a55..cdd41ea9db2d 100644
--- a/crates/data_models/src/payments/payment_attempt.rs
+++ b/crates/data_models/src/payments/payment_attempt.rs
@@ -286,6 +286,8 @@ pub enum PaymentAttemptUpdate {
connector_response_reference_id: Option,
amount_capturable: Option,
updated_by: String,
+ authentication_data: Option,
+ encoded_data: Option,
},
UnresolvedResponseUpdate {
status: storage_enums::AttemptStatus,
diff --git a/crates/diesel_models/src/connector_response.rs b/crates/diesel_models/src/connector_response.rs
deleted file mode 100644
index 863ce28ee0ae..000000000000
--- a/crates/diesel_models/src/connector_response.rs
+++ /dev/null
@@ -1,122 +0,0 @@
-use diesel::{AsChangeset, Identifiable, Insertable, Queryable};
-use serde::{Deserialize, Serialize};
-use time::PrimitiveDateTime;
-
-use crate::schema::connector_response;
-
-#[derive(Clone, Debug, Deserialize, Serialize, Insertable, router_derive::DebugAsDisplay)]
-#[diesel(table_name = connector_response)]
-#[serde(deny_unknown_fields)]
-pub struct ConnectorResponseNew {
- pub payment_id: String,
- pub merchant_id: String,
- pub attempt_id: String,
- #[serde(with = "common_utils::custom_serde::iso8601")]
- pub created_at: PrimitiveDateTime,
- #[serde(with = "common_utils::custom_serde::iso8601")]
- pub modified_at: PrimitiveDateTime,
- pub connector_name: Option,
- pub connector_transaction_id: Option,
- pub authentication_data: Option,
- pub encoded_data: Option,
- pub updated_by: String,
-}
-
-#[derive(Clone, Debug, Deserialize, Serialize, Identifiable, Queryable)]
-#[diesel(table_name = connector_response)]
-pub struct ConnectorResponse {
- pub id: i32,
- pub payment_id: String,
- pub merchant_id: String,
- pub attempt_id: String,
- #[serde(with = "common_utils::custom_serde::iso8601")]
- pub created_at: PrimitiveDateTime,
- #[serde(with = "common_utils::custom_serde::iso8601")]
- pub modified_at: PrimitiveDateTime,
- pub connector_name: Option,
- pub connector_transaction_id: Option,
- pub authentication_data: Option,
- pub encoded_data: Option,
- pub updated_by: String,
-}
-
-#[derive(Clone, Default, Debug, Deserialize, AsChangeset, Serialize)]
-#[diesel(table_name = connector_response)]
-pub struct ConnectorResponseUpdateInternal {
- pub connector_transaction_id: Option,
- pub authentication_data: Option,
- pub modified_at: Option,
- pub encoded_data: Option,
- pub connector_name: Option,
- pub updated_by: String,
-}
-
-#[derive(Clone, Debug, Serialize, Deserialize)]
-pub enum ConnectorResponseUpdate {
- ResponseUpdate {
- connector_transaction_id: Option,
- authentication_data: Option,
- encoded_data: Option,
- connector_name: Option,
- updated_by: String,
- },
- ErrorUpdate {
- connector_name: Option,
- updated_by: String,
- },
-}
-
-impl ConnectorResponseUpdate {
- pub fn apply_changeset(self, source: ConnectorResponse) -> ConnectorResponse {
- let connector_response_update: ConnectorResponseUpdateInternal = self.into();
- ConnectorResponse {
- modified_at: connector_response_update
- .modified_at
- .unwrap_or_else(common_utils::date_time::now),
- connector_name: connector_response_update
- .connector_name
- .or(source.connector_name),
- connector_transaction_id: source
- .connector_transaction_id
- .or(connector_response_update.connector_transaction_id),
- authentication_data: connector_response_update
- .authentication_data
- .or(source.authentication_data),
- encoded_data: connector_response_update
- .encoded_data
- .or(source.encoded_data),
- updated_by: connector_response_update.updated_by,
- ..source
- }
- }
-}
-
-impl From for ConnectorResponseUpdateInternal {
- fn from(connector_response_update: ConnectorResponseUpdate) -> Self {
- match connector_response_update {
- ConnectorResponseUpdate::ResponseUpdate {
- connector_transaction_id,
- authentication_data,
- encoded_data,
- connector_name,
- updated_by,
- } => Self {
- connector_transaction_id,
- authentication_data,
- encoded_data,
- modified_at: Some(common_utils::date_time::now()),
- connector_name,
- updated_by,
- },
- ConnectorResponseUpdate::ErrorUpdate {
- connector_name,
- updated_by,
- } => Self {
- connector_name,
- modified_at: Some(common_utils::date_time::now()),
- updated_by,
- ..Self::default()
- },
- }
- }
-}
diff --git a/crates/diesel_models/src/gsm.rs b/crates/diesel_models/src/gsm.rs
index d5b3122c7806..2e824758aa5a 100644
--- a/crates/diesel_models/src/gsm.rs
+++ b/crates/diesel_models/src/gsm.rs
@@ -1,6 +1,9 @@
//! Gateway status mapping
-use common_utils::custom_serde;
+use common_utils::{
+ custom_serde,
+ events::{ApiEventMetric, ApiEventsType},
+};
use diesel::{AsChangeset, Identifiable, Insertable, Queryable};
use time::PrimitiveDateTime;
@@ -95,3 +98,9 @@ impl From for GatewayStatusMapperUpdateInternal {
}
}
}
+
+impl ApiEventMetric for GatewayStatusMap {
+ fn get_api_event_type(&self) -> Option {
+ Some(ApiEventsType::Gsm)
+ }
+}
diff --git a/crates/diesel_models/src/kv.rs b/crates/diesel_models/src/kv.rs
index 81fa7a88ee3b..f56ef8304186 100644
--- a/crates/diesel_models/src/kv.rs
+++ b/crates/diesel_models/src/kv.rs
@@ -3,7 +3,6 @@ use serde::{Deserialize, Serialize};
use crate::{
address::{Address, AddressNew, AddressUpdateInternal},
- connector_response::{ConnectorResponse, ConnectorResponseNew, ConnectorResponseUpdate},
errors,
payment_attempt::{PaymentAttempt, PaymentAttemptNew, PaymentAttemptUpdate},
payment_intent::{PaymentIntentNew, PaymentIntentUpdate},
@@ -51,7 +50,6 @@ pub enum Insertable {
PaymentIntent(PaymentIntentNew),
PaymentAttempt(PaymentAttemptNew),
Refund(RefundNew),
- ConnectorResponse(ConnectorResponseNew),
Address(Box),
ReverseLookUp(ReverseLookupNew),
}
@@ -62,16 +60,9 @@ pub enum Updateable {
PaymentIntentUpdate(PaymentIntentUpdateMems),
PaymentAttemptUpdate(PaymentAttemptUpdateMems),
RefundUpdate(RefundUpdateMems),
- ConnectorResponseUpdate(ConnectorResponseUpdateMems),
AddressUpdate(Box),
}
-#[derive(Debug, Serialize, Deserialize)]
-pub struct ConnectorResponseUpdateMems {
- pub orig: ConnectorResponse,
- pub update_data: ConnectorResponseUpdate,
-}
-
#[derive(Debug, Serialize, Deserialize)]
pub struct AddressUpdateMems {
pub orig: Address,
diff --git a/crates/diesel_models/src/lib.rs b/crates/diesel_models/src/lib.rs
index 08d74fb8fd37..46a6965b3a7b 100644
--- a/crates/diesel_models/src/lib.rs
+++ b/crates/diesel_models/src/lib.rs
@@ -4,7 +4,7 @@ pub mod business_profile;
pub mod capture;
pub mod cards_info;
pub mod configs;
-pub mod connector_response;
+
pub mod customers;
pub mod dispute;
pub mod encryption;
@@ -44,10 +44,10 @@ use diesel_impl::{DieselArray, OptionalDieselArray};
pub type StorageResult = error_stack::Result;
pub type PgPooledConn = async_bb8_diesel::Connection;
pub use self::{
- address::*, api_keys::*, cards_info::*, configs::*, connector_response::*, customers::*,
- dispute::*, ephemeral_key::*, events::*, file::*, locker_mock_up::*, mandate::*,
- merchant_account::*, merchant_connector_account::*, payment_attempt::*, payment_intent::*,
- payment_method::*, process_tracker::*, refund::*, reverse_lookup::*,
+ address::*, api_keys::*, cards_info::*, configs::*, customers::*, dispute::*, ephemeral_key::*,
+ events::*, file::*, locker_mock_up::*, mandate::*, merchant_account::*,
+ merchant_connector_account::*, payment_attempt::*, payment_intent::*, payment_method::*,
+ process_tracker::*, refund::*, reverse_lookup::*,
};
/// The types and implementations provided by this module are required for the schema generated by
diff --git a/crates/diesel_models/src/payment_attempt.rs b/crates/diesel_models/src/payment_attempt.rs
index 058086106111..ce388fea10eb 100644
--- a/crates/diesel_models/src/payment_attempt.rs
+++ b/crates/diesel_models/src/payment_attempt.rs
@@ -203,6 +203,8 @@ pub enum PaymentAttemptUpdate {
connector_response_reference_id: Option,
amount_capturable: Option,
updated_by: String,
+ authentication_data: Option,
+ encoded_data: Option,
},
UnresolvedResponseUpdate {
status: storage_enums::AttemptStatus,
@@ -478,6 +480,8 @@ impl From for PaymentAttemptUpdateInternal {
connector_response_reference_id,
amount_capturable,
updated_by,
+ authentication_data,
+ encoded_data,
} => Self {
status: Some(status),
connector,
@@ -494,6 +498,8 @@ impl From for PaymentAttemptUpdateInternal {
connector_response_reference_id,
amount_capturable,
updated_by,
+ authentication_data,
+ encoded_data,
..Default::default()
},
PaymentAttemptUpdate::ErrorUpdate {
diff --git a/crates/diesel_models/src/payment_link.rs b/crates/diesel_models/src/payment_link.rs
index 4b182a8155a5..50cc5e89cee9 100644
--- a/crates/diesel_models/src/payment_link.rs
+++ b/crates/diesel_models/src/payment_link.rs
@@ -20,8 +20,8 @@ pub struct PaymentLink {
pub last_modified_at: PrimitiveDateTime,
#[serde(default, with = "common_utils::custom_serde::iso8601::option")]
pub fulfilment_time: Option,
+ pub custom_merchant_name: Option,
}
-
#[derive(
Clone,
Debug,
@@ -47,4 +47,5 @@ pub struct PaymentLinkNew {
pub last_modified_at: Option,
#[serde(default, with = "common_utils::custom_serde::iso8601::option")]
pub fulfilment_time: Option,
+ pub custom_merchant_name: Option,
}
diff --git a/crates/diesel_models/src/query.rs b/crates/diesel_models/src/query.rs
index ac3eeba44359..f315327702ad 100644
--- a/crates/diesel_models/src/query.rs
+++ b/crates/diesel_models/src/query.rs
@@ -4,7 +4,7 @@ pub mod business_profile;
mod capture;
pub mod cards_info;
pub mod configs;
-pub mod connector_response;
+
pub mod customers;
pub mod dispute;
pub mod events;
diff --git a/crates/diesel_models/src/schema.rs b/crates/diesel_models/src/schema.rs
index 50531e432adc..6c9cea035b3f 100644
--- a/crates/diesel_models/src/schema.rs
+++ b/crates/diesel_models/src/schema.rs
@@ -157,31 +157,6 @@ diesel::table! {
}
}
-diesel::table! {
- use diesel::sql_types::*;
- use crate::enums::diesel_exports::*;
-
- connector_response (id) {
- id -> Int4,
- #[max_length = 64]
- payment_id -> Varchar,
- #[max_length = 64]
- merchant_id -> Varchar,
- #[max_length = 64]
- attempt_id -> Varchar,
- created_at -> Timestamp,
- modified_at -> Timestamp,
- #[max_length = 64]
- connector_name -> Nullable,
- #[max_length = 128]
- connector_transaction_id -> Nullable,
- authentication_data -> Nullable,
- encoded_data -> Nullable,
- #[max_length = 32]
- updated_by -> Varchar,
- }
-}
-
diesel::table! {
use diesel::sql_types::*;
use crate::enums::diesel_exports::*;
@@ -691,6 +666,8 @@ diesel::table! {
created_at -> Timestamp,
last_modified_at -> Timestamp,
fulfilment_time -> Nullable,
+ #[max_length = 64]
+ custom_merchant_name -> Nullable,
}
}
@@ -930,7 +907,6 @@ diesel::allow_tables_to_appear_in_same_query!(
captures,
cards_info,
configs,
- connector_response,
customers,
dispute,
events,
diff --git a/crates/drainer/src/lib.rs b/crates/drainer/src/lib.rs
index 19abe9ba3aad..7ccfd600d662 100644
--- a/crates/drainer/src/lib.rs
+++ b/crates/drainer/src/lib.rs
@@ -206,7 +206,6 @@ async fn drainer(
let payment_attempt = "payment_attempt";
let refund = "refund";
let reverse_lookup = "reverse_lookup";
- let connector_response = "connector_response";
let address = "address";
match db_op {
// TODO: Handle errors
@@ -230,13 +229,6 @@ async fn drainer(
kv::Insertable::Refund(a) => {
macro_util::handle_resp!(a.insert(&conn).await, insert_op, refund)
}
- kv::Insertable::ConnectorResponse(a) => {
- macro_util::handle_resp!(
- a.insert(&conn).await,
- insert_op,
- connector_response
- )
- }
kv::Insertable::Address(addr) => {
macro_util::handle_resp!(addr.insert(&conn).await, insert_op, address)
}
@@ -283,11 +275,6 @@ async fn drainer(
refund
)
}
- kv::Updateable::ConnectorResponseUpdate(a) => macro_util::handle_resp!(
- a.orig.update(&conn, a.update_data).await,
- update_op,
- connector_response
- ),
kv::Updateable::AddressUpdate(a) => macro_util::handle_resp!(
a.orig.update(&conn, a.update_data).await,
update_op,
diff --git a/crates/router/src/core.rs b/crates/router/src/core.rs
index d87ff64003b4..817fafdae520 100644
--- a/crates/router/src/core.rs
+++ b/crates/router/src/core.rs
@@ -8,6 +8,7 @@ pub mod customers;
pub mod disputes;
pub mod errors;
pub mod files;
+pub mod gsm;
pub mod mandate;
pub mod metrics;
pub mod payment_link;
diff --git a/crates/router/src/core/gsm.rs b/crates/router/src/core/gsm.rs
new file mode 100644
index 000000000000..d25860674570
--- /dev/null
+++ b/crates/router/src/core/gsm.rs
@@ -0,0 +1,137 @@
+use api_models::gsm as gsm_api_types;
+use diesel_models::gsm as storage;
+use error_stack::{IntoReport, ResultExt};
+use router_env::{instrument, tracing};
+
+use crate::{
+ core::{
+ errors,
+ errors::{RouterResponse, StorageErrorExt},
+ },
+ db::gsm::GsmInterface,
+ services,
+ types::{self, transformers::ForeignInto},
+ AppState,
+};
+
+#[instrument(skip_all)]
+pub async fn create_gsm_rule(
+ state: AppState,
+ gsm_rule: gsm_api_types::GsmCreateRequest,
+) -> RouterResponse {
+ let db = state.store.as_ref();
+ GsmInterface::add_gsm_rule(db, gsm_rule.foreign_into())
+ .await
+ .to_duplicate_response(errors::ApiErrorResponse::GenericDuplicateError {
+ message: "GSM with given key already exists in our records".to_string(),
+ })
+ .map(services::ApplicationResponse::Json)
+}
+
+#[instrument(skip_all)]
+pub async fn retrieve_gsm_rule(
+ state: AppState,
+ gsm_request: gsm_api_types::GsmRetrieveRequest,
+) -> RouterResponse {
+ let db = state.store.as_ref();
+ let gsm_api_types::GsmRetrieveRequest {
+ connector,
+ flow,
+ sub_flow,
+ code,
+ message,
+ } = gsm_request;
+ GsmInterface::find_gsm_rule(db, connector.to_string(), flow, sub_flow, code, message)
+ .await
+ .to_not_found_response(errors::ApiErrorResponse::GenericNotFoundError {
+ message: "GSM with given key does not exist in our records".to_string(),
+ })
+ .map(services::ApplicationResponse::Json)
+}
+
+#[instrument(skip_all)]
+pub async fn update_gsm_rule(
+ state: AppState,
+ gsm_request: gsm_api_types::GsmUpdateRequest,
+) -> RouterResponse {
+ let db = state.store.as_ref();
+ let gsm_api_types::GsmUpdateRequest {
+ connector,
+ flow,
+ sub_flow,
+ code,
+ message,
+ decision,
+ status,
+ router_error,
+ step_up_possible,
+ } = gsm_request;
+ GsmInterface::update_gsm_rule(
+ db,
+ connector.to_string(),
+ flow,
+ sub_flow,
+ code,
+ message,
+ storage::GatewayStatusMappingUpdate {
+ decision: decision.map(|d| d.to_string()),
+ status,
+ router_error: Some(router_error),
+ step_up_possible,
+ },
+ )
+ .await
+ .to_not_found_response(errors::ApiErrorResponse::GenericNotFoundError {
+ message: "GSM with given key does not exist in our records".to_string(),
+ })
+ .attach_printable("Failed while updating Gsm rule")
+ .map(services::ApplicationResponse::Json)
+}
+
+#[instrument(skip_all)]
+pub async fn delete_gsm_rule(
+ state: AppState,
+ gsm_request: gsm_api_types::GsmDeleteRequest,
+) -> RouterResponse {
+ let db = state.store.as_ref();
+ let gsm_api_types::GsmDeleteRequest {
+ connector,
+ flow,
+ sub_flow,
+ code,
+ message,
+ } = gsm_request;
+ match GsmInterface::delete_gsm_rule(
+ db,
+ connector.to_string(),
+ flow.to_owned(),
+ sub_flow.to_owned(),
+ code.to_owned(),
+ message.to_owned(),
+ )
+ .await
+ .to_not_found_response(errors::ApiErrorResponse::GenericNotFoundError {
+ message: "GSM with given key does not exist in our records".to_string(),
+ })
+ .attach_printable("Failed while Deleting Gsm rule")
+ {
+ Ok(is_deleted) => {
+ if is_deleted {
+ Ok(services::ApplicationResponse::Json(
+ gsm_api_types::GsmDeleteResponse {
+ gsm_rule_delete: true,
+ connector,
+ flow,
+ sub_flow,
+ code,
+ },
+ ))
+ } else {
+ Err(errors::ApiErrorResponse::InternalServerError)
+ .into_report()
+ .attach_printable("Failed while Deleting Gsm rule, got response as false")
+ }
+ }
+ Err(err) => Err(err),
+ }
+}
diff --git a/crates/router/src/core/payment_link.rs b/crates/router/src/core/payment_link.rs
index 2c51fa0c3cbb..0012efc86c9f 100644
--- a/crates/router/src/core/payment_link.rs
+++ b/crates/router/src/core/payment_link.rs
@@ -1,6 +1,6 @@
use api_models::admin as admin_types;
-use common_utils::ext_traits::AsyncExt;
use error_stack::{IntoReport, ResultExt};
+use masking::PeekInterface;
use super::errors::{self, RouterResult, StorageErrorExt};
use crate::{
@@ -43,6 +43,11 @@ pub async fn intiate_payment_link_flow(
.await
.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
+ let payment_link_id = payment_intent
+ .payment_link_id
+ .get_required_value("payment_link_id")
+ .change_context(errors::ApiErrorResponse::PaymentLinkNotFound)?;
+
helpers::validate_payment_status_against_not_allowed_statuses(
&payment_intent.status,
&[
@@ -55,20 +60,10 @@ pub async fn intiate_payment_link_flow(
"create payment link",
)?;
- let fulfillment_time = payment_intent
- .payment_link_id
- .as_ref()
- .async_and_then(|pli| async move {
- db.find_payment_link_by_payment_link_id(pli)
- .await
- .ok()?
- .fulfilment_time
- .ok_or(errors::ApiErrorResponse::PaymentNotFound)
- .ok()
- })
+ let payment_link = db
+ .find_payment_link_by_payment_link_id(&payment_link_id)
.await
- .get_required_value("fulfillment_time")
- .change_context(errors::ApiErrorResponse::PaymentNotFound)?;
+ .to_not_found_response(errors::ApiErrorResponse::PaymentLinkNotFound)?;
let payment_link_config = merchant_account
.payment_link_config
@@ -108,10 +103,15 @@ pub async fn intiate_payment_link_flow(
amount: payment_intent.amount,
currency,
payment_id: payment_intent.payment_id,
- merchant_name: merchant_account.merchant_name,
+ merchant_name: payment_link.custom_merchant_name.unwrap_or(
+ merchant_account
+ .merchant_name
+ .map(|merchant_name| merchant_name.into_inner().peek().to_owned())
+ .unwrap_or_default(),
+ ),
order_details,
return_url,
- expiry: fulfillment_time,
+ expiry: payment_link.fulfilment_time,
pub_key,
client_secret,
merchant_logo: payment_link_config
diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs
index 98ab158e7935..a114b20380bf 100644
--- a/crates/router/src/core/payments.rs
+++ b/crates/router/src/core/payments.rs
@@ -1578,7 +1578,6 @@ where
pub payment_intent: storage::PaymentIntent,
pub payment_attempt: storage::PaymentAttempt,
pub multiple_capture_data: Option,
- pub connector_response: storage::ConnectorResponse,
pub amount: api::Amount,
pub mandate_id: Option,
pub mandate_connector: Option,
@@ -1671,10 +1670,7 @@ pub fn should_call_connector(
!matches!(
payment_data.payment_intent.status,
storage_enums::IntentStatus::Failed | storage_enums::IntentStatus::Succeeded
- ) && payment_data
- .connector_response
- .authentication_data
- .is_none()
+ ) && payment_data.payment_attempt.authentication_data.is_none()
}
"PaymentStatus" => {
matches!(
diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs
index fd9fd7361da3..4ee2fd4b94d3 100644
--- a/crates/router/src/core/payments/helpers.rs
+++ b/crates/router/src/core/payments/helpers.rs
@@ -2998,60 +2998,6 @@ impl AttemptType {
}
}
}
-
- #[instrument(skip_all)]
- pub async fn get_or_insert_connector_response(
- &self,
- payment_attempt: &PaymentAttempt,
- db: &dyn StorageInterface,
- storage_scheme: storage::enums::MerchantStorageScheme,
- ) -> RouterResult {
- match self {
- Self::New => db
- .insert_connector_response(
- payments::PaymentCreate::make_connector_response(payment_attempt),
- storage_scheme,
- )
- .await
- .to_duplicate_response(errors::ApiErrorResponse::DuplicatePayment {
- payment_id: payment_attempt.payment_id.clone(),
- }),
- Self::SameOld => db
- .find_connector_response_by_payment_id_merchant_id_attempt_id(
- &payment_attempt.payment_id,
- &payment_attempt.merchant_id,
- &payment_attempt.attempt_id,
- storage_scheme,
- )
- .await
- .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound),
- }
- }
-
- #[instrument(skip_all)]
- pub async fn get_connector_response(
- &self,
- db: &dyn StorageInterface,
- payment_id: &str,
- merchant_id: &str,
- attempt_id: &str,
- storage_scheme: storage_enums::MerchantStorageScheme,
- ) -> RouterResult {
- match self {
- Self::New => Err(errors::ApiErrorResponse::InternalServerError)
- .into_report()
- .attach_printable("Precondition failed, the attempt type should not be `New`"),
- Self::SameOld => db
- .find_connector_response_by_payment_id_merchant_id_attempt_id(
- payment_id,
- merchant_id,
- attempt_id,
- storage_scheme,
- )
- .await
- .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound),
- }
- }
}
#[inline(always)]
diff --git a/crates/router/src/core/payments/operations/payment_approve.rs b/crates/router/src/core/payments/operations/payment_approve.rs
index 4cd1bae04dee..d5d0d2d01765 100644
--- a/crates/router/src/core/payments/operations/payment_approve.rs
+++ b/crates/router/src/core/payments/operations/payment_approve.rs
@@ -161,16 +161,6 @@ impl
)
.await?;
- let connector_response = db
- .find_connector_response_by_payment_id_merchant_id_attempt_id(
- &payment_attempt.payment_id,
- &payment_attempt.merchant_id,
- &payment_attempt.attempt_id,
- storage_scheme,
- )
- .await
- .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
-
let redirect_response = request
.feature_metadata
.as_ref()
@@ -224,7 +214,6 @@ impl
payment_intent,
payment_attempt,
currency,
- connector_response,
amount,
email: request.email.clone(),
mandate_id: None,
diff --git a/crates/router/src/core/payments/operations/payment_cancel.rs b/crates/router/src/core/payments/operations/payment_cancel.rs
index 43fdc440e64d..f734afef7826 100644
--- a/crates/router/src/core/payments/operations/payment_cancel.rs
+++ b/crates/router/src/core/payments/operations/payment_cancel.rs
@@ -106,15 +106,6 @@ impl
)
.await?;
- let connector_response = db
- .find_connector_response_by_payment_id_merchant_id_attempt_id(
- &payment_attempt.payment_id,
- &payment_attempt.merchant_id,
- &payment_attempt.attempt_id,
- storage_scheme,
- )
- .await
- .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
let currency = payment_attempt.currency.get_required_value("currency")?;
let amount = payment_attempt.amount.into();
@@ -161,7 +152,7 @@ impl
refunds: vec![],
disputes: vec![],
attempts: None,
- connector_response,
+
sessions_token: vec![],
card_cvc: None,
creds_identifier,
diff --git a/crates/router/src/core/payments/operations/payment_capture.rs b/crates/router/src/core/payments/operations/payment_capture.rs
index 1cfcbce5532f..6e794b1ba618 100644
--- a/crates/router/src/core/payments/operations/payment_capture.rs
+++ b/crates/router/src/core/payments/operations/payment_capture.rs
@@ -3,7 +3,6 @@ use std::marker::PhantomData;
use api_models::enums::FrmSuggestion;
use async_trait::async_trait;
use common_utils::ext_traits::AsyncExt;
-use diesel_models::connector_response::ConnectorResponse;
use error_stack::ResultExt;
use router_env::{instrument, tracing};
@@ -20,7 +19,7 @@ use crate::{
types::{
api::{self, PaymentIdTypeExt},
domain,
- storage::{self, enums, payment_attempt::PaymentAttemptExt, ConnectorResponseExt},
+ storage::{self, enums, payment_attempt::PaymentAttemptExt},
},
utils::OptionExt,
};
@@ -89,9 +88,7 @@ impl
helpers::validate_capture_method(capture_method)?;
- let (multiple_capture_data, connector_response) = if capture_method
- == enums::CaptureMethod::ManualMultiple
- {
+ let multiple_capture_data = if capture_method == enums::CaptureMethod::ManualMultiple {
let amount_to_capture = request
.amount_to_capture
.get_required_value("amount_to_capture")?;
@@ -121,37 +118,13 @@ impl
.to_not_found_response(errors::ApiErrorResponse::DuplicatePayment {
payment_id: payment_id.clone(),
})?;
- let new_connector_response = db
- .insert_connector_response(
- ConnectorResponse::make_new_connector_response(
- capture.payment_id.clone(),
- capture.merchant_id.clone(),
- capture.capture_id.clone(),
- Some(capture.connector.clone()),
- storage_scheme.to_string(),
- ),
- storage_scheme,
- )
- .await
- .to_not_found_response(errors::ApiErrorResponse::DuplicatePayment { payment_id })?;
- (
- Some(MultipleCaptureData::new_for_create(
- previous_captures,
- capture,
- )),
- new_connector_response,
- )
+
+ Some(MultipleCaptureData::new_for_create(
+ previous_captures,
+ capture,
+ ))
} else {
- let connector_response = db
- .find_connector_response_by_payment_id_merchant_id_attempt_id(
- &payment_attempt.payment_id,
- &payment_attempt.merchant_id,
- &payment_attempt.attempt_id,
- storage_scheme,
- )
- .await
- .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
- (None, connector_response)
+ None
};
currency = payment_attempt.currency.get_required_value("currency")?;
@@ -223,7 +196,6 @@ impl
refunds: vec![],
disputes: vec![],
attempts: None,
- connector_response,
sessions_token: vec![],
card_cvc: None,
creds_identifier,
diff --git a/crates/router/src/core/payments/operations/payment_complete_authorize.rs b/crates/router/src/core/payments/operations/payment_complete_authorize.rs
index 4e87b3869431..038d34ea290f 100644
--- a/crates/router/src/core/payments/operations/payment_complete_authorize.rs
+++ b/crates/router/src/core/payments/operations/payment_complete_authorize.rs
@@ -170,16 +170,6 @@ impl
)
.await?;
- let connector_response = db
- .find_connector_response_by_payment_id_merchant_id_attempt_id(
- &payment_attempt.payment_id,
- &payment_attempt.merchant_id,
- &payment_attempt.attempt_id,
- storage_scheme,
- )
- .await
- .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
-
let redirect_response = request
.feature_metadata
.as_ref()
@@ -219,7 +209,6 @@ impl
payment_intent,
payment_attempt,
currency,
- connector_response,
amount,
email: request.email.clone(),
mandate_id: None,
diff --git a/crates/router/src/core/payments/operations/payment_confirm.rs b/crates/router/src/core/payments/operations/payment_confirm.rs
index 5de281a5e63c..21f7db3d0b41 100644
--- a/crates/router/src/core/payments/operations/payment_confirm.rs
+++ b/crates/router/src/core/payments/operations/payment_confirm.rs
@@ -157,77 +157,49 @@ impl
})
.map(|x| x.transpose());
- let (mut payment_attempt, shipping_address, billing_address, connector_response) =
- match payment_intent.status {
- api_models::enums::IntentStatus::RequiresCustomerAction
- | api_models::enums::IntentStatus::RequiresMerchantAction
- | api_models::enums::IntentStatus::RequiresPaymentMethod
- | api_models::enums::IntentStatus::RequiresConfirmation => {
- let attempt_type = helpers::AttemptType::SameOld;
-
- let attempt_id = payment_intent.active_attempt.get_id();
- let connector_response_fut = attempt_type.get_connector_response(
+ let (mut payment_attempt, shipping_address, billing_address) = match payment_intent.status {
+ api_models::enums::IntentStatus::RequiresCustomerAction
+ | api_models::enums::IntentStatus::RequiresMerchantAction
+ | api_models::enums::IntentStatus::RequiresPaymentMethod
+ | api_models::enums::IntentStatus::RequiresConfirmation => {
+ let (payment_attempt, shipping_address, billing_address, _) = futures::try_join!(
+ payment_attempt_fut,
+ shipping_address_fut,
+ billing_address_fut,
+ config_update_fut
+ )?;
+
+ (payment_attempt, shipping_address, billing_address)
+ }
+ _ => {
+ let (mut payment_attempt, shipping_address, billing_address, _) = futures::try_join!(
+ payment_attempt_fut,
+ shipping_address_fut,
+ billing_address_fut,
+ config_update_fut
+ )?;
+
+ let attempt_type = helpers::get_attempt_type(
+ &payment_intent,
+ &payment_attempt,
+ request,
+ "confirm",
+ )?;
+
+ (payment_intent, payment_attempt) = attempt_type
+ .modify_payment_intent_and_payment_attempt(
+ // 3
+ request,
+ payment_intent,
+ payment_attempt,
db,
- &payment_intent.payment_id,
- &payment_intent.merchant_id,
- attempt_id.as_str(),
storage_scheme,
- );
-
- let (payment_attempt, shipping_address, billing_address, connector_response, _) =
- futures::try_join!(
- payment_attempt_fut,
- shipping_address_fut,
- billing_address_fut,
- connector_response_fut,
- config_update_fut
- )?;
-
- (
- payment_attempt,
- shipping_address,
- billing_address,
- connector_response,
)
- }
- _ => {
- let (mut payment_attempt, shipping_address, billing_address, _) = futures::try_join!(
- payment_attempt_fut,
- shipping_address_fut,
- billing_address_fut,
- config_update_fut
- )?;
-
- let attempt_type = helpers::get_attempt_type(
- &payment_intent,
- &payment_attempt,
- request,
- "confirm",
- )?;
-
- (payment_intent, payment_attempt) = attempt_type
- .modify_payment_intent_and_payment_attempt(
- // 3
- request,
- payment_intent,
- payment_attempt,
- db,
- storage_scheme,
- )
- .await?;
-
- let connector_response = attempt_type
- .get_or_insert_connector_response(&payment_attempt, db, storage_scheme)
- .await?;
+ .await?;
- (
- payment_attempt,
- shipping_address,
- billing_address,
- connector_response,
- )
- }
- };
+ (payment_attempt, shipping_address, billing_address)
+ }
+ };
payment_intent.order_details = request
.get_order_details_as_value()
@@ -354,7 +326,6 @@ impl
payment_intent,
payment_attempt,
currency,
- connector_response,
amount,
email: request.email.clone(),
mandate_id: None,
diff --git a/crates/router/src/core/payments/operations/payment_create.rs b/crates/router/src/core/payments/operations/payment_create.rs
index 909f4d456530..97bb84371306 100644
--- a/crates/router/src/core/payments/operations/payment_create.rs
+++ b/crates/router/src/core/payments/operations/payment_create.rs
@@ -62,7 +62,7 @@ impl
let ephemeral_key = Self::get_ephemeral_key(request, state, merchant_account).await;
let merchant_id = &merchant_account.merchant_id;
let storage_scheme = merchant_account.storage_scheme;
- let (payment_intent, payment_attempt, connector_response);
+ let (payment_intent, payment_attempt);
let money @ (amount, currency) = payments_create_request_validation(request)?;
@@ -196,16 +196,6 @@ impl
payment_id: payment_id.clone(),
})?;
- connector_response = db
- .insert_connector_response(
- Self::make_connector_response(&payment_attempt),
- storage_scheme,
- )
- .await
- .to_duplicate_response(errors::ApiErrorResponse::DuplicatePayment {
- payment_id: payment_id.clone(),
- })?;
-
let mandate_id = request
.mandate_id
.as_ref()
@@ -300,7 +290,6 @@ impl
disputes: vec![],
attempts: None,
force_sync: None,
- connector_response,
sessions_token: vec![],
card_cvc: request.card_cvc.clone(),
creds_identifier,
@@ -727,24 +716,6 @@ impl PaymentCreate {
})
}
- #[instrument(skip_all)]
- pub fn make_connector_response(
- payment_attempt: &PaymentAttempt,
- ) -> storage::ConnectorResponseNew {
- storage::ConnectorResponseNew {
- payment_id: payment_attempt.payment_id.clone(),
- merchant_id: payment_attempt.merchant_id.clone(),
- attempt_id: payment_attempt.attempt_id.clone(),
- created_at: payment_attempt.created_at,
- modified_at: payment_attempt.modified_at,
- connector_name: payment_attempt.connector.clone(),
- connector_transaction_id: None,
- authentication_data: None,
- encoded_data: None,
- updated_by: payment_attempt.updated_by.clone(),
- }
- }
-
#[instrument(skip_all)]
pub async fn get_ephemeral_key(
request: &api::PaymentsRequest,
@@ -813,6 +784,7 @@ async fn create_payment_link(
created_at,
last_modified_at,
fulfilment_time: payment_link_object.link_expiry,
+ custom_merchant_name: payment_link_object.custom_merchant_name,
};
let payment_link_db = db
.insert_payment_link(payment_link_req)
diff --git a/crates/router/src/core/payments/operations/payment_method_validate.rs b/crates/router/src/core/payments/operations/payment_method_validate.rs
index 33f6c23c8363..7e4fe0951b03 100644
--- a/crates/router/src/core/payments/operations/payment_method_validate.rs
+++ b/crates/router/src/core/payments/operations/payment_method_validate.rs
@@ -7,7 +7,7 @@ use error_stack::ResultExt;
use router_derive::PaymentOperation;
use router_env::{instrument, tracing};
-use super::{BoxedOperation, Domain, GetTracker, PaymentCreate, UpdateTracker, ValidateRequest};
+use super::{BoxedOperation, Domain, GetTracker, UpdateTracker, ValidateRequest};
use crate::{
consts,
core::{
@@ -89,7 +89,7 @@ impl
let merchant_id = &merchant_account.merchant_id;
let storage_scheme = merchant_account.storage_scheme;
- let (payment_intent, payment_attempt, connector_response);
+ let (payment_intent, payment_attempt);
let payment_id = payment_id
.get_payment_intent_id()
@@ -135,19 +135,6 @@ impl
}
}?;
- connector_response = match db
- .insert_connector_response(
- PaymentCreate::make_connector_response(&payment_attempt),
- storage_scheme,
- )
- .await
- {
- Ok(connector_resp) => Ok(connector_resp),
- Err(err) => {
- Err(err.change_context(errors::ApiErrorResponse::VerificationFailed { data: None }))
- }
- }?;
-
let creds_identifier = request
.merchant_connector_details
.as_ref()
@@ -180,7 +167,6 @@ impl
mandate_connector: None,
setup_mandate: request.mandate_data.clone().map(Into::into),
token: request.payment_token.clone(),
- connector_response,
payment_method_data: request.payment_method_data.clone(),
confirm: Some(true),
address: types::PaymentAddress::default(),
diff --git a/crates/router/src/core/payments/operations/payment_reject.rs b/crates/router/src/core/payments/operations/payment_reject.rs
index 415ab3eccfe7..a6c2561aaeed 100644
--- a/crates/router/src/core/payments/operations/payment_reject.rs
+++ b/crates/router/src/core/payments/operations/payment_reject.rs
@@ -104,15 +104,6 @@ impl
)
.await?;
- let connector_response = db
- .find_connector_response_by_payment_id_merchant_id_attempt_id(
- &payment_attempt.payment_id,
- &payment_attempt.merchant_id,
- &payment_attempt.attempt_id,
- storage_scheme,
- )
- .await
- .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
let currency = payment_attempt.currency.get_required_value("currency")?;
let amount = payment_attempt.amount.into();
@@ -147,7 +138,7 @@ impl
refunds: vec![],
disputes: vec![],
attempts: None,
- connector_response,
+
sessions_token: vec![],
card_cvc: None,
creds_identifier: None,
diff --git a/crates/router/src/core/payments/operations/payment_response.rs b/crates/router/src/core/payments/operations/payment_response.rs
index 60d3bc165a97..77c344949660 100644
--- a/crates/router/src/core/payments/operations/payment_response.rs
+++ b/crates/router/src/core/payments/operations/payment_response.rs
@@ -296,10 +296,7 @@ async fn payment_response_update_tracker(
router_data: types::RouterData,
storage_scheme: enums::MerchantStorageScheme,
) -> RouterResult> {
- let (capture_update, mut payment_attempt_update, connector_response_update) = match router_data
- .response
- .clone()
- {
+ let (capture_update, mut payment_attempt_update) = match router_data.response.clone() {
Err(err) => {
let (capture_update, attempt_update) = match payment_data.multiple_capture_data {
Some(multiple_capture_data) => {
@@ -356,14 +353,7 @@ async fn payment_response_update_tracker(
)
}
};
- (
- capture_update,
- attempt_update,
- Some(storage::ConnectorResponseUpdate::ErrorUpdate {
- connector_name: Some(router_data.connector.clone()),
- updated_by: storage_scheme.to_string(),
- }),
- )
+ (capture_update, attempt_update)
}
Ok(payments_response) => match payments_response {
types::PaymentsResponseData::PreProcessingResponse {
@@ -394,7 +384,7 @@ async fn payment_response_update_tracker(
updated_by: storage_scheme.to_string(),
};
- (None, Some(payment_attempt_update), None)
+ (None, Some(payment_attempt_update))
}
types::PaymentsResponseData::TransactionResponse {
resource_id,
@@ -409,8 +399,7 @@ async fn payment_response_update_tracker(
| types::ResponseId::EncodedData(id) => Some(id),
};
- let encoded_data = payment_data.connector_response.encoded_data.clone();
- let connector_name = router_data.connector.clone();
+ let encoded_data = payment_data.payment_attempt.encoded_data.clone();
let authentication_data = redirection_data
.map(|data| utils::Encode::::encode_to_value(&data))
@@ -478,23 +467,13 @@ async fn payment_response_update_tracker(
None
},
updated_by: storage_scheme.to_string(),
+ authentication_data,
+ encoded_data,
}),
),
};
- let connector_response_update = storage::ConnectorResponseUpdate::ResponseUpdate {
- connector_transaction_id,
- authentication_data,
- encoded_data,
- connector_name: Some(connector_name),
- updated_by: storage_scheme.to_string(),
- };
-
- (
- capture_updates,
- payment_attempt_update,
- Some(connector_response_update),
- )
+ (capture_updates, payment_attempt_update)
}
types::PaymentsResponseData::TransactionUnresolvedResponse {
resource_id,
@@ -519,14 +498,13 @@ async fn payment_response_update_tracker(
connector_response_reference_id,
updated_by: storage_scheme.to_string(),
}),
- None,
)
}
- types::PaymentsResponseData::SessionResponse { .. } => (None, None, None),
- types::PaymentsResponseData::SessionTokenResponse { .. } => (None, None, None),
- types::PaymentsResponseData::TokenizationResponse { .. } => (None, None, None),
- types::PaymentsResponseData::ConnectorCustomerResponse { .. } => (None, None, None),
- types::PaymentsResponseData::ThreeDSEnrollmentResponse { .. } => (None, None, None),
+ types::PaymentsResponseData::SessionResponse { .. } => (None, None),
+ types::PaymentsResponseData::SessionTokenResponse { .. } => (None, None),
+ types::PaymentsResponseData::TokenizationResponse { .. } => (None, None),
+ types::PaymentsResponseData::ConnectorCustomerResponse { .. } => (None, None),
+ types::PaymentsResponseData::ThreeDSEnrollmentResponse { .. } => (None, None),
types::PaymentsResponseData::MultipleCaptureResponse {
capture_sync_response_list,
} => match payment_data.multiple_capture_data {
@@ -535,13 +513,9 @@ async fn payment_response_update_tracker(
&multiple_capture_data,
capture_sync_response_list,
)?;
- (
- Some((multiple_capture_data, capture_update_list)),
- None,
- None,
- )
+ (Some((multiple_capture_data, capture_update_list)), None)
}
- None => (None, None, None),
+ None => (None, None),
},
},
};
@@ -571,40 +545,18 @@ async fn payment_response_update_tracker(
// Stage 1
let payment_attempt = payment_data.payment_attempt.clone();
- let connector_response = payment_data.connector_response.clone();
-
- let payment_attempt_fut = Box::pin(async move {
- Ok::<_, error_stack::Report>(match payment_attempt_update {
- Some(payment_attempt_update) => db
- .update_payment_attempt_with_attempt_id(
- payment_attempt,
- payment_attempt_update,
- storage_scheme,
- )
- .await
- .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?,
- None => payment_attempt,
- })
- });
-
- let connector_response_fut = Box::pin(async move {
- Ok::<_, error_stack::Report>(match connector_response_update {
- Some(connector_response_update) => db
- .update_connector_response(
- connector_response,
- connector_response_update,
- storage_scheme,
- )
- .await
- .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?,
- None => connector_response,
- })
- });
-
- let (payment_attempt, connector_response) =
- futures::try_join!(payment_attempt_fut, connector_response_fut)?;
- payment_data.payment_attempt = payment_attempt;
- payment_data.connector_response = connector_response;
+
+ payment_data.payment_attempt = match payment_attempt_update {
+ Some(payment_attempt_update) => db
+ .update_payment_attempt_with_attempt_id(
+ payment_attempt,
+ payment_attempt_update,
+ storage_scheme,
+ )
+ .await
+ .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?,
+ None => payment_attempt,
+ };
let amount_captured = get_total_amount_captured(
router_data.request,
diff --git a/crates/router/src/core/payments/operations/payment_session.rs b/crates/router/src/core/payments/operations/payment_session.rs
index 354c62648bb3..52677ab3cc8d 100644
--- a/crates/router/src/core/payments/operations/payment_session.rs
+++ b/crates/router/src/core/payments/operations/payment_session.rs
@@ -126,20 +126,6 @@ impl
payment_intent.shipping_address_id = shipping_address.clone().map(|x| x.address_id);
payment_intent.billing_address_id = billing_address.clone().map(|x| x.address_id);
- let connector_response = db
- .find_connector_response_by_payment_id_merchant_id_attempt_id(
- &payment_intent.payment_id,
- &payment_intent.merchant_id,
- &payment_attempt.attempt_id,
- storage_scheme,
- )
- .await
- .map_err(|error| {
- error
- .change_context(errors::ApiErrorResponse::InternalServerError)
- .attach_printable("Database error when finding connector response")
- })?;
-
let customer_details = payments::CustomerDetails {
customer_id: payment_intent.customer_id.clone(),
name: None,
@@ -190,7 +176,6 @@ impl
disputes: vec![],
attempts: None,
sessions_token: vec![],
- connector_response,
card_cvc: None,
creds_identifier,
pm_token: None,
diff --git a/crates/router/src/core/payments/operations/payment_start.rs b/crates/router/src/core/payments/operations/payment_start.rs
index e9fa301bf07b..5578f6b3dc15 100644
--- a/crates/router/src/core/payments/operations/payment_start.rs
+++ b/crates/router/src/core/payments/operations/payment_start.rs
@@ -126,20 +126,6 @@ impl
..CustomerDetails::default()
};
- let connector_response = db
- .find_connector_response_by_payment_id_merchant_id_attempt_id(
- &payment_intent.payment_id,
- &payment_intent.merchant_id,
- &payment_attempt.attempt_id,
- storage_scheme,
- )
- .await
- .map_err(|error| {
- error
- .change_context(errors::ApiErrorResponse::InternalServerError)
- .attach_printable("Database error when finding connector response")
- })?;
-
Ok((
Box::new(self),
PaymentData {
@@ -150,7 +136,6 @@ impl
email: None,
mandate_id: None,
mandate_connector: None,
- connector_response,
setup_mandate: None,
token: payment_attempt.payment_token.clone(),
address: PaymentAddress {
diff --git a/crates/router/src/core/payments/operations/payment_status.rs b/crates/router/src/core/payments/operations/payment_status.rs
index 96aac6c9d79b..83e7131b2675 100644
--- a/crates/router/src/core/payments/operations/payment_status.rs
+++ b/crates/router/src/core/payments/operations/payment_status.rs
@@ -226,7 +226,7 @@ async fn get_tracker_for_sync<
PaymentData,
Option,
)> {
- let (payment_intent, payment_attempt, currency, amount);
+ let (payment_intent, mut payment_attempt, currency, amount);
(payment_intent, payment_attempt) = get_payment_intent_payment_attempt(
db,
@@ -250,18 +250,7 @@ async fn get_tracker_for_sync<
let payment_id_str = payment_attempt.payment_id.clone();
- let mut connector_response = db
- .find_connector_response_by_payment_id_merchant_id_attempt_id(
- &payment_intent.payment_id,
- &payment_intent.merchant_id,
- &payment_attempt.attempt_id,
- storage_scheme,
- )
- .await
- .change_context(errors::ApiErrorResponse::PaymentNotFound)
- .attach_printable("Database error when finding connector response")?;
-
- connector_response.encoded_data = request.param.clone();
+ payment_attempt.encoded_data = request.param.clone();
currency = payment_attempt.currency.get_required_value("currency")?;
amount = payment_attempt.amount.into();
@@ -349,7 +338,7 @@ async fn get_tracker_for_sync<
format!("Error while retrieving frm_response, merchant_id: {}, payment_id: {payment_id_str}", &merchant_account.merchant_id)
});
- let contains_encoded_data = connector_response.encoded_data.is_some();
+ let contains_encoded_data = payment_attempt.encoded_data.is_some();
let creds_identifier = request
.merchant_connector_details
@@ -373,7 +362,6 @@ async fn get_tracker_for_sync<
PaymentData {
flow: PhantomData,
payment_intent,
- connector_response,
currency,
amount,
email: None,
diff --git a/crates/router/src/core/payments/operations/payment_update.rs b/crates/router/src/core/payments/operations/payment_update.rs
index 622d09754396..0a49c830b732 100644
--- a/crates/router/src/core/payments/operations/payment_update.rs
+++ b/crates/router/src/core/payments/operations/payment_update.rs
@@ -219,20 +219,6 @@ impl
)?;
}
- let connector_response = db
- .find_connector_response_by_payment_id_merchant_id_attempt_id(
- &payment_intent.payment_id,
- &payment_intent.merchant_id,
- &payment_attempt.attempt_id,
- storage_scheme,
- )
- .await
- .map_err(|error| {
- error
- .change_context(errors::ApiErrorResponse::InternalServerError)
- .attach_printable("Database error when finding connector response")
- })?;
-
let mandate_id = request
.mandate_id
.as_ref()
@@ -341,7 +327,6 @@ impl
refunds: vec![],
disputes: vec![],
attempts: None,
- connector_response,
sessions_token: vec![],
card_cvc: request.card_cvc.clone(),
creds_identifier,
diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs
index c62529826387..6c6b4ae9339f 100644
--- a/crates/router/src/core/payments/transformers.rs
+++ b/crates/router/src/core/payments/transformers.rs
@@ -460,14 +460,8 @@ where
let output = Ok(match payment_request {
Some(_request) => {
- if payments::is_start_pay(&operation)
- && payment_data
- .connector_response
- .authentication_data
- .is_some()
- {
- let redirection_data = payment_data
- .connector_response
+ if payments::is_start_pay(&operation) && payment_attempt.authentication_data.is_some() {
+ let redirection_data = payment_attempt
.authentication_data
.get_required_value("redirection_data")?;
@@ -523,16 +517,15 @@ where
display_to_timestamp: wait_screen_data.display_to_timestamp,
}
}))
- .or(payment_data
- .connector_response
- .authentication_data
- .map(|_| api_models::payments::NextActionData::RedirectToUrl {
+ .or(payment_attempt.authentication_data.as_ref().map(|_| {
+ api_models::payments::NextActionData::RedirectToUrl {
redirect_to_url: helpers::create_startpay_url(
server,
&payment_attempt,
&payment_intent,
),
- }));
+ }
+ }));
};
// next action check for third party sdk session (for ex: Apple pay through trustpay has third party sdk session response)
@@ -1056,7 +1049,7 @@ impl TryFrom> for types::PaymentsSyncData
}
None => types::ResponseId::NoResponseId,
},
- encoded_data: payment_data.connector_response.encoded_data,
+ encoded_data: payment_data.payment_attempt.encoded_data,
capture_method: payment_data.payment_attempt.capture_method,
connector_meta: payment_data.payment_attempt.connector_metadata,
sync_type: match payment_data.multiple_capture_data {
@@ -1356,7 +1349,7 @@ impl TryFrom> for types::CompleteAuthoriz
browser_info,
email: payment_data.email,
payment_method_data: payment_data.payment_method_data,
- connector_transaction_id: payment_data.connector_response.connector_transaction_id,
+ connector_transaction_id: payment_data.payment_attempt.connector_transaction_id,
redirect_response,
connector_meta: payment_data.payment_attempt.connector_metadata,
})
diff --git a/crates/router/src/db.rs b/crates/router/src/db.rs
index 3efef2c40f29..6fe34d8dd69b 100644
--- a/crates/router/src/db.rs
+++ b/crates/router/src/db.rs
@@ -5,7 +5,6 @@ pub mod cache;
pub mod capture;
pub mod cards_info;
pub mod configs;
-pub mod connector_response;
pub mod customers;
pub mod dispute;
pub mod ephemeral_key;
@@ -52,7 +51,6 @@ pub trait StorageInterface:
+ api_keys::ApiKeyInterface
+ configs::ConfigInterface
+ capture::CaptureInterface
- + connector_response::ConnectorResponseInterface
+ customers::CustomerInterface
+ dispute::DisputeInterface
+ ephemeral_key::EphemeralKeyInterface
diff --git a/crates/router/src/db/connector_response.rs b/crates/router/src/db/connector_response.rs
deleted file mode 100644
index 354231d136ec..000000000000
--- a/crates/router/src/db/connector_response.rs
+++ /dev/null
@@ -1,343 +0,0 @@
-use error_stack::{IntoReport, ResultExt};
-use router_env::{instrument, tracing};
-
-use super::{MockDb, Store};
-use crate::{
- core::errors::{self, CustomResult},
- types::storage::{self as storage_type, enums},
-};
-
-#[async_trait::async_trait]
-pub trait ConnectorResponseInterface {
- async fn insert_connector_response(
- &self,
- connector_response: storage_type::ConnectorResponseNew,
- storage_scheme: enums::MerchantStorageScheme,
- ) -> CustomResult;
-
- async fn find_connector_response_by_payment_id_merchant_id_attempt_id(
- &self,
- payment_id: &str,
- merchant_id: &str,
- attempt_id: &str,
- storage_scheme: enums::MerchantStorageScheme,
- ) -> CustomResult;
-
- async fn update_connector_response(
- &self,
- this: storage_type::ConnectorResponse,
- payment_attempt: storage_type::ConnectorResponseUpdate,
- storage_scheme: enums::MerchantStorageScheme,
- ) -> CustomResult;
-}
-
-#[cfg(not(feature = "kv_store"))]
-mod storage {
- use error_stack::IntoReport;
- use router_env::{instrument, tracing};
-
- use super::Store;
- use crate::{
- connection,
- core::errors::{self, CustomResult},
- types::storage::{self as storage_type, enums},
- };
-
- #[async_trait::async_trait]
- impl super::ConnectorResponseInterface for Store {
- #[instrument(skip_all)]
- async fn insert_connector_response(
- &self,
- connector_response: storage_type::ConnectorResponseNew,
- _storage_scheme: enums::MerchantStorageScheme,
- ) -> CustomResult {
- let conn = connection::pg_connection_write(self).await?;
- connector_response
- .insert(&conn)
- .await
- .map_err(Into::into)
- .into_report()
- }
-
- #[instrument(skip_all)]
- async fn find_connector_response_by_payment_id_merchant_id_attempt_id(
- &self,
- payment_id: &str,
- merchant_id: &str,
- attempt_id: &str,
- _storage_scheme: enums::MerchantStorageScheme,
- ) -> CustomResult {
- let conn = connection::pg_connection_read(self).await?;
- storage_type::ConnectorResponse::find_by_payment_id_merchant_id_attempt_id(
- &conn,
- payment_id,
- merchant_id,
- attempt_id,
- )
- .await
- .map_err(Into::into)
- .into_report()
- }
-
- async fn update_connector_response(
- &self,
- this: storage_type::ConnectorResponse,
- connector_response_update: storage_type::ConnectorResponseUpdate,
- _storage_scheme: enums::MerchantStorageScheme,
- ) -> CustomResult {
- let conn = connection::pg_connection_write(self).await?;
- this.update(&conn, connector_response_update)
- .await
- .map_err(Into::into)
- .into_report()
- }
- }
-}
-
-#[cfg(feature = "kv_store")]
-mod storage {
-
- use diesel_models::enums as storage_enums;
- use error_stack::{IntoReport, ResultExt};
- use redis_interface::HsetnxReply;
- use router_env::{instrument, tracing};
- use storage_impl::redis::kv_store::{kv_wrapper, KvOperation};
-
- use super::Store;
- use crate::{
- connection,
- core::errors::{self, CustomResult},
- types::storage::{self as storage_type, enums, kv},
- utils::db_utils,
- };
-
- #[async_trait::async_trait]
- impl super::ConnectorResponseInterface for Store {
- #[instrument(skip_all)]
- async fn insert_connector_response(
- &self,
- connector_response: storage_type::ConnectorResponseNew,
- storage_scheme: enums::MerchantStorageScheme,
- ) -> CustomResult {
- let conn = connection::pg_connection_write(self).await?;
-
- match storage_scheme {
- storage_enums::MerchantStorageScheme::PostgresOnly => connector_response
- .insert(&conn)
- .await
- .map_err(Into::into)
- .into_report(),
- storage_enums::MerchantStorageScheme::RedisKv => {
- let merchant_id = &connector_response.merchant_id;
- let payment_id = &connector_response.payment_id;
- let attempt_id = &connector_response.attempt_id;
-
- let key = format!("mid_{merchant_id}_pid_{payment_id}");
- let field = format!("connector_resp_{merchant_id}_{payment_id}_{attempt_id}");
-
- let created_connector_resp = storage_type::ConnectorResponse {
- id: Default::default(),
- payment_id: connector_response.payment_id.clone(),
- merchant_id: connector_response.merchant_id.clone(),
- attempt_id: connector_response.attempt_id.clone(),
- created_at: connector_response.created_at,
- modified_at: connector_response.modified_at,
- connector_name: connector_response.connector_name.clone(),
- connector_transaction_id: connector_response
- .connector_transaction_id
- .clone(),
- authentication_data: connector_response.authentication_data.clone(),
- encoded_data: connector_response.encoded_data.clone(),
- updated_by: storage_scheme.to_string(),
- };
-
- let redis_entry = kv::TypedSql {
- op: kv::DBOperation::Insert {
- insertable: kv::Insertable::ConnectorResponse(
- connector_response.clone(),
- ),
- },
- };
-
- match kv_wrapper::(
- self,
- KvOperation::HSetNx(&field, &created_connector_resp, redis_entry),
- &key,
- )
- .await
- .change_context(errors::StorageError::KVError)?
- .try_into_hsetnx()
- {
- Ok(HsetnxReply::KeyNotSet) => Err(errors::StorageError::DuplicateValue {
- entity: "address",
- key: Some(key),
- })
- .into_report(),
- Ok(HsetnxReply::KeySet) => Ok(created_connector_resp),
- Err(er) => Err(er).change_context(errors::StorageError::KVError),
- }
- }
- }
- }
-
- #[instrument(skip_all)]
- async fn find_connector_response_by_payment_id_merchant_id_attempt_id(
- &self,
- payment_id: &str,
- merchant_id: &str,
- attempt_id: &str,
- storage_scheme: enums::MerchantStorageScheme,
- ) -> CustomResult {
- let conn = connection::pg_connection_read(self).await?;
- let database_call = || async {
- storage_type::ConnectorResponse::find_by_payment_id_merchant_id_attempt_id(
- &conn,
- payment_id,
- merchant_id,
- attempt_id,
- )
- .await
- .map_err(Into::into)
- .into_report()
- };
- match storage_scheme {
- storage_enums::MerchantStorageScheme::PostgresOnly => database_call().await,
- storage_enums::MerchantStorageScheme::RedisKv => {
- let key = format!("mid_{merchant_id}_pid_{payment_id}");
- let field = format!("connector_resp_{merchant_id}_{payment_id}_{attempt_id}");
-
- db_utils::try_redis_get_else_try_database_get(
- async {
- kv_wrapper(
- self,
- KvOperation::::HGet(&field),
- key,
- )
- .await?
- .try_into_hget()
- },
- database_call,
- )
- .await
- }
- }
- }
-
- async fn update_connector_response(
- &self,
- this: storage_type::ConnectorResponse,
- connector_response_update: storage_type::ConnectorResponseUpdate,
- storage_scheme: enums::MerchantStorageScheme,
- ) -> CustomResult {
- let conn = connection::pg_connection_write(self).await?;
- match storage_scheme {
- storage_enums::MerchantStorageScheme::PostgresOnly => this
- .update(&conn, connector_response_update)
- .await
- .map_err(Into::into)
- .into_report(),
- storage_enums::MerchantStorageScheme::RedisKv => {
- let key = format!("mid_{}_pid_{}", this.merchant_id, this.payment_id);
- let updated_connector_response = connector_response_update
- .clone()
- .apply_changeset(this.clone());
- let redis_value = serde_json::to_string(&updated_connector_response)
- .into_report()
- .change_context(errors::StorageError::KVError)?;
- let field = format!(
- "connector_resp_{}_{}_{}",
- &updated_connector_response.merchant_id,
- &updated_connector_response.payment_id,
- &updated_connector_response.attempt_id
- );
-
- let redis_entry = kv::TypedSql {
- op: kv::DBOperation::Update {
- updatable: kv::Updateable::ConnectorResponseUpdate(
- kv::ConnectorResponseUpdateMems {
- orig: this,
- update_data: connector_response_update,
- },
- ),
- },
- };
-
- kv_wrapper::<(), _, _>(
- self,
- KvOperation::Hset::(
- (&field, redis_value),
- redis_entry,
- ),
- &key,
- )
- .await
- .change_context(errors::StorageError::KVError)?
- .try_into_hset()
- .change_context(errors::StorageError::KVError)?;
-
- Ok(updated_connector_response)
- }
- }
- }
- }
-}
-
-#[async_trait::async_trait]
-impl ConnectorResponseInterface for MockDb {
- #[instrument(skip_all)]
- async fn insert_connector_response(
- &self,
- new: storage_type::ConnectorResponseNew,
- storage_scheme: enums::MerchantStorageScheme,
- ) -> CustomResult {
- let mut connector_response = self.connector_response.lock().await;
- let response = storage_type::ConnectorResponse {
- id: connector_response
- .len()
- .try_into()
- .into_report()
- .change_context(errors::StorageError::MockDbError)?,
- payment_id: new.payment_id,
- merchant_id: new.merchant_id,
- attempt_id: new.attempt_id,
- created_at: new.created_at,
- modified_at: new.modified_at,
- connector_name: new.connector_name,
- connector_transaction_id: new.connector_transaction_id,
- authentication_data: new.authentication_data,
- encoded_data: new.encoded_data,
- updated_by: storage_scheme.to_string(),
- };
- connector_response.push(response.clone());
- Ok(response)
- }
-
- #[instrument(skip_all)]
- async fn find_connector_response_by_payment_id_merchant_id_attempt_id(
- &self,
- _payment_id: &str,
- _merchant_id: &str,
- _attempt_id: &str,
- _storage_scheme: enums::MerchantStorageScheme,
- ) -> CustomResult {
- // [#172]: Implement function for `MockDb`
- Err(errors::StorageError::MockDbError)?
- }
-
- // safety: interface only used for testing
- #[allow(clippy::unwrap_used)]
- async fn update_connector_response(
- &self,
- this: storage_type::ConnectorResponse,
- connector_response_update: storage_type::ConnectorResponseUpdate,
- _storage_scheme: enums::MerchantStorageScheme,
- ) -> CustomResult {
- let mut connector_response = self.connector_response.lock().await;
- let response = connector_response
- .iter_mut()
- .find(|item| item.id == this.id)
- .unwrap();
- *response = connector_response_update.apply_changeset(response.clone());
- Ok(response.clone())
- }
-}
diff --git a/crates/router/src/lib.rs b/crates/router/src/lib.rs
index 21ebfc06137b..38efe8b75134 100644
--- a/crates/router/src/lib.rs
+++ b/crates/router/src/lib.rs
@@ -142,6 +142,7 @@ pub fn mk_app(
.service(routes::Files::server(state.clone()))
.service(routes::Disputes::server(state.clone()))
.service(routes::Routing::server(state.clone()))
+ .service(routes::Gsm::server(state.clone()))
}
#[cfg(all(feature = "olap", feature = "kms"))]
diff --git a/crates/router/src/routes.rs b/crates/router/src/routes.rs
index 38f95c4cdda8..47b9f23cf8cb 100644
--- a/crates/router/src/routes.rs
+++ b/crates/router/src/routes.rs
@@ -10,6 +10,7 @@ pub mod disputes;
pub mod dummy_connector;
pub mod ephemeral_key;
pub mod files;
+pub mod gsm;
pub mod health;
pub mod lock_utils;
pub mod mandates;
@@ -36,7 +37,7 @@ pub use self::app::Routing;
pub use self::app::Verify;
pub use self::app::{
ApiKeys, AppState, BusinessProfile, Cache, Cards, Configs, Customers, Disputes, EphemeralKey,
- Files, Health, Mandates, MerchantAccount, MerchantConnectorAccount, PaymentLink,
+ Files, Gsm, Health, Mandates, MerchantAccount, MerchantConnectorAccount, PaymentLink,
PaymentMethods, Payments, Refunds, Webhooks,
};
#[cfg(feature = "stripe")]
diff --git a/crates/router/src/routes/app.rs b/crates/router/src/routes/app.rs
index 8dbc440aa7de..0b97df1e7fc3 100644
--- a/crates/router/src/routes/app.rs
+++ b/crates/router/src/routes/app.rs
@@ -19,7 +19,7 @@ use super::routing as cloud_routing;
#[cfg(all(feature = "olap", feature = "kms"))]
use super::verification::{apple_pay_merchant_registration, retrieve_apple_pay_verified_domains};
#[cfg(feature = "olap")]
-use super::{admin::*, api_keys::*, disputes::*, files::*};
+use super::{admin::*, api_keys::*, disputes::*, files::*, gsm::*};
use super::{cache::*, health::*, payment_link::*};
#[cfg(any(feature = "olap", feature = "oltp"))]
use super::{configs::*, customers::*, mandates::*, payments::*, refunds::*};
@@ -676,6 +676,20 @@ impl BusinessProfile {
}
}
+pub struct Gsm;
+
+#[cfg(feature = "olap")]
+impl Gsm {
+ pub fn server(state: AppState) -> Scope {
+ web::scope("/gsm")
+ .app_data(web::Data::new(state))
+ .service(web::resource("").route(web::post().to(create_gsm_rule)))
+ .service(web::resource("/get").route(web::post().to(get_gsm_rule)))
+ .service(web::resource("/update").route(web::post().to(update_gsm_rule)))
+ .service(web::resource("/delete").route(web::post().to(delete_gsm_rule)))
+ }
+}
+
#[cfg(all(feature = "olap", feature = "kms"))]
pub struct Verify;
diff --git a/crates/router/src/routes/gsm.rs b/crates/router/src/routes/gsm.rs
new file mode 100644
index 000000000000..02d943792dba
--- /dev/null
+++ b/crates/router/src/routes/gsm.rs
@@ -0,0 +1,93 @@
+use actix_web::{web, HttpRequest, Responder};
+use api_models::gsm as gsm_api_types;
+use router_env::{instrument, tracing, Flow};
+
+use super::app::AppState;
+use crate::{
+ core::{api_locking, gsm},
+ services::{api, authentication as auth},
+};
+
+#[instrument(skip_all, fields(flow = ?Flow::GsmRuleCreate))]
+pub async fn create_gsm_rule(
+ state: web::Data,
+ req: HttpRequest,
+ json_payload: web::Json,
+) -> impl Responder {
+ let payload = json_payload.into_inner();
+
+ let flow = Flow::GsmRuleCreate;
+ Box::pin(api::server_wrap(
+ flow,
+ state.clone(),
+ &req,
+ payload,
+ |state, _, payload| gsm::create_gsm_rule(state, payload),
+ &auth::AdminApiAuth,
+ api_locking::LockAction::NotApplicable,
+ ))
+ .await
+}
+
+#[instrument(skip_all, fields(flow = ?Flow::GsmRuleRetrieve))]
+pub async fn get_gsm_rule(
+ state: web::Data,
+ req: HttpRequest,
+ json_payload: web::Json,
+) -> impl Responder {
+ let gsm_retrieve_req = json_payload.into_inner();
+ let flow = Flow::GsmRuleRetrieve;
+ Box::pin(api::server_wrap(
+ flow,
+ state.clone(),
+ &req,
+ gsm_retrieve_req,
+ |state, _, gsm_retrieve_req| gsm::retrieve_gsm_rule(state, gsm_retrieve_req),
+ &auth::AdminApiAuth,
+ api_locking::LockAction::NotApplicable,
+ ))
+ .await
+}
+
+#[instrument(skip_all, fields(flow = ?Flow::GsmRuleUpdate))]
+pub async fn update_gsm_rule(
+ state: web::Data,
+ req: HttpRequest,
+ json_payload: web::Json,
+) -> impl Responder {
+ let payload = json_payload.into_inner();
+
+ let flow = Flow::GsmRuleUpdate;
+ Box::pin(api::server_wrap(
+ flow,
+ state.clone(),
+ &req,
+ payload,
+ |state, _, payload| gsm::update_gsm_rule(state, payload),
+ &auth::AdminApiAuth,
+ api_locking::LockAction::NotApplicable,
+ ))
+ .await
+}
+
+#[instrument(skip_all, fields(flow = ?Flow::GsmRuleDelete))]
+pub async fn delete_gsm_rule(
+ state: web::Data,
+ req: HttpRequest,
+ json_payload: web::Json,
+) -> impl Responder {
+ let payload = json_payload.into_inner();
+
+ let flow = Flow::GsmRuleDelete;
+
+ Box::pin(api::server_wrap(
+ flow,
+ state,
+ &req,
+ payload,
+ |state, _, payload| gsm::delete_gsm_rule(state, payload),
+ &auth::AdminApiAuth,
+ api_locking::LockAction::NotApplicable,
+ ))
+ .await
+}
diff --git a/crates/router/src/routes/lock_utils.rs b/crates/router/src/routes/lock_utils.rs
index 14614268d79d..4e6fc1870f56 100644
--- a/crates/router/src/routes/lock_utils.rs
+++ b/crates/router/src/routes/lock_utils.rs
@@ -23,6 +23,7 @@ pub enum ApiIdentifier {
ApiKeys,
PaymentLink,
Routing,
+ Gsm,
}
impl From for ApiIdentifier {
@@ -129,6 +130,10 @@ impl From for ApiIdentifier {
Flow::Verification => Self::Verification,
Flow::PaymentLinkInitiate | Flow::PaymentLinkRetrieve => Self::PaymentLink,
+ Flow::GsmRuleCreate
+ | Flow::GsmRuleRetrieve
+ | Flow::GsmRuleUpdate
+ | Flow::GsmRuleDelete => Self::Gsm,
}
}
}
diff --git a/crates/router/src/types.rs b/crates/router/src/types.rs
index 8f08ce062560..f2e86a4bf335 100644
--- a/crates/router/src/types.rs
+++ b/crates/router/src/types.rs
@@ -1193,3 +1193,5 @@ impl
}
}
}
+
+pub type GsmResponse = storage::GatewayStatusMap;
diff --git a/crates/router/src/types/storage.rs b/crates/router/src/types/storage.rs
index 1e7c34a420b1..c63ff5fb7f86 100644
--- a/crates/router/src/types/storage.rs
+++ b/crates/router/src/types/storage.rs
@@ -4,7 +4,6 @@ pub mod business_profile;
pub mod capture;
pub mod cards_info;
pub mod configs;
-pub mod connector_response;
pub mod customers;
pub mod dispute;
pub mod enums;
@@ -41,11 +40,11 @@ pub use data_models::payments::{
};
pub use self::{
- address::*, api_keys::*, capture::*, cards_info::*, configs::*, connector_response::*,
- customers::*, dispute::*, ephemeral_key::*, events::*, file::*, gsm::*, locker_mock_up::*,
- mandate::*, merchant_account::*, merchant_connector_account::*, merchant_key_store::*,
- payment_link::*, payment_method::*, payout_attempt::*, payouts::*, process_tracker::*,
- refund::*, reverse_lookup::*, routing_algorithm::*,
+ address::*, api_keys::*, capture::*, cards_info::*, configs::*, customers::*, dispute::*,
+ ephemeral_key::*, events::*, file::*, gsm::*, locker_mock_up::*, mandate::*,
+ merchant_account::*, merchant_connector_account::*, merchant_key_store::*, payment_link::*,
+ payment_method::*, payout_attempt::*, payouts::*, process_tracker::*, refund::*,
+ reverse_lookup::*, routing_algorithm::*,
};
use crate::types::api::routing;
diff --git a/crates/router/src/types/storage/connector_response.rs b/crates/router/src/types/storage/connector_response.rs
deleted file mode 100644
index c93c231e3d1c..000000000000
--- a/crates/router/src/types/storage/connector_response.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-pub use diesel_models::{
- connector_response::{
- ConnectorResponse, ConnectorResponseNew, ConnectorResponseUpdate,
- ConnectorResponseUpdateInternal,
- },
- enums::MerchantStorageScheme,
-};
-
-pub trait ConnectorResponseExt {
- fn make_new_connector_response(
- payment_id: String,
- merchant_id: String,
- attempt_id: String,
- connector: Option,
- storage_scheme: String,
- ) -> ConnectorResponseNew;
-}
-
-impl ConnectorResponseExt for ConnectorResponse {
- fn make_new_connector_response(
- payment_id: String,
- merchant_id: String,
- attempt_id: String,
- connector: Option,
- storage_scheme: String,
- ) -> ConnectorResponseNew {
- let now = common_utils::date_time::now();
- ConnectorResponseNew {
- payment_id,
- merchant_id,
- attempt_id,
- created_at: now,
- modified_at: now,
- connector_name: connector,
- connector_transaction_id: None,
- authentication_data: None,
- encoded_data: None,
- updated_by: storage_scheme,
- }
- }
-}
diff --git a/crates/router/src/types/storage/kv.rs b/crates/router/src/types/storage/kv.rs
index 2afc73e6637d..6bb6c38e7b26 100644
--- a/crates/router/src/types/storage/kv.rs
+++ b/crates/router/src/types/storage/kv.rs
@@ -1,4 +1,4 @@
pub use diesel_models::kv::{
- AddressUpdateMems, ConnectorResponseUpdateMems, DBOperation, Insertable,
- PaymentAttemptUpdateMems, PaymentIntentUpdateMems, RefundUpdateMems, TypedSql, Updateable,
+ AddressUpdateMems, DBOperation, Insertable, PaymentAttemptUpdateMems, PaymentIntentUpdateMems,
+ RefundUpdateMems, TypedSql, Updateable,
};
diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs
index 83ca0d014dc8..1cd016de18e6 100644
--- a/crates/router/src/types/transformers.rs
+++ b/crates/router/src/types/transformers.rs
@@ -1,6 +1,6 @@
// use actix_web::HttpMessage;
use actix_web::http::header::HeaderMap;
-use api_models::{enums as api_enums, payments, routing::ConnectorSelection};
+use api_models::{enums as api_enums, gsm as gsm_api_types, payments, routing::ConnectorSelection};
use common_utils::{
consts::X_HS_LATENCY,
crypto::Encryptable,
@@ -1031,3 +1031,19 @@ impl ForeignFrom
}
}
}
+
+impl ForeignFrom for storage::GatewayStatusMappingNew {
+ fn foreign_from(value: gsm_api_types::GsmCreateRequest) -> Self {
+ Self {
+ connector: value.connector.to_string(),
+ flow: value.flow,
+ sub_flow: value.sub_flow,
+ code: value.code,
+ message: value.message,
+ decision: value.decision.to_string(),
+ status: value.status,
+ router_error: value.router_error,
+ step_up_possible: value.step_up_possible,
+ }
+ }
+}
diff --git a/crates/router_env/src/logger/types.rs b/crates/router_env/src/logger/types.rs
index 9822432115b0..0c9751aee440 100644
--- a/crates/router_env/src/logger/types.rs
+++ b/crates/router_env/src/logger/types.rs
@@ -235,6 +235,14 @@ pub enum Flow {
BusinessProfileList,
/// Different verification flows
Verification,
+ /// Gsm Rule Creation flow
+ GsmRuleCreate,
+ /// Gsm Rule Retrieve flow
+ GsmRuleRetrieve,
+ /// Gsm Rule Update flow
+ GsmRuleUpdate,
+ /// Gsm Rule Delete flow
+ GsmRuleDelete,
}
///
diff --git a/crates/storage_impl/src/connector_response.rs b/crates/storage_impl/src/connector_response.rs
deleted file mode 100644
index 7d4ff6df94d9..000000000000
--- a/crates/storage_impl/src/connector_response.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-use diesel_models::connector_response::ConnectorResponse;
-
-use crate::redis::kv_store::KvStorePartition;
-
-impl KvStorePartition for ConnectorResponse {}
diff --git a/crates/storage_impl/src/lib.rs b/crates/storage_impl/src/lib.rs
index cef4a8981a43..00d8703940c7 100644
--- a/crates/storage_impl/src/lib.rs
+++ b/crates/storage_impl/src/lib.rs
@@ -8,7 +8,6 @@ use redis::{kv_store::RedisConnInterface, RedisStore};
mod address;
pub mod config;
pub mod connection;
-mod connector_response;
pub mod database;
pub mod errors;
mod lookup;
diff --git a/crates/storage_impl/src/mock_db.rs b/crates/storage_impl/src/mock_db.rs
index 76bdb1160ccc..33f3f7a77f27 100644
--- a/crates/storage_impl/src/mock_db.rs
+++ b/crates/storage_impl/src/mock_db.rs
@@ -27,7 +27,6 @@ pub struct MockDb {
pub customers: Arc>>,
pub refunds: Arc>>,
pub processes: Arc>>,
- pub connector_response: Arc>>,
pub redis: Arc,
pub api_keys: Arc>>,
pub ephemeral_keys: Arc>>,
@@ -57,7 +56,6 @@ impl MockDb {
customers: Default::default(),
refunds: Default::default(),
processes: Default::default(),
- connector_response: Default::default(),
redis: Arc::new(
RedisStore::new(redis)
.await
diff --git a/crates/storage_impl/src/payments/payment_attempt.rs b/crates/storage_impl/src/payments/payment_attempt.rs
index e3047221b6f5..21002917df83 100644
--- a/crates/storage_impl/src/payments/payment_attempt.rs
+++ b/crates/storage_impl/src/payments/payment_attempt.rs
@@ -1062,7 +1062,6 @@ impl DataModelExt for PaymentAttemptNew {
connector_response_reference_id: self.connector_response_reference_id,
multiple_capture_count: self.multiple_capture_count,
amount_capturable: self.amount_capturable,
-
updated_by: self.updated_by,
authentication_data: self.authentication_data,
encoded_data: self.encoded_data,
@@ -1244,6 +1243,8 @@ impl DataModelExt for PaymentAttemptUpdate {
connector_response_reference_id,
amount_capturable,
updated_by,
+ authentication_data,
+ encoded_data,
} => DieselPaymentAttemptUpdate::ResponseUpdate {
status,
connector,
@@ -1259,6 +1260,8 @@ impl DataModelExt for PaymentAttemptUpdate {
connector_response_reference_id,
amount_capturable,
updated_by,
+ authentication_data,
+ encoded_data,
},
Self::UnresolvedResponseUpdate {
status,
@@ -1481,6 +1484,8 @@ impl DataModelExt for PaymentAttemptUpdate {
connector_response_reference_id,
amount_capturable,
updated_by,
+ authentication_data,
+ encoded_data,
} => Self::ResponseUpdate {
status,
connector,
@@ -1496,6 +1501,8 @@ impl DataModelExt for PaymentAttemptUpdate {
connector_response_reference_id,
amount_capturable,
updated_by,
+ authentication_data,
+ encoded_data,
},
DieselPaymentAttemptUpdate::UnresolvedResponseUpdate {
status,
diff --git a/migrations/2023-10-25-070909_add_merchant_custom_name_payment_link/down.sql b/migrations/2023-10-25-070909_add_merchant_custom_name_payment_link/down.sql
new file mode 100644
index 000000000000..84f009021df8
--- /dev/null
+++ b/migrations/2023-10-25-070909_add_merchant_custom_name_payment_link/down.sql
@@ -0,0 +1,2 @@
+-- This file should undo anything in `up.sql`
+ALTER TABLE payment_link DROP COLUMN custom_merchant_name;
diff --git a/migrations/2023-10-25-070909_add_merchant_custom_name_payment_link/up.sql b/migrations/2023-10-25-070909_add_merchant_custom_name_payment_link/up.sql
new file mode 100644
index 000000000000..c4fa756e57a0
--- /dev/null
+++ b/migrations/2023-10-25-070909_add_merchant_custom_name_payment_link/up.sql
@@ -0,0 +1,2 @@
+-- Your SQL goes here
+ALTER TABLE payment_link ADD COLUMN custom_merchant_name VARCHAR(64);
\ No newline at end of file
diff --git a/migrations/2023-11-08-144951_drop_connector_response_table/down.sql b/migrations/2023-11-08-144951_drop_connector_response_table/down.sql
new file mode 100644
index 000000000000..ff9ca4e4f9c7
--- /dev/null
+++ b/migrations/2023-11-08-144951_drop_connector_response_table/down.sql
@@ -0,0 +1,34 @@
+-- This file should undo anything in `up.sql`
+CREATE TABLE connector_response (
+ id SERIAL PRIMARY KEY,
+ payment_id VARCHAR(255) NOT NULL,
+ merchant_id VARCHAR(255) NOT NULL,
+ txn_id VARCHAR(255) NOT NULL,
+ created_at TIMESTAMP NOT NULL DEFAULT now()::TIMESTAMP,
+ modified_at TIMESTAMP NOT NULL DEFAULT now()::TIMESTAMP,
+ connector_name VARCHAR(32) NOT NULL,
+ connector_transaction_id VARCHAR(255),
+ authentication_data JSON,
+ encoded_data TEXT
+);
+
+CREATE UNIQUE INDEX connector_response_id_index ON connector_response (payment_id, merchant_id, txn_id);
+
+ALTER TABLE connector_response ALTER COLUMN connector_name DROP NOT NULL;
+ALTER TABLE connector_response RENAME COLUMN txn_id TO attempt_id;
+ALTER TABLE connector_response
+ ALTER COLUMN payment_id TYPE VARCHAR(64),
+ ALTER COLUMN merchant_id TYPE VARCHAR(64),
+ ALTER COLUMN attempt_id TYPE VARCHAR(64),
+ ALTER COLUMN connector_name TYPE VARCHAR(64),
+ ALTER COLUMN connector_transaction_id TYPE VARCHAR(128);
+
+
+
+ALTER TABLE connector_response
+ALTER COLUMN modified_at DROP DEFAULT;
+
+ALTER TABLE connector_response
+ALTER COLUMN created_at DROP DEFAULT;
+
+ALTER TABLE connector_response ADD column updated_by VARCHAR(32) NOT NULL DEFAULT 'postgres_only';
diff --git a/migrations/2023-11-08-144951_drop_connector_response_table/up.sql b/migrations/2023-11-08-144951_drop_connector_response_table/up.sql
new file mode 100644
index 000000000000..0059a6b38dc1
--- /dev/null
+++ b/migrations/2023-11-08-144951_drop_connector_response_table/up.sql
@@ -0,0 +1,2 @@
+-- Your SQL goes here
+DROP TABLE connector_response; --NOT to run in deployment envs
\ No newline at end of file
diff --git a/openapi/openapi_spec.json b/openapi/openapi_spec.json
index 5af67e499275..6e61f2eb614e 100644
--- a/openapi/openapi_spec.json
+++ b/openapi/openapi_spec.json
@@ -7866,6 +7866,11 @@
"merchant_custom_domain_name": {
"type": "string",
"nullable": true
+ },
+ "custom_merchant_name": {
+ "type": "string",
+ "description": "Custom merchant name for payment link",
+ "nullable": true
}
}
},