mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-27 11:24:45 +08:00
feat(ai): add endpoints to chat with ai service (#8585)
Co-authored-by: Riddhiagrawal001 <riddhi.agrawal2112@gmail.com> Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@ -1133,4 +1133,8 @@ version = "HOSTNAME" # value of HOSTNAME from deployment which tells its
|
|||||||
|
|
||||||
[platform]
|
[platform]
|
||||||
enabled = true # Enable or disable platform features
|
enabled = true # Enable or disable platform features
|
||||||
allow_connected_merchants = false # Enable or disable connected merchant account features
|
allow_connected_merchants = false # Enable or disable connected merchant account features
|
||||||
|
|
||||||
|
[chat]
|
||||||
|
enabled = false # Enable or disable chat features
|
||||||
|
hyperswitch_ai_host = "http://0.0.0.0:8000" # Hyperswitch ai workflow host
|
||||||
@ -380,4 +380,8 @@ connector_names = "connector_names" # Comma-separated list of allowed connec
|
|||||||
[grpc_client.unified_connector_service]
|
[grpc_client.unified_connector_service]
|
||||||
host = "localhost" # Unified Connector Service Client Host
|
host = "localhost" # Unified Connector Service Client Host
|
||||||
port = 8000 # Unified Connector Service Client Port
|
port = 8000 # Unified Connector Service Client Port
|
||||||
connection_timeout = 10 # Connection Timeout Duration in Seconds
|
connection_timeout = 10 # Connection Timeout Duration in Seconds
|
||||||
|
|
||||||
|
[chat]
|
||||||
|
enabled = false # Enable or disable chat features
|
||||||
|
hyperswitch_ai_host = "http://0.0.0.0:8000" # Hyperswitch ai workflow host
|
||||||
|
|||||||
@ -1226,3 +1226,7 @@ connector_names = "stripe, adyen" # Comma-separated list of allowe
|
|||||||
[infra_values]
|
[infra_values]
|
||||||
cluster = "CLUSTER"
|
cluster = "CLUSTER"
|
||||||
version = "HOSTNAME"
|
version = "HOSTNAME"
|
||||||
|
|
||||||
|
[chat]
|
||||||
|
enabled = false
|
||||||
|
hyperswitch_ai_host = "http://0.0.0.0:8000"
|
||||||
@ -1109,6 +1109,10 @@ background_color = "#FFFFFF"
|
|||||||
enabled = true
|
enabled = true
|
||||||
allow_connected_merchants = true
|
allow_connected_merchants = true
|
||||||
|
|
||||||
|
[chat]
|
||||||
|
enabled = false
|
||||||
|
hyperswitch_ai_host = "http://0.0.0.0:8000"
|
||||||
|
|
||||||
[authentication_providers]
|
[authentication_providers]
|
||||||
click_to_pay = {connector_list = "adyen, cybersource"}
|
click_to_pay = {connector_list = "adyen, cybersource"}
|
||||||
|
|
||||||
|
|||||||
18
crates/api_models/src/chat.rs
Normal file
18
crates/api_models/src/chat.rs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
use common_utils::id_type;
|
||||||
|
use masking::Secret;
|
||||||
|
|
||||||
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
|
pub struct ChatRequest {
|
||||||
|
pub message: Secret<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, serde::Deserialize, serde::Serialize)]
|
||||||
|
pub struct ChatResponse {
|
||||||
|
pub response: Secret<serde_json::Value>,
|
||||||
|
pub merchant_id: id_type::MerchantId,
|
||||||
|
pub status: String,
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
pub query_executed: Option<Secret<String>>,
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
pub row_count: Option<i32>,
|
||||||
|
}
|
||||||
@ -1,4 +1,5 @@
|
|||||||
pub mod apple_pay_certificates_migration;
|
pub mod apple_pay_certificates_migration;
|
||||||
|
pub mod chat;
|
||||||
pub mod connector_onboarding;
|
pub mod connector_onboarding;
|
||||||
pub mod customer;
|
pub mod customer;
|
||||||
pub mod dispute;
|
pub mod dispute;
|
||||||
|
|||||||
5
crates/api_models/src/events/chat.rs
Normal file
5
crates/api_models/src/events/chat.rs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
use common_utils::events::{ApiEventMetric, ApiEventsType};
|
||||||
|
|
||||||
|
use crate::chat::{ChatRequest, ChatResponse};
|
||||||
|
|
||||||
|
common_utils::impl_api_event_type!(Chat, (ChatRequest, ChatResponse));
|
||||||
@ -5,6 +5,7 @@ pub mod apple_pay_certificates_migration;
|
|||||||
pub mod authentication;
|
pub mod authentication;
|
||||||
pub mod blocklist;
|
pub mod blocklist;
|
||||||
pub mod cards_info;
|
pub mod cards_info;
|
||||||
|
pub mod chat;
|
||||||
pub mod conditional_configs;
|
pub mod conditional_configs;
|
||||||
pub mod connector_enums;
|
pub mod connector_enums;
|
||||||
pub mod connector_onboarding;
|
pub mod connector_onboarding;
|
||||||
|
|||||||
@ -191,3 +191,6 @@ pub const METRICS_HOST_TAG_NAME: &str = "host";
|
|||||||
|
|
||||||
/// API client request timeout (in seconds)
|
/// API client request timeout (in seconds)
|
||||||
pub const REQUEST_TIME_OUT: u64 = 30;
|
pub const REQUEST_TIME_OUT: u64 = 30;
|
||||||
|
|
||||||
|
/// API client request timeout for ai service (in seconds)
|
||||||
|
pub const REQUEST_TIME_OUT_FOR_AI_SERVICE: u64 = 120;
|
||||||
|
|||||||
@ -137,6 +137,7 @@ pub enum ApiEventsType {
|
|||||||
profile_acquirer_id: id_type::ProfileAcquirerId,
|
profile_acquirer_id: id_type::ProfileAcquirerId,
|
||||||
},
|
},
|
||||||
ThreeDsDecisionRule,
|
ThreeDsDecisionRule,
|
||||||
|
Chat,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ApiEventMetric for serde_json::Value {}
|
impl ApiEventMetric for serde_json::Value {}
|
||||||
|
|||||||
15
crates/hyperswitch_domain_models/src/chat.rs
Normal file
15
crates/hyperswitch_domain_models/src/chat.rs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
use common_utils::id_type;
|
||||||
|
use masking::Secret;
|
||||||
|
|
||||||
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
|
pub struct GetDataMessage {
|
||||||
|
pub message: Secret<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
|
pub struct HyperswitchAiDataRequest {
|
||||||
|
pub merchant_id: id_type::MerchantId,
|
||||||
|
pub profile_id: id_type::ProfileId,
|
||||||
|
pub org_id: id_type::OrganizationId,
|
||||||
|
pub query: GetDataMessage,
|
||||||
|
}
|
||||||
@ -6,6 +6,7 @@ pub mod business_profile;
|
|||||||
pub mod callback_mapper;
|
pub mod callback_mapper;
|
||||||
pub mod card_testing_guard_data;
|
pub mod card_testing_guard_data;
|
||||||
pub mod cards_info;
|
pub mod cards_info;
|
||||||
|
pub mod chat;
|
||||||
pub mod connector_endpoints;
|
pub mod connector_endpoints;
|
||||||
pub mod consts;
|
pub mod consts;
|
||||||
pub mod customer;
|
pub mod customer;
|
||||||
|
|||||||
@ -452,6 +452,7 @@ pub(crate) async fn fetch_raw_secrets(
|
|||||||
|
|
||||||
Settings {
|
Settings {
|
||||||
server: conf.server,
|
server: conf.server,
|
||||||
|
chat: conf.chat,
|
||||||
master_database,
|
master_database,
|
||||||
redis: conf.redis,
|
redis: conf.redis,
|
||||||
log: conf.log,
|
log: conf.log,
|
||||||
|
|||||||
@ -70,6 +70,7 @@ pub struct Settings<S: SecretState> {
|
|||||||
pub server: Server,
|
pub server: Server,
|
||||||
pub proxy: Proxy,
|
pub proxy: Proxy,
|
||||||
pub env: Env,
|
pub env: Env,
|
||||||
|
pub chat: ChatSettings,
|
||||||
pub master_database: SecretStateContainer<Database, S>,
|
pub master_database: SecretStateContainer<Database, S>,
|
||||||
#[cfg(feature = "olap")]
|
#[cfg(feature = "olap")]
|
||||||
pub replica_database: SecretStateContainer<Database, S>,
|
pub replica_database: SecretStateContainer<Database, S>,
|
||||||
@ -195,6 +196,13 @@ pub struct Platform {
|
|||||||
pub allow_connected_merchants: bool,
|
pub allow_connected_merchants: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Clone, Default)]
|
||||||
|
#[serde(default)]
|
||||||
|
pub struct ChatSettings {
|
||||||
|
pub enabled: bool,
|
||||||
|
pub hyperswitch_ai_host: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Deserialize)]
|
#[derive(Debug, Clone, Default, Deserialize)]
|
||||||
pub struct Multitenancy {
|
pub struct Multitenancy {
|
||||||
pub tenants: TenantConfig,
|
pub tenants: TenantConfig,
|
||||||
@ -1016,6 +1024,7 @@ impl Settings<SecuredSecret> {
|
|||||||
self.secrets.get_inner().validate()?;
|
self.secrets.get_inner().validate()?;
|
||||||
self.locker.validate()?;
|
self.locker.validate()?;
|
||||||
self.connectors.validate("connectors")?;
|
self.connectors.validate("connectors")?;
|
||||||
|
self.chat.validate()?;
|
||||||
|
|
||||||
self.cors.validate()?;
|
self.cors.validate()?;
|
||||||
|
|
||||||
|
|||||||
@ -343,3 +343,15 @@ impl super::settings::OpenRouter {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl super::settings::ChatSettings {
|
||||||
|
pub fn validate(&self) -> Result<(), ApplicationError> {
|
||||||
|
use common_utils::fp_utils::when;
|
||||||
|
|
||||||
|
when(self.enabled && self.hyperswitch_ai_host.is_empty(), || {
|
||||||
|
Err(ApplicationError::InvalidConfigurationValueError(
|
||||||
|
"hyperswitch ai host must be set if chat is enabled".into(),
|
||||||
|
))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -72,4 +72,5 @@ pub mod relay;
|
|||||||
#[cfg(feature = "v2")]
|
#[cfg(feature = "v2")]
|
||||||
pub mod revenue_recovery;
|
pub mod revenue_recovery;
|
||||||
|
|
||||||
|
pub mod chat;
|
||||||
pub mod tokenization;
|
pub mod tokenization;
|
||||||
|
|||||||
57
crates/router/src/core/chat.rs
Normal file
57
crates/router/src/core/chat.rs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
use api_models::chat as chat_api;
|
||||||
|
use common_utils::{
|
||||||
|
consts,
|
||||||
|
errors::CustomResult,
|
||||||
|
request::{Method, RequestBuilder, RequestContent},
|
||||||
|
};
|
||||||
|
use error_stack::ResultExt;
|
||||||
|
use external_services::http_client;
|
||||||
|
use hyperswitch_domain_models::chat as chat_domain;
|
||||||
|
use router_env::{instrument, logger, tracing};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
db::errors::chat::ChatErrors,
|
||||||
|
routes::SessionState,
|
||||||
|
services::{authentication as auth, ApplicationResponse},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[instrument(skip_all)]
|
||||||
|
pub async fn get_data_from_hyperswitch_ai_workflow(
|
||||||
|
state: SessionState,
|
||||||
|
user_from_token: auth::UserFromToken,
|
||||||
|
req: chat_api::ChatRequest,
|
||||||
|
) -> CustomResult<ApplicationResponse<chat_api::ChatResponse>, ChatErrors> {
|
||||||
|
let url = format!("{}/webhook", state.conf.chat.hyperswitch_ai_host);
|
||||||
|
|
||||||
|
let request_body = chat_domain::HyperswitchAiDataRequest {
|
||||||
|
query: chat_domain::GetDataMessage {
|
||||||
|
message: req.message,
|
||||||
|
},
|
||||||
|
org_id: user_from_token.org_id,
|
||||||
|
merchant_id: user_from_token.merchant_id,
|
||||||
|
profile_id: user_from_token.profile_id,
|
||||||
|
};
|
||||||
|
logger::info!("Request for AI service: {:?}", request_body);
|
||||||
|
|
||||||
|
let request = RequestBuilder::new()
|
||||||
|
.method(Method::Post)
|
||||||
|
.url(&url)
|
||||||
|
.attach_default_headers()
|
||||||
|
.set_body(RequestContent::Json(Box::new(request_body.clone())))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let response = http_client::send_request(
|
||||||
|
&state.conf.proxy,
|
||||||
|
request,
|
||||||
|
Some(consts::REQUEST_TIME_OUT_FOR_AI_SERVICE),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.change_context(ChatErrors::InternalServerError)
|
||||||
|
.attach_printable("Error when sending request to AI service")?
|
||||||
|
.json::<_>()
|
||||||
|
.await
|
||||||
|
.change_context(ChatErrors::InternalServerError)
|
||||||
|
.attach_printable("Error when deserializing response from AI service")?;
|
||||||
|
|
||||||
|
Ok(ApplicationResponse::Json(response))
|
||||||
|
}
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
pub mod chat;
|
||||||
pub mod customers_error_response;
|
pub mod customers_error_response;
|
||||||
pub mod error_handlers;
|
pub mod error_handlers;
|
||||||
pub mod transformers;
|
pub mod transformers;
|
||||||
|
|||||||
37
crates/router/src/core/errors/chat.rs
Normal file
37
crates/router/src/core/errors/chat.rs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
pub enum ChatErrors {
|
||||||
|
#[error("User InternalServerError")]
|
||||||
|
InternalServerError,
|
||||||
|
#[error("Missing Config error")]
|
||||||
|
MissingConfigError,
|
||||||
|
#[error("Chat response deserialization failed")]
|
||||||
|
ChatResponseDeserializationFailed,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl common_utils::errors::ErrorSwitch<api_models::errors::types::ApiErrorResponse> for ChatErrors {
|
||||||
|
fn switch(&self) -> api_models::errors::types::ApiErrorResponse {
|
||||||
|
use api_models::errors::types::{ApiError, ApiErrorResponse as AER};
|
||||||
|
let sub_code = "AI";
|
||||||
|
match self {
|
||||||
|
Self::InternalServerError => {
|
||||||
|
AER::InternalServerError(ApiError::new("HE", 0, self.get_error_message(), None))
|
||||||
|
}
|
||||||
|
Self::MissingConfigError => {
|
||||||
|
AER::InternalServerError(ApiError::new(sub_code, 1, self.get_error_message(), None))
|
||||||
|
}
|
||||||
|
Self::ChatResponseDeserializationFailed => {
|
||||||
|
AER::BadRequest(ApiError::new(sub_code, 2, self.get_error_message(), None))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ChatErrors {
|
||||||
|
pub fn get_error_message(&self) -> String {
|
||||||
|
match self {
|
||||||
|
Self::InternalServerError => "Something went wrong".to_string(),
|
||||||
|
Self::MissingConfigError => "Missing webhook url".to_string(),
|
||||||
|
Self::ChatResponseDeserializationFailed => "Failed to parse chat response".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -189,7 +189,8 @@ pub fn mk_app(
|
|||||||
.service(routes::MerchantAccount::server(state.clone()))
|
.service(routes::MerchantAccount::server(state.clone()))
|
||||||
.service(routes::User::server(state.clone()))
|
.service(routes::User::server(state.clone()))
|
||||||
.service(routes::ApiKeys::server(state.clone()))
|
.service(routes::ApiKeys::server(state.clone()))
|
||||||
.service(routes::Routing::server(state.clone()));
|
.service(routes::Routing::server(state.clone()))
|
||||||
|
.service(routes::Chat::server(state.clone()));
|
||||||
|
|
||||||
#[cfg(feature = "v1")]
|
#[cfg(feature = "v1")]
|
||||||
{
|
{
|
||||||
|
|||||||
@ -75,6 +75,8 @@ pub mod process_tracker;
|
|||||||
#[cfg(feature = "v2")]
|
#[cfg(feature = "v2")]
|
||||||
pub mod proxy;
|
pub mod proxy;
|
||||||
|
|
||||||
|
pub mod chat;
|
||||||
|
|
||||||
#[cfg(feature = "dummy_connector")]
|
#[cfg(feature = "dummy_connector")]
|
||||||
pub use self::app::DummyConnector;
|
pub use self::app::DummyConnector;
|
||||||
#[cfg(feature = "v2")]
|
#[cfg(feature = "v2")]
|
||||||
@ -86,7 +88,7 @@ pub use self::app::Recon;
|
|||||||
#[cfg(feature = "v2")]
|
#[cfg(feature = "v2")]
|
||||||
pub use self::app::Tokenization;
|
pub use self::app::Tokenization;
|
||||||
pub use self::app::{
|
pub use self::app::{
|
||||||
ApiKeys, AppState, ApplePayCertificatesMigration, Authentication, Cache, Cards, Configs,
|
ApiKeys, AppState, ApplePayCertificatesMigration, Authentication, Cache, Cards, Chat, Configs,
|
||||||
ConnectorOnboarding, Customers, Disputes, EphemeralKey, FeatureMatrix, Files, Forex, Gsm,
|
ConnectorOnboarding, Customers, Disputes, EphemeralKey, FeatureMatrix, Files, Forex, Gsm,
|
||||||
Health, Hypersense, Mandates, MerchantAccount, MerchantConnectorAccount, PaymentLink,
|
Health, Hypersense, Mandates, MerchantAccount, MerchantConnectorAccount, PaymentLink,
|
||||||
PaymentMethods, Payments, Poll, ProcessTracker, Profile, ProfileAcquirer, ProfileNew, Refunds,
|
PaymentMethods, Payments, Poll, ProcessTracker, Profile, ProfileAcquirer, ProfileNew, Refunds,
|
||||||
|
|||||||
@ -59,8 +59,8 @@ use super::verification::{apple_pay_merchant_registration, retrieve_apple_pay_ve
|
|||||||
#[cfg(feature = "oltp")]
|
#[cfg(feature = "oltp")]
|
||||||
use super::webhooks::*;
|
use super::webhooks::*;
|
||||||
use super::{
|
use super::{
|
||||||
admin, api_keys, cache::*, connector_onboarding, disputes, files, gsm, health::*, profiles,
|
admin, api_keys, cache::*, chat, connector_onboarding, disputes, files, gsm, health::*,
|
||||||
relay, user, user_role,
|
profiles, relay, user, user_role,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "v1")]
|
#[cfg(feature = "v1")]
|
||||||
use super::{apple_pay_certificates_migration, blocklist, payment_link, webhook_events};
|
use super::{apple_pay_certificates_migration, blocklist, payment_link, webhook_events};
|
||||||
@ -2215,6 +2215,23 @@ impl Gsm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Chat;
|
||||||
|
|
||||||
|
#[cfg(feature = "olap")]
|
||||||
|
impl Chat {
|
||||||
|
pub fn server(state: AppState) -> Scope {
|
||||||
|
let mut route = web::scope("/chat").app_data(web::Data::new(state.clone()));
|
||||||
|
if state.conf.chat.enabled {
|
||||||
|
route = route.service(
|
||||||
|
web::scope("/ai").service(
|
||||||
|
web::resource("/data")
|
||||||
|
.route(web::post().to(chat::get_data_from_hyperswitch_ai_workflow)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
route
|
||||||
|
}
|
||||||
|
}
|
||||||
pub struct ThreeDsDecisionRule;
|
pub struct ThreeDsDecisionRule;
|
||||||
|
|
||||||
#[cfg(feature = "oltp")]
|
#[cfg(feature = "oltp")]
|
||||||
|
|||||||
38
crates/router/src/routes/chat.rs
Normal file
38
crates/router/src/routes/chat.rs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
use actix_web::{web, HttpRequest, HttpResponse};
|
||||||
|
#[cfg(feature = "olap")]
|
||||||
|
use api_models::chat as chat_api;
|
||||||
|
use router_env::{instrument, tracing, Flow};
|
||||||
|
|
||||||
|
use super::AppState;
|
||||||
|
use crate::{
|
||||||
|
core::{api_locking, chat as chat_core},
|
||||||
|
services::{
|
||||||
|
api,
|
||||||
|
authentication::{self as auth},
|
||||||
|
authorization::permissions::Permission,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[instrument(skip_all)]
|
||||||
|
pub async fn get_data_from_hyperswitch_ai_workflow(
|
||||||
|
state: web::Data<AppState>,
|
||||||
|
http_req: HttpRequest,
|
||||||
|
payload: web::Json<chat_api::ChatRequest>,
|
||||||
|
) -> HttpResponse {
|
||||||
|
let flow = Flow::GetDataFromHyperswitchAiFlow;
|
||||||
|
Box::pin(api::server_wrap(
|
||||||
|
flow.clone(),
|
||||||
|
state,
|
||||||
|
&http_req,
|
||||||
|
payload.into_inner(),
|
||||||
|
|state, user: auth::UserFromToken, payload, _| {
|
||||||
|
chat_core::get_data_from_hyperswitch_ai_workflow(state, user, payload)
|
||||||
|
},
|
||||||
|
// At present, the AI service retrieves data scoped to the merchant level
|
||||||
|
&auth::JWTAuth {
|
||||||
|
permission: Permission::MerchantPaymentRead,
|
||||||
|
},
|
||||||
|
api_locking::LockAction::NotApplicable,
|
||||||
|
))
|
||||||
|
.await
|
||||||
|
}
|
||||||
@ -35,6 +35,7 @@ pub enum ApiIdentifier {
|
|||||||
UserRole,
|
UserRole,
|
||||||
ConnectorOnboarding,
|
ConnectorOnboarding,
|
||||||
Recon,
|
Recon,
|
||||||
|
AiWorkflow,
|
||||||
Poll,
|
Poll,
|
||||||
ApplePayCertificatesMigration,
|
ApplePayCertificatesMigration,
|
||||||
Relay,
|
Relay,
|
||||||
@ -300,6 +301,8 @@ impl From<Flow> for ApiIdentifier {
|
|||||||
| Flow::DeleteTheme
|
| Flow::DeleteTheme
|
||||||
| Flow::CloneConnector => Self::User,
|
| Flow::CloneConnector => Self::User,
|
||||||
|
|
||||||
|
Flow::GetDataFromHyperswitchAiFlow => Self::AiWorkflow,
|
||||||
|
|
||||||
Flow::ListRolesV2
|
Flow::ListRolesV2
|
||||||
| Flow::ListInvitableRolesAtEntityLevel
|
| Flow::ListInvitableRolesAtEntityLevel
|
||||||
| Flow::ListUpdatableRolesAtEntityLevel
|
| Flow::ListUpdatableRolesAtEntityLevel
|
||||||
|
|||||||
@ -349,6 +349,8 @@ pub enum Flow {
|
|||||||
ApplePayCertificatesMigration,
|
ApplePayCertificatesMigration,
|
||||||
/// Gsm Rule Delete flow
|
/// Gsm Rule Delete flow
|
||||||
GsmRuleDelete,
|
GsmRuleDelete,
|
||||||
|
/// Get data from embedded flow
|
||||||
|
GetDataFromHyperswitchAiFlow,
|
||||||
/// User Sign Up
|
/// User Sign Up
|
||||||
UserSignUp,
|
UserSignUp,
|
||||||
/// User Sign Up
|
/// User Sign Up
|
||||||
|
|||||||
@ -724,3 +724,7 @@ redsys = { payment_method = "card" }
|
|||||||
billing_connectors_which_require_payment_sync = "stripebilling, recurly"
|
billing_connectors_which_require_payment_sync = "stripebilling, recurly"
|
||||||
[billing_connectors_invoice_sync]
|
[billing_connectors_invoice_sync]
|
||||||
billing_connectors_which_requires_invoice_sync_call = "recurly"
|
billing_connectors_which_requires_invoice_sync_call = "recurly"
|
||||||
|
|
||||||
|
[chat]
|
||||||
|
enabled = false
|
||||||
|
hyperswitch_ai_host = "http://0.0.0.0:8000"
|
||||||
Reference in New Issue
Block a user