mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-27 19:46:48 +08:00
feat(router): add straight-through routing connector selection in payments (#153)
This commit is contained in:
@ -293,7 +293,7 @@ Feel free to connect with us in case of queries and also if you want to confirm
|
|||||||
|
|
||||||
Add connector name in :
|
Add connector name in :
|
||||||
|
|
||||||
- `crates/router/src/types/connector.rs` in Connector enum
|
- `crates/api_models/src/enums.rs` in Connector enum (in alphabetical order)
|
||||||
- `crates/router/src/types/api/mod.rs` convert_connector function
|
- `crates/router/src/types/api/mod.rs` convert_connector function
|
||||||
|
|
||||||
Configure the Connectors API credentials using the PaymentConnectors API.
|
Configure the Connectors API credentials using the PaymentConnectors API.
|
||||||
|
|||||||
@ -468,6 +468,34 @@ pub enum MandateStatus {
|
|||||||
Revoked,
|
Revoked,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Copy,
|
||||||
|
Debug,
|
||||||
|
Default,
|
||||||
|
Eq,
|
||||||
|
PartialEq,
|
||||||
|
serde::Deserialize,
|
||||||
|
serde::Serialize,
|
||||||
|
strum::Display,
|
||||||
|
strum::EnumString,
|
||||||
|
frunk::LabelledGeneric,
|
||||||
|
)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
#[strum(serialize_all = "snake_case")]
|
||||||
|
pub enum Connector {
|
||||||
|
Aci,
|
||||||
|
Adyen,
|
||||||
|
Applepay,
|
||||||
|
Authorizedotnet,
|
||||||
|
Braintree,
|
||||||
|
Checkout,
|
||||||
|
#[default]
|
||||||
|
Dummy,
|
||||||
|
Klarna,
|
||||||
|
Stripe,
|
||||||
|
}
|
||||||
|
|
||||||
impl From<AttemptStatus> for IntentStatus {
|
impl From<AttemptStatus> for IntentStatus {
|
||||||
fn from(s: AttemptStatus) -> Self {
|
fn from(s: AttemptStatus) -> Self {
|
||||||
match s {
|
match s {
|
||||||
|
|||||||
@ -22,6 +22,7 @@ pub struct PaymentsRequest {
|
|||||||
pub merchant_id: Option<String>,
|
pub merchant_id: Option<String>,
|
||||||
#[serde(default, deserialize_with = "amount::deserialize_option")]
|
#[serde(default, deserialize_with = "amount::deserialize_option")]
|
||||||
pub amount: Option<Amount>,
|
pub amount: Option<Amount>,
|
||||||
|
pub connector: Option<api_enums::Connector>,
|
||||||
pub currency: Option<String>,
|
pub currency: Option<String>,
|
||||||
pub capture_method: Option<api_enums::CaptureMethod>,
|
pub capture_method: Option<api_enums::CaptureMethod>,
|
||||||
pub amount_to_capture: Option<i64>,
|
pub amount_to_capture: Option<i64>,
|
||||||
|
|||||||
@ -349,6 +349,7 @@ impl From<ApiErrorResponse> for ErrorCode {
|
|||||||
ApiErrorResponse::RefundFailed { data } => ErrorCode::RefundFailed, // Nothing at stripe to map
|
ApiErrorResponse::RefundFailed { data } => ErrorCode::RefundFailed, // Nothing at stripe to map
|
||||||
|
|
||||||
ApiErrorResponse::InternalServerError => ErrorCode::InternalServerError, // not a stripe code
|
ApiErrorResponse::InternalServerError => ErrorCode::InternalServerError, // not a stripe code
|
||||||
|
ApiErrorResponse::IncorrectConnectorNameGiven => ErrorCode::InternalServerError,
|
||||||
ApiErrorResponse::MandateActive => ErrorCode::MandateActive, //not a stripe code
|
ApiErrorResponse::MandateActive => ErrorCode::MandateActive, //not a stripe code
|
||||||
ApiErrorResponse::CustomerRedacted => ErrorCode::CustomerRedacted, //not a stripe code
|
ApiErrorResponse::CustomerRedacted => ErrorCode::CustomerRedacted, //not a stripe code
|
||||||
ApiErrorResponse::DuplicateRefundRequest => ErrorCode::DuplicateRefundRequest,
|
ApiErrorResponse::DuplicateRefundRequest => ErrorCode::DuplicateRefundRequest,
|
||||||
|
|||||||
@ -47,12 +47,14 @@ pub async fn payment_intents_create(
|
|||||||
&req,
|
&req,
|
||||||
create_payment_req,
|
create_payment_req,
|
||||||
|state, merchant_account, req| {
|
|state, merchant_account, req| {
|
||||||
|
let connector = req.connector;
|
||||||
payments::payments_core::<Authorize, api_types::PaymentsResponse, _, _, _>(
|
payments::payments_core::<Authorize, api_types::PaymentsResponse, _, _, _>(
|
||||||
state,
|
state,
|
||||||
merchant_account,
|
merchant_account,
|
||||||
payments::PaymentCreate,
|
payments::PaymentCreate,
|
||||||
req,
|
req,
|
||||||
api::AuthFlow::Merchant,
|
api::AuthFlow::Merchant,
|
||||||
|
connector,
|
||||||
payments::CallConnectorAction::Trigger,
|
payments::CallConnectorAction::Trigger,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -101,6 +103,7 @@ pub async fn payment_intents_retrieve(
|
|||||||
payments::PaymentStatus,
|
payments::PaymentStatus,
|
||||||
payload,
|
payload,
|
||||||
auth_flow,
|
auth_flow,
|
||||||
|
None,
|
||||||
payments::CallConnectorAction::Trigger,
|
payments::CallConnectorAction::Trigger,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -149,12 +152,14 @@ pub async fn payment_intents_update(
|
|||||||
&req,
|
&req,
|
||||||
payload,
|
payload,
|
||||||
|state, merchant_account, req| {
|
|state, merchant_account, req| {
|
||||||
|
let connector = req.connector;
|
||||||
payments::payments_core::<Authorize, api_types::PaymentsResponse, _, _, _>(
|
payments::payments_core::<Authorize, api_types::PaymentsResponse, _, _, _>(
|
||||||
state,
|
state,
|
||||||
merchant_account,
|
merchant_account,
|
||||||
payments::PaymentUpdate,
|
payments::PaymentUpdate,
|
||||||
req,
|
req,
|
||||||
auth_flow,
|
auth_flow,
|
||||||
|
connector,
|
||||||
payments::CallConnectorAction::Trigger,
|
payments::CallConnectorAction::Trigger,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -204,12 +209,14 @@ pub async fn payment_intents_confirm(
|
|||||||
&req,
|
&req,
|
||||||
payload,
|
payload,
|
||||||
|state, merchant_account, req| {
|
|state, merchant_account, req| {
|
||||||
|
let connector = req.connector;
|
||||||
payments::payments_core::<Authorize, api_types::PaymentsResponse, _, _, _>(
|
payments::payments_core::<Authorize, api_types::PaymentsResponse, _, _, _>(
|
||||||
state,
|
state,
|
||||||
merchant_account,
|
merchant_account,
|
||||||
payments::PaymentConfirm,
|
payments::PaymentConfirm,
|
||||||
req,
|
req,
|
||||||
auth_flow,
|
auth_flow,
|
||||||
|
connector,
|
||||||
payments::CallConnectorAction::Trigger,
|
payments::CallConnectorAction::Trigger,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -257,6 +264,7 @@ pub async fn payment_intents_capture(
|
|||||||
payments::PaymentCapture,
|
payments::PaymentCapture,
|
||||||
payload,
|
payload,
|
||||||
api::AuthFlow::Merchant,
|
api::AuthFlow::Merchant,
|
||||||
|
None,
|
||||||
payments::CallConnectorAction::Trigger,
|
payments::CallConnectorAction::Trigger,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -310,6 +318,7 @@ pub async fn payment_intents_cancel(
|
|||||||
payments::PaymentCancel,
|
payments::PaymentCancel,
|
||||||
req,
|
req,
|
||||||
auth_flow,
|
auth_flow,
|
||||||
|
None,
|
||||||
payments::CallConnectorAction::Trigger,
|
payments::CallConnectorAction::Trigger,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|||||||
@ -114,6 +114,7 @@ impl From<Shipping> for Address {
|
|||||||
#[derive(Default, PartialEq, Eq, Deserialize, Clone)]
|
#[derive(Default, PartialEq, Eq, Deserialize, Clone)]
|
||||||
pub(crate) struct StripePaymentIntentRequest {
|
pub(crate) struct StripePaymentIntentRequest {
|
||||||
pub(crate) amount: Option<i64>, //amount in cents, hence passed as integer
|
pub(crate) amount: Option<i64>, //amount in cents, hence passed as integer
|
||||||
|
pub(crate) connector: Option<api_enums::Connector>,
|
||||||
pub(crate) currency: Option<String>,
|
pub(crate) currency: Option<String>,
|
||||||
#[serde(rename = "amount_to_capture")]
|
#[serde(rename = "amount_to_capture")]
|
||||||
pub(crate) amount_capturable: Option<i64>,
|
pub(crate) amount_capturable: Option<i64>,
|
||||||
@ -137,6 +138,7 @@ impl From<StripePaymentIntentRequest> for PaymentsRequest {
|
|||||||
fn from(item: StripePaymentIntentRequest) -> Self {
|
fn from(item: StripePaymentIntentRequest) -> Self {
|
||||||
PaymentsRequest {
|
PaymentsRequest {
|
||||||
amount: item.amount.map(|amount| amount.into()),
|
amount: item.amount.map(|amount| amount.into()),
|
||||||
|
connector: item.connector,
|
||||||
currency: item.currency.as_ref().map(|c| c.to_uppercase()),
|
currency: item.currency.as_ref().map(|c| c.to_uppercase()),
|
||||||
capture_method: item.capture_method,
|
capture_method: item.capture_method,
|
||||||
amount_to_capture: item.amount_capturable,
|
amount_to_capture: item.amount_capturable,
|
||||||
|
|||||||
@ -43,12 +43,14 @@ pub async fn setup_intents_create(
|
|||||||
&req,
|
&req,
|
||||||
create_payment_req,
|
create_payment_req,
|
||||||
|state, merchant_account, req| {
|
|state, merchant_account, req| {
|
||||||
|
let connector = req.connector;
|
||||||
payments::payments_core::<Verify, api_types::PaymentsResponse, _, _, _>(
|
payments::payments_core::<Verify, api_types::PaymentsResponse, _, _, _>(
|
||||||
state,
|
state,
|
||||||
merchant_account,
|
merchant_account,
|
||||||
payments::PaymentCreate,
|
payments::PaymentCreate,
|
||||||
req,
|
req,
|
||||||
api::AuthFlow::Merchant,
|
api::AuthFlow::Merchant,
|
||||||
|
connector,
|
||||||
payments::CallConnectorAction::Trigger,
|
payments::CallConnectorAction::Trigger,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -97,6 +99,7 @@ pub async fn setup_intents_retrieve(
|
|||||||
payments::PaymentStatus,
|
payments::PaymentStatus,
|
||||||
payload,
|
payload,
|
||||||
auth_flow,
|
auth_flow,
|
||||||
|
None,
|
||||||
payments::CallConnectorAction::Trigger,
|
payments::CallConnectorAction::Trigger,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -145,12 +148,14 @@ pub async fn setup_intents_update(
|
|||||||
&req,
|
&req,
|
||||||
payload,
|
payload,
|
||||||
|state, merchant_account, req| {
|
|state, merchant_account, req| {
|
||||||
|
let connector = req.connector;
|
||||||
payments::payments_core::<Verify, api_types::PaymentsResponse, _, _, _>(
|
payments::payments_core::<Verify, api_types::PaymentsResponse, _, _, _>(
|
||||||
state,
|
state,
|
||||||
merchant_account,
|
merchant_account,
|
||||||
payments::PaymentUpdate,
|
payments::PaymentUpdate,
|
||||||
req,
|
req,
|
||||||
auth_flow,
|
auth_flow,
|
||||||
|
connector,
|
||||||
payments::CallConnectorAction::Trigger,
|
payments::CallConnectorAction::Trigger,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -200,12 +205,14 @@ pub async fn setup_intents_confirm(
|
|||||||
&req,
|
&req,
|
||||||
payload,
|
payload,
|
||||||
|state, merchant_account, req| {
|
|state, merchant_account, req| {
|
||||||
|
let connector = req.connector;
|
||||||
payments::payments_core::<Verify, api_types::PaymentsResponse, _, _, _>(
|
payments::payments_core::<Verify, api_types::PaymentsResponse, _, _, _>(
|
||||||
state,
|
state,
|
||||||
merchant_account,
|
merchant_account,
|
||||||
payments::PaymentConfirm,
|
payments::PaymentConfirm,
|
||||||
req,
|
req,
|
||||||
auth_flow,
|
auth_flow,
|
||||||
|
connector,
|
||||||
payments::CallConnectorAction::Trigger,
|
payments::CallConnectorAction::Trigger,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|||||||
@ -123,6 +123,8 @@ pub enum ApiErrorResponse {
|
|||||||
PaymentNotSucceeded,
|
PaymentNotSucceeded,
|
||||||
#[error(error_type= ErrorType::ObjectNotFound, code = "RE_05", message = "Successful payment not found for the given payment id")]
|
#[error(error_type= ErrorType::ObjectNotFound, code = "RE_05", message = "Successful payment not found for the given payment id")]
|
||||||
SuccessfulPaymentNotFound,
|
SuccessfulPaymentNotFound,
|
||||||
|
#[error(error_type = ErrorType::ObjectNotFound, code = "RE_05", message = "The connector provided in the request is incorrect or not available")]
|
||||||
|
IncorrectConnectorNameGiven,
|
||||||
#[error(error_type = ErrorType::ObjectNotFound, code = "RE_05", message = "Address does not exist in our records.")]
|
#[error(error_type = ErrorType::ObjectNotFound, code = "RE_05", message = "Address does not exist in our records.")]
|
||||||
AddressNotFound,
|
AddressNotFound,
|
||||||
#[error(error_type = ErrorType::ValidationError, code = "RE_03", message = "Mandate Validation Failed" )]
|
#[error(error_type = ErrorType::ValidationError, code = "RE_03", message = "Mandate Validation Failed" )]
|
||||||
@ -183,6 +185,7 @@ impl actix_web::ResponseError for ApiErrorResponse {
|
|||||||
| ApiErrorResponse::ClientSecretNotGiven
|
| ApiErrorResponse::ClientSecretNotGiven
|
||||||
| ApiErrorResponse::ClientSecretInvalid
|
| ApiErrorResponse::ClientSecretInvalid
|
||||||
| ApiErrorResponse::SuccessfulPaymentNotFound
|
| ApiErrorResponse::SuccessfulPaymentNotFound
|
||||||
|
| ApiErrorResponse::IncorrectConnectorNameGiven
|
||||||
| ApiErrorResponse::ResourceIdNotFound
|
| ApiErrorResponse::ResourceIdNotFound
|
||||||
| ApiErrorResponse::AddressNotFound => StatusCode::BAD_REQUEST, // 400
|
| ApiErrorResponse::AddressNotFound => StatusCode::BAD_REQUEST, // 400
|
||||||
ApiErrorResponse::DuplicateMerchantAccount
|
ApiErrorResponse::DuplicateMerchantAccount
|
||||||
|
|||||||
@ -25,15 +25,14 @@ use crate::{
|
|||||||
payments,
|
payments,
|
||||||
},
|
},
|
||||||
db::StorageInterface,
|
db::StorageInterface,
|
||||||
logger,
|
logger, pii,
|
||||||
pii::{Email, Secret},
|
|
||||||
routes::AppState,
|
routes::AppState,
|
||||||
scheduler::utils as pt_utils,
|
scheduler::utils as pt_utils,
|
||||||
services,
|
services,
|
||||||
types::{
|
types::{
|
||||||
self,
|
self,
|
||||||
api::{self, PaymentIdTypeExt, PaymentsResponse, PaymentsRetrieveRequest},
|
api::{self, enums as api_enums},
|
||||||
storage::{self, enums, ProcessTrackerExt},
|
storage::{self, enums as storage_enums},
|
||||||
transformers::ForeignInto,
|
transformers::ForeignInto,
|
||||||
},
|
},
|
||||||
utils::{self, OptionExt},
|
utils::{self, OptionExt},
|
||||||
@ -45,6 +44,7 @@ pub async fn payments_operation_core<F, Req, Op, FData>(
|
|||||||
merchant_account: storage::MerchantAccount,
|
merchant_account: storage::MerchantAccount,
|
||||||
operation: Op,
|
operation: Op,
|
||||||
req: Req,
|
req: Req,
|
||||||
|
use_connector: Option<api_enums::Connector>,
|
||||||
call_connector_action: CallConnectorAction,
|
call_connector_action: CallConnectorAction,
|
||||||
) -> RouterResult<(PaymentData<F>, Req, Option<storage::Customer>)>
|
) -> RouterResult<(PaymentData<F>, Req, Option<storage::Customer>)>
|
||||||
where
|
where
|
||||||
@ -106,6 +106,7 @@ where
|
|||||||
validate_result.storage_scheme,
|
validate_result.storage_scheme,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
payment_data.payment_method_data = payment_method_data;
|
payment_data.payment_method_data = payment_method_data;
|
||||||
if let Some(token) = payment_token {
|
if let Some(token) = payment_token {
|
||||||
payment_data.token = Some(token)
|
payment_data.token = Some(token)
|
||||||
@ -113,7 +114,7 @@ where
|
|||||||
|
|
||||||
let connector_details = operation
|
let connector_details = operation
|
||||||
.to_domain()?
|
.to_domain()?
|
||||||
.get_connector(&merchant_account, state)
|
.get_connector(&merchant_account, state, use_connector)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
if let api::ConnectorCallType::Single(ref connector) = connector_details {
|
if let api::ConnectorCallType::Single(ref connector) = connector_details {
|
||||||
@ -175,6 +176,7 @@ pub async fn payments_core<F, Res, Req, Op, FData>(
|
|||||||
operation: Op,
|
operation: Op,
|
||||||
req: Req,
|
req: Req,
|
||||||
auth_flow: services::AuthFlow,
|
auth_flow: services::AuthFlow,
|
||||||
|
use_connector: Option<api_enums::Connector>,
|
||||||
call_connector_action: CallConnectorAction,
|
call_connector_action: CallConnectorAction,
|
||||||
) -> RouterResponse<Res>
|
) -> RouterResponse<Res>
|
||||||
where
|
where
|
||||||
@ -199,9 +201,11 @@ where
|
|||||||
merchant_account,
|
merchant_account,
|
||||||
operation.clone(),
|
operation.clone(),
|
||||||
req,
|
req,
|
||||||
|
use_connector,
|
||||||
call_connector_action,
|
call_connector_action,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Res::generate_response(
|
Res::generate_response(
|
||||||
Some(req),
|
Some(req),
|
||||||
payment_data,
|
payment_data,
|
||||||
@ -220,7 +224,7 @@ fn is_start_pay<Op: Debug>(operation: &Op) -> bool {
|
|||||||
pub async fn handle_payments_redirect_response<'a, F>(
|
pub async fn handle_payments_redirect_response<'a, F>(
|
||||||
state: &AppState,
|
state: &AppState,
|
||||||
merchant_account: storage::MerchantAccount,
|
merchant_account: storage::MerchantAccount,
|
||||||
req: PaymentsRetrieveRequest,
|
req: api::PaymentsRetrieveRequest,
|
||||||
) -> RouterResponse<api::RedirectionResponse>
|
) -> RouterResponse<api::RedirectionResponse>
|
||||||
where
|
where
|
||||||
F: Send + Clone + 'a,
|
F: Send + Clone + 'a,
|
||||||
@ -229,11 +233,10 @@ where
|
|||||||
|
|
||||||
let query_params = req.param.clone().get_required_value("param")?;
|
let query_params = req.param.clone().get_required_value("param")?;
|
||||||
|
|
||||||
let resource_id = req.resource_id.get_payment_intent_id().change_context(
|
let resource_id = api::PaymentIdTypeExt::get_payment_intent_id(&req.resource_id)
|
||||||
errors::ApiErrorResponse::MissingRequiredField {
|
.change_context(errors::ApiErrorResponse::MissingRequiredField {
|
||||||
field_name: "payment_id".to_string(),
|
field_name: "payment_id".to_string(),
|
||||||
},
|
})?;
|
||||||
)?;
|
|
||||||
|
|
||||||
let connector_data = api::ConnectorData::get_connector_by_name(
|
let connector_data = api::ConnectorData::get_connector_by_name(
|
||||||
&state.conf.connectors,
|
&state.conf.connectors,
|
||||||
@ -277,15 +280,16 @@ where
|
|||||||
pub async fn payments_response_for_redirection_flows<'a>(
|
pub async fn payments_response_for_redirection_flows<'a>(
|
||||||
state: &AppState,
|
state: &AppState,
|
||||||
merchant_account: storage::MerchantAccount,
|
merchant_account: storage::MerchantAccount,
|
||||||
req: PaymentsRetrieveRequest,
|
req: api::PaymentsRetrieveRequest,
|
||||||
flow_type: CallConnectorAction,
|
flow_type: CallConnectorAction,
|
||||||
) -> RouterResponse<PaymentsResponse> {
|
) -> RouterResponse<api::PaymentsResponse> {
|
||||||
payments_core::<api::PSync, api::PaymentsResponse, _, _, _>(
|
payments_core::<api::PSync, api::PaymentsResponse, _, _, _>(
|
||||||
state,
|
state,
|
||||||
merchant_account,
|
merchant_account,
|
||||||
payments::PaymentStatus,
|
payments::PaymentStatus,
|
||||||
req,
|
req,
|
||||||
services::api::AuthFlow::Merchant,
|
services::api::AuthFlow::Merchant,
|
||||||
|
None,
|
||||||
flow_type,
|
flow_type,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@ -433,7 +437,7 @@ where
|
|||||||
pub enum CallConnectorAction {
|
pub enum CallConnectorAction {
|
||||||
Trigger,
|
Trigger,
|
||||||
Avoid,
|
Avoid,
|
||||||
StatusUpdate(enums::AttemptStatus),
|
StatusUpdate(storage_enums::AttemptStatus),
|
||||||
HandleResponse(Vec<u8>),
|
HandleResponse(Vec<u8>),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -453,7 +457,7 @@ where
|
|||||||
pub payment_attempt: storage::PaymentAttempt,
|
pub payment_attempt: storage::PaymentAttempt,
|
||||||
pub connector_response: storage::ConnectorResponse,
|
pub connector_response: storage::ConnectorResponse,
|
||||||
pub amount: api::Amount,
|
pub amount: api::Amount,
|
||||||
pub currency: enums::Currency,
|
pub currency: storage_enums::Currency,
|
||||||
pub mandate_id: Option<String>,
|
pub mandate_id: Option<String>,
|
||||||
pub setup_mandate: Option<api::MandateData>,
|
pub setup_mandate: Option<api::MandateData>,
|
||||||
pub address: PaymentAddress,
|
pub address: PaymentAddress,
|
||||||
@ -463,21 +467,21 @@ where
|
|||||||
pub payment_method_data: Option<api::PaymentMethod>,
|
pub payment_method_data: Option<api::PaymentMethod>,
|
||||||
pub refunds: Vec<storage::Refund>,
|
pub refunds: Vec<storage::Refund>,
|
||||||
pub sessions_token: Vec<api::SessionToken>,
|
pub sessions_token: Vec<api::SessionToken>,
|
||||||
pub card_cvc: Option<Secret<String>>,
|
pub card_cvc: Option<pii::Secret<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct CustomerDetails {
|
pub struct CustomerDetails {
|
||||||
pub customer_id: Option<String>,
|
pub customer_id: Option<String>,
|
||||||
pub name: Option<masking::Secret<String, masking::WithType>>,
|
pub name: Option<masking::Secret<String, masking::WithType>>,
|
||||||
pub email: Option<masking::Secret<String, Email>>,
|
pub email: Option<masking::Secret<String, pii::Email>>,
|
||||||
pub phone: Option<masking::Secret<String, masking::WithType>>,
|
pub phone: Option<masking::Secret<String, masking::WithType>>,
|
||||||
pub phone_country_code: Option<String>,
|
pub phone_country_code: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn if_not_create_change_operation<'a, Op, F>(
|
pub fn if_not_create_change_operation<'a, Op, F>(
|
||||||
is_update: bool,
|
is_update: bool,
|
||||||
status: enums::IntentStatus,
|
status: storage_enums::IntentStatus,
|
||||||
current: &'a Op,
|
current: &'a Op,
|
||||||
) -> BoxedOperation<F, api::PaymentsRequest>
|
) -> BoxedOperation<F, api::PaymentsRequest>
|
||||||
where
|
where
|
||||||
@ -486,9 +490,9 @@ where
|
|||||||
&'a Op: Operation<F, api::PaymentsRequest>,
|
&'a Op: Operation<F, api::PaymentsRequest>,
|
||||||
{
|
{
|
||||||
match status {
|
match status {
|
||||||
enums::IntentStatus::RequiresConfirmation
|
storage_enums::IntentStatus::RequiresConfirmation
|
||||||
| enums::IntentStatus::RequiresCustomerAction
|
| storage_enums::IntentStatus::RequiresCustomerAction
|
||||||
| enums::IntentStatus::RequiresPaymentMethod => {
|
| storage_enums::IntentStatus::RequiresPaymentMethod => {
|
||||||
if is_update {
|
if is_update {
|
||||||
Box::new(&PaymentUpdate)
|
Box::new(&PaymentUpdate)
|
||||||
} else {
|
} else {
|
||||||
@ -525,7 +529,7 @@ pub fn should_call_connector<Op: Debug, F: Clone>(
|
|||||||
"PaymentStart" => {
|
"PaymentStart" => {
|
||||||
!matches!(
|
!matches!(
|
||||||
payment_data.payment_intent.status,
|
payment_data.payment_intent.status,
|
||||||
enums::IntentStatus::Failed | enums::IntentStatus::Succeeded
|
storage_enums::IntentStatus::Failed | storage_enums::IntentStatus::Succeeded
|
||||||
) && payment_data
|
) && payment_data
|
||||||
.connector_response
|
.connector_response
|
||||||
.authentication_data
|
.authentication_data
|
||||||
@ -534,20 +538,20 @@ pub fn should_call_connector<Op: Debug, F: Clone>(
|
|||||||
"PaymentStatus" => {
|
"PaymentStatus" => {
|
||||||
matches!(
|
matches!(
|
||||||
payment_data.payment_intent.status,
|
payment_data.payment_intent.status,
|
||||||
enums::IntentStatus::Failed
|
storage_enums::IntentStatus::Failed
|
||||||
| enums::IntentStatus::Processing
|
| storage_enums::IntentStatus::Processing
|
||||||
| enums::IntentStatus::Succeeded
|
| storage_enums::IntentStatus::Succeeded
|
||||||
| enums::IntentStatus::RequiresCustomerAction
|
| storage_enums::IntentStatus::RequiresCustomerAction
|
||||||
) && payment_data.force_sync.unwrap_or(false)
|
) && payment_data.force_sync.unwrap_or(false)
|
||||||
}
|
}
|
||||||
"PaymentCancel" => matches!(
|
"PaymentCancel" => matches!(
|
||||||
payment_data.payment_intent.status,
|
payment_data.payment_intent.status,
|
||||||
enums::IntentStatus::RequiresCapture
|
storage_enums::IntentStatus::RequiresCapture
|
||||||
),
|
),
|
||||||
"PaymentCapture" => {
|
"PaymentCapture" => {
|
||||||
matches!(
|
matches!(
|
||||||
payment_data.payment_intent.status,
|
payment_data.payment_intent.status,
|
||||||
enums::IntentStatus::RequiresCapture
|
storage_enums::IntentStatus::RequiresCapture
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
"PaymentSession" => true,
|
"PaymentSession" => true,
|
||||||
@ -602,13 +606,14 @@ pub async fn add_process_sync_task(
|
|||||||
&payment_attempt.txn_id,
|
&payment_attempt.txn_id,
|
||||||
&payment_attempt.merchant_id,
|
&payment_attempt.merchant_id,
|
||||||
);
|
);
|
||||||
let process_tracker_entry = storage::ProcessTracker::make_process_tracker_new(
|
let process_tracker_entry =
|
||||||
process_tracker_id,
|
<storage::ProcessTracker as storage::ProcessTrackerExt>::make_process_tracker_new(
|
||||||
task,
|
process_tracker_id,
|
||||||
runner,
|
task,
|
||||||
tracking_data,
|
runner,
|
||||||
schedule_time,
|
tracking_data,
|
||||||
)?;
|
schedule_time,
|
||||||
|
)?;
|
||||||
|
|
||||||
db.insert_process(process_tracker_entry).await?;
|
db.insert_process(process_tracker_entry).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@ -620,43 +620,52 @@ pub async fn get_customer_from_details(
|
|||||||
pub async fn get_connector_default(
|
pub async fn get_connector_default(
|
||||||
merchant_account: &storage::MerchantAccount,
|
merchant_account: &storage::MerchantAccount,
|
||||||
state: &AppState,
|
state: &AppState,
|
||||||
|
request_connector: Option<api_enums::Connector>,
|
||||||
) -> CustomResult<api::ConnectorCallType, errors::ApiErrorResponse> {
|
) -> CustomResult<api::ConnectorCallType, errors::ApiErrorResponse> {
|
||||||
let connectors = &state.conf.connectors;
|
let connectors = &state.conf.connectors;
|
||||||
let vec_val: Vec<serde_json::Value> = merchant_account
|
if let Some(connector) = request_connector {
|
||||||
.custom_routing_rules
|
let connector_data = api::ConnectorData::get_connector_by_name(
|
||||||
.clone()
|
connectors,
|
||||||
.parse_value("CustomRoutingRulesVec")
|
&connector.to_string(),
|
||||||
.change_context(errors::ConnectorError::RoutingRulesParsingError)
|
api::GetToken::Connector,
|
||||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
)?;
|
||||||
let custom_routing_rules: api::CustomRoutingRules = vec_val[0]
|
Ok(api::ConnectorCallType::Single(connector_data))
|
||||||
.clone()
|
} else {
|
||||||
.parse_value("CustomRoutingRules")
|
let vec_val: Vec<serde_json::Value> = merchant_account
|
||||||
.change_context(errors::ConnectorError::RoutingRulesParsingError)
|
.custom_routing_rules
|
||||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
.clone()
|
||||||
let connector_names = custom_routing_rules
|
.parse_value("CustomRoutingRulesVec")
|
||||||
.connectors_pecking_order
|
.change_context(errors::ConnectorError::RoutingRulesParsingError)
|
||||||
.unwrap_or_else(|| vec!["stripe".to_string()]);
|
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||||
|
let custom_routing_rules: api::CustomRoutingRules = vec_val[0]
|
||||||
|
.clone()
|
||||||
|
.parse_value("CustomRoutingRules")
|
||||||
|
.change_context(errors::ConnectorError::RoutingRulesParsingError)
|
||||||
|
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||||
|
let connector_names = custom_routing_rules
|
||||||
|
.connectors_pecking_order
|
||||||
|
.unwrap_or_else(|| vec!["stripe".to_string()]);
|
||||||
|
|
||||||
//use routing rules if configured by merchant else query MCA as per PM
|
//use routing rules if configured by merchant else query MCA as per PM
|
||||||
let connector_list: types::ConnectorsList = types::ConnectorsList {
|
let connector_list: types::ConnectorsList = types::ConnectorsList {
|
||||||
connectors: connector_names,
|
connectors: connector_names,
|
||||||
};
|
};
|
||||||
|
|
||||||
let connector_name = connector_list
|
let connector_name = connector_list
|
||||||
.connectors
|
.connectors
|
||||||
.first()
|
.first()
|
||||||
.get_required_value("connectors")
|
.get_required_value("connectors")
|
||||||
.change_context(errors::ConnectorError::FailedToObtainPreferredConnector)
|
.change_context(errors::ConnectorError::FailedToObtainPreferredConnector)
|
||||||
.change_context(errors::ApiErrorResponse::InternalServerError)?
|
.change_context(errors::ApiErrorResponse::InternalServerError)?
|
||||||
.as_str();
|
.as_str();
|
||||||
|
|
||||||
let connector_data = api::ConnectorData::get_connector_by_name(
|
let connector_data = api::ConnectorData::get_connector_by_name(
|
||||||
connectors,
|
connectors,
|
||||||
connector_name,
|
connector_name,
|
||||||
api::GetToken::Connector,
|
api::GetToken::Connector,
|
||||||
)?;
|
)?;
|
||||||
|
Ok(api::ConnectorCallType::Single(connector_data))
|
||||||
Ok(api::ConnectorCallType::Single(connector_data))
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
|
|||||||
@ -30,7 +30,8 @@ use crate::{
|
|||||||
pii::Secret,
|
pii::Secret,
|
||||||
routes::AppState,
|
routes::AppState,
|
||||||
types::{
|
types::{
|
||||||
self, api,
|
self,
|
||||||
|
api::{self, enums as api_enums},
|
||||||
storage::{self, enums},
|
storage::{self, enums},
|
||||||
PaymentsResponseData,
|
PaymentsResponseData,
|
||||||
},
|
},
|
||||||
@ -138,6 +139,7 @@ pub trait Domain<F: Clone, R>: Send + Sync {
|
|||||||
&'a self,
|
&'a self,
|
||||||
merchant_account: &storage::MerchantAccount,
|
merchant_account: &storage::MerchantAccount,
|
||||||
state: &AppState,
|
state: &AppState,
|
||||||
|
request_connector: Option<api_enums::Connector>,
|
||||||
) -> CustomResult<api::ConnectorCallType, errors::ApiErrorResponse>;
|
) -> CustomResult<api::ConnectorCallType, errors::ApiErrorResponse>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,8 +206,9 @@ where
|
|||||||
&'a self,
|
&'a self,
|
||||||
merchant_account: &storage::MerchantAccount,
|
merchant_account: &storage::MerchantAccount,
|
||||||
state: &AppState,
|
state: &AppState,
|
||||||
|
request_connector: Option<api_enums::Connector>,
|
||||||
) -> CustomResult<api::ConnectorCallType, errors::ApiErrorResponse> {
|
) -> CustomResult<api::ConnectorCallType, errors::ApiErrorResponse> {
|
||||||
helpers::get_connector_default(merchant_account, state).await
|
helpers::get_connector_default(merchant_account, state, request_connector).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
@ -291,8 +294,9 @@ where
|
|||||||
&'a self,
|
&'a self,
|
||||||
merchant_account: &storage::MerchantAccount,
|
merchant_account: &storage::MerchantAccount,
|
||||||
state: &AppState,
|
state: &AppState,
|
||||||
|
request_connector: Option<api_enums::Connector>,
|
||||||
) -> CustomResult<api::ConnectorCallType, errors::ApiErrorResponse> {
|
) -> CustomResult<api::ConnectorCallType, errors::ApiErrorResponse> {
|
||||||
helpers::get_connector_default(merchant_account, state).await
|
helpers::get_connector_default(merchant_account, state, request_connector).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,7 +354,8 @@ where
|
|||||||
&'a self,
|
&'a self,
|
||||||
merchant_account: &storage::MerchantAccount,
|
merchant_account: &storage::MerchantAccount,
|
||||||
state: &AppState,
|
state: &AppState,
|
||||||
|
request_connector: Option<api_enums::Connector>,
|
||||||
) -> CustomResult<api::ConnectorCallType, errors::ApiErrorResponse> {
|
) -> CustomResult<api::ConnectorCallType, errors::ApiErrorResponse> {
|
||||||
helpers::get_connector_default(merchant_account, state).await
|
helpers::get_connector_default(merchant_account, state, request_connector).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@ use crate::{
|
|||||||
routes::AppState,
|
routes::AppState,
|
||||||
types::{
|
types::{
|
||||||
self,
|
self,
|
||||||
api::{self, PaymentIdTypeExt},
|
api::{self, enums as api_enums, PaymentIdTypeExt},
|
||||||
storage::{self, enums},
|
storage::{self, enums},
|
||||||
transformers::ForeignInto,
|
transformers::ForeignInto,
|
||||||
},
|
},
|
||||||
@ -243,8 +243,9 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentConfirm {
|
|||||||
&'a self,
|
&'a self,
|
||||||
merchant_account: &storage::MerchantAccount,
|
merchant_account: &storage::MerchantAccount,
|
||||||
state: &AppState,
|
state: &AppState,
|
||||||
|
request_connector: Option<api_enums::Connector>,
|
||||||
) -> CustomResult<api::ConnectorCallType, errors::ApiErrorResponse> {
|
) -> CustomResult<api::ConnectorCallType, errors::ApiErrorResponse> {
|
||||||
helpers::get_connector_default(merchant_account, state).await
|
helpers::get_connector_default(merchant_account, state, request_connector).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,7 +19,7 @@ use crate::{
|
|||||||
routes::AppState,
|
routes::AppState,
|
||||||
types::{
|
types::{
|
||||||
self,
|
self,
|
||||||
api::{self, PaymentIdTypeExt},
|
api::{self, enums as api_enums, PaymentIdTypeExt},
|
||||||
storage::{
|
storage::{
|
||||||
self,
|
self,
|
||||||
enums::{self, IntentStatus},
|
enums::{self, IntentStatus},
|
||||||
@ -290,8 +290,9 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentCreate {
|
|||||||
&'a self,
|
&'a self,
|
||||||
merchant_account: &storage::MerchantAccount,
|
merchant_account: &storage::MerchantAccount,
|
||||||
state: &AppState,
|
state: &AppState,
|
||||||
|
request_connector: Option<api_enums::Connector>,
|
||||||
) -> CustomResult<api::ConnectorCallType, errors::ApiErrorResponse> {
|
) -> CustomResult<api::ConnectorCallType, errors::ApiErrorResponse> {
|
||||||
helpers::get_connector_default(merchant_account, state).await
|
helpers::get_connector_default(merchant_account, state, request_connector).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -265,8 +265,9 @@ where
|
|||||||
&'a self,
|
&'a self,
|
||||||
merchant_account: &storage::MerchantAccount,
|
merchant_account: &storage::MerchantAccount,
|
||||||
state: &AppState,
|
state: &AppState,
|
||||||
|
request_connector: Option<api_enums::Connector>,
|
||||||
) -> CustomResult<api::ConnectorCallType, errors::ApiErrorResponse> {
|
) -> CustomResult<api::ConnectorCallType, errors::ApiErrorResponse> {
|
||||||
helpers::get_connector_default(merchant_account, state).await
|
helpers::get_connector_default(merchant_account, state, request_connector).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@ use crate::{
|
|||||||
pii::Secret,
|
pii::Secret,
|
||||||
routes::AppState,
|
routes::AppState,
|
||||||
types::{
|
types::{
|
||||||
api::{self, PaymentIdTypeExt},
|
api::{self, enums as api_enums, PaymentIdTypeExt},
|
||||||
storage::{self, enums},
|
storage::{self, enums},
|
||||||
transformers::ForeignInto,
|
transformers::ForeignInto,
|
||||||
},
|
},
|
||||||
@ -257,6 +257,7 @@ where
|
|||||||
&'a self,
|
&'a self,
|
||||||
merchant_account: &storage::MerchantAccount,
|
merchant_account: &storage::MerchantAccount,
|
||||||
state: &AppState,
|
state: &AppState,
|
||||||
|
_request_connector: Option<api_enums::Connector>,
|
||||||
) -> RouterResult<api::ConnectorCallType> {
|
) -> RouterResult<api::ConnectorCallType> {
|
||||||
let connectors = &state.conf.connectors;
|
let connectors = &state.conf.connectors;
|
||||||
let db = &state.store;
|
let db = &state.store;
|
||||||
|
|||||||
@ -15,7 +15,7 @@ use crate::{
|
|||||||
pii::Secret,
|
pii::Secret,
|
||||||
routes::AppState,
|
routes::AppState,
|
||||||
types::{
|
types::{
|
||||||
api::{self, PaymentIdTypeExt},
|
api::{self, enums as api_enums, PaymentIdTypeExt},
|
||||||
storage::{self, enums, Customer},
|
storage::{self, enums, Customer},
|
||||||
transformers::ForeignInto,
|
transformers::ForeignInto,
|
||||||
},
|
},
|
||||||
@ -265,7 +265,8 @@ where
|
|||||||
&'a self,
|
&'a self,
|
||||||
merchant_account: &storage::MerchantAccount,
|
merchant_account: &storage::MerchantAccount,
|
||||||
state: &AppState,
|
state: &AppState,
|
||||||
|
request_connector: Option<api_enums::Connector>,
|
||||||
) -> CustomResult<api::ConnectorCallType, errors::ApiErrorResponse> {
|
) -> CustomResult<api::ConnectorCallType, errors::ApiErrorResponse> {
|
||||||
helpers::get_connector_default(merchant_account, state).await
|
helpers::get_connector_default(merchant_account, state, request_connector).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,7 +15,7 @@ use crate::{
|
|||||||
db::StorageInterface,
|
db::StorageInterface,
|
||||||
routes::AppState,
|
routes::AppState,
|
||||||
types::{
|
types::{
|
||||||
api,
|
api::{self, enums as api_enums},
|
||||||
storage::{self, enums},
|
storage::{self, enums},
|
||||||
transformers::ForeignInto,
|
transformers::ForeignInto,
|
||||||
},
|
},
|
||||||
@ -117,8 +117,9 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentStatus {
|
|||||||
&'a self,
|
&'a self,
|
||||||
merchant_account: &storage::MerchantAccount,
|
merchant_account: &storage::MerchantAccount,
|
||||||
state: &AppState,
|
state: &AppState,
|
||||||
|
request_connector: Option<api_enums::Connector>,
|
||||||
) -> CustomResult<api::ConnectorCallType, errors::ApiErrorResponse> {
|
) -> CustomResult<api::ConnectorCallType, errors::ApiErrorResponse> {
|
||||||
helpers::get_connector_default(merchant_account, state).await
|
helpers::get_connector_default(merchant_account, state, request_connector).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@ use crate::{
|
|||||||
db::StorageInterface,
|
db::StorageInterface,
|
||||||
routes::AppState,
|
routes::AppState,
|
||||||
types::{
|
types::{
|
||||||
api::{self, PaymentIdTypeExt},
|
api::{self, enums as api_enums, PaymentIdTypeExt},
|
||||||
storage::{self, enums},
|
storage::{self, enums},
|
||||||
transformers::ForeignInto,
|
transformers::ForeignInto,
|
||||||
},
|
},
|
||||||
@ -237,8 +237,9 @@ impl<F: Clone + Send> Domain<F, api::PaymentsRequest> for PaymentUpdate {
|
|||||||
&'a self,
|
&'a self,
|
||||||
merchant_account: &storage::MerchantAccount,
|
merchant_account: &storage::MerchantAccount,
|
||||||
state: &AppState,
|
state: &AppState,
|
||||||
|
request_connector: Option<api_enums::Connector>,
|
||||||
) -> CustomResult<api::ConnectorCallType, errors::ApiErrorResponse> {
|
) -> CustomResult<api::ConnectorCallType, errors::ApiErrorResponse> {
|
||||||
helpers::get_connector_default(merchant_account, state).await
|
helpers::get_connector_default(merchant_account, state, request_connector).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -52,6 +52,7 @@ async fn payments_incoming_webhook_flow(
|
|||||||
param: None,
|
param: None,
|
||||||
},
|
},
|
||||||
services::AuthFlow::Merchant,
|
services::AuthFlow::Merchant,
|
||||||
|
None,
|
||||||
consume_or_trigger_flow,
|
consume_or_trigger_flow,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
|||||||
@ -46,6 +46,7 @@ pub async fn payments_create(
|
|||||||
|state, merchant_account, req| {
|
|state, merchant_account, req| {
|
||||||
// TODO: Change for making it possible for the flow to be inferred internally or through validation layer
|
// TODO: Change for making it possible for the flow to be inferred internally or through validation layer
|
||||||
async {
|
async {
|
||||||
|
let connector = req.connector;
|
||||||
match req.amount.as_ref() {
|
match req.amount.as_ref() {
|
||||||
Some(api_types::Amount::Value(_)) | None => {
|
Some(api_types::Amount::Value(_)) | None => {
|
||||||
payments::payments_core::<Authorize, PaymentsResponse, _, _, _>(
|
payments::payments_core::<Authorize, PaymentsResponse, _, _, _>(
|
||||||
@ -54,10 +55,12 @@ pub async fn payments_create(
|
|||||||
payments::PaymentCreate,
|
payments::PaymentCreate,
|
||||||
req,
|
req,
|
||||||
api::AuthFlow::Merchant,
|
api::AuthFlow::Merchant,
|
||||||
|
connector,
|
||||||
payments::CallConnectorAction::Trigger,
|
payments::CallConnectorAction::Trigger,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(api_types::Amount::Zero) => {
|
Some(api_types::Amount::Zero) => {
|
||||||
payments::payments_core::<Verify, PaymentsResponse, _, _, _>(
|
payments::payments_core::<Verify, PaymentsResponse, _, _, _>(
|
||||||
state,
|
state,
|
||||||
@ -65,6 +68,7 @@ pub async fn payments_create(
|
|||||||
payments::PaymentCreate,
|
payments::PaymentCreate,
|
||||||
req,
|
req,
|
||||||
api::AuthFlow::Merchant,
|
api::AuthFlow::Merchant,
|
||||||
|
connector,
|
||||||
payments::CallConnectorAction::Trigger,
|
payments::CallConnectorAction::Trigger,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@ -100,6 +104,7 @@ pub async fn payments_start(
|
|||||||
payments::operations::PaymentStart,
|
payments::operations::PaymentStart,
|
||||||
req,
|
req,
|
||||||
api::AuthFlow::Client,
|
api::AuthFlow::Client,
|
||||||
|
None,
|
||||||
payments::CallConnectorAction::Trigger,
|
payments::CallConnectorAction::Trigger,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -140,6 +145,7 @@ pub async fn payments_retrieve(
|
|||||||
payments::PaymentStatus,
|
payments::PaymentStatus,
|
||||||
req,
|
req,
|
||||||
api::AuthFlow::Merchant,
|
api::AuthFlow::Merchant,
|
||||||
|
None,
|
||||||
payments::CallConnectorAction::Trigger,
|
payments::CallConnectorAction::Trigger,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -179,12 +185,14 @@ pub async fn payments_update(
|
|||||||
&req,
|
&req,
|
||||||
payload,
|
payload,
|
||||||
|state, merchant_account, req| {
|
|state, merchant_account, req| {
|
||||||
|
let connector = req.connector;
|
||||||
payments::payments_core::<Authorize, PaymentsResponse, _, _, _>(
|
payments::payments_core::<Authorize, PaymentsResponse, _, _, _>(
|
||||||
state,
|
state,
|
||||||
merchant_account,
|
merchant_account,
|
||||||
payments::PaymentUpdate,
|
payments::PaymentUpdate,
|
||||||
req,
|
req,
|
||||||
auth_flow,
|
auth_flow,
|
||||||
|
connector,
|
||||||
payments::CallConnectorAction::Trigger,
|
payments::CallConnectorAction::Trigger,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -223,12 +231,14 @@ pub async fn payments_confirm(
|
|||||||
&req,
|
&req,
|
||||||
payload,
|
payload,
|
||||||
|state, merchant_account, req| {
|
|state, merchant_account, req| {
|
||||||
|
let connector = req.connector;
|
||||||
payments::payments_core::<Authorize, PaymentsResponse, _, _, _>(
|
payments::payments_core::<Authorize, PaymentsResponse, _, _, _>(
|
||||||
state,
|
state,
|
||||||
merchant_account,
|
merchant_account,
|
||||||
payments::PaymentConfirm,
|
payments::PaymentConfirm,
|
||||||
req,
|
req,
|
||||||
auth_flow,
|
auth_flow,
|
||||||
|
connector,
|
||||||
payments::CallConnectorAction::Trigger,
|
payments::CallConnectorAction::Trigger,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -261,6 +271,7 @@ pub(crate) async fn payments_capture(
|
|||||||
payments::PaymentCapture,
|
payments::PaymentCapture,
|
||||||
payload,
|
payload,
|
||||||
api::AuthFlow::Merchant,
|
api::AuthFlow::Merchant,
|
||||||
|
None,
|
||||||
payments::CallConnectorAction::Trigger,
|
payments::CallConnectorAction::Trigger,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -288,6 +299,7 @@ pub(crate) async fn payments_connector_session(
|
|||||||
payments::PaymentSession,
|
payments::PaymentSession,
|
||||||
payload,
|
payload,
|
||||||
api::AuthFlow::Merchant,
|
api::AuthFlow::Merchant,
|
||||||
|
None,
|
||||||
payments::CallConnectorAction::Trigger,
|
payments::CallConnectorAction::Trigger,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -347,6 +359,7 @@ pub async fn payments_cancel(
|
|||||||
payments::PaymentCancel,
|
payments::PaymentCancel,
|
||||||
req,
|
req,
|
||||||
api::AuthFlow::Merchant,
|
api::AuthFlow::Merchant,
|
||||||
|
None,
|
||||||
payments::CallConnectorAction::Trigger,
|
payments::CallConnectorAction::Trigger,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|||||||
@ -41,6 +41,7 @@ impl ProcessTrackerWorkflow for PaymentsSyncWorkflow {
|
|||||||
merchant_account.clone(),
|
merchant_account.clone(),
|
||||||
operations::PaymentStatus,
|
operations::PaymentStatus,
|
||||||
tracking_data.clone(),
|
tracking_data.clone(),
|
||||||
|
None,
|
||||||
payment_flows::CallConnectorAction::Trigger,
|
payment_flows::CallConnectorAction::Trigger,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|||||||
@ -13,9 +13,9 @@ pub mod transformers;
|
|||||||
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
pub use api_models::enums::Connector;
|
||||||
use error_stack::{IntoReport, ResultExt};
|
use error_stack::{IntoReport, ResultExt};
|
||||||
|
|
||||||
pub use self::connector::Connector;
|
|
||||||
use self::{api::payments, storage::enums as storage_enums};
|
use self::{api::payments, storage::enums as storage_enums};
|
||||||
pub use crate::core::payments::PaymentAddress;
|
pub use crate::core::payments::PaymentAddress;
|
||||||
use crate::{core::errors, services};
|
use crate::{core::errors, services};
|
||||||
|
|||||||
@ -17,7 +17,7 @@ use crate::{
|
|||||||
connector,
|
connector,
|
||||||
core::errors::{self, CustomResult},
|
core::errors::{self, CustomResult},
|
||||||
services::ConnectorRedirectResponse,
|
services::ConnectorRedirectResponse,
|
||||||
types,
|
types::{self, api::enums as api_enums},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait ConnectorCommon {
|
pub trait ConnectorCommon {
|
||||||
@ -82,6 +82,12 @@ pub enum ConnectorCallType {
|
|||||||
Multiple(Vec<ConnectorData>),
|
Multiple(Vec<ConnectorData>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ConnectorCallType {
|
||||||
|
pub fn is_single(&self) -> bool {
|
||||||
|
matches!(self, Self::Single(_))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ConnectorData {
|
impl ConnectorData {
|
||||||
pub fn get_connector_by_name(
|
pub fn get_connector_by_name(
|
||||||
connectors: &Connectors,
|
connectors: &Connectors,
|
||||||
@ -89,7 +95,7 @@ impl ConnectorData {
|
|||||||
connector_type: GetToken,
|
connector_type: GetToken,
|
||||||
) -> CustomResult<ConnectorData, errors::ApiErrorResponse> {
|
) -> CustomResult<ConnectorData, errors::ApiErrorResponse> {
|
||||||
let connector = Self::convert_connector(connectors, name)?;
|
let connector = Self::convert_connector(connectors, name)?;
|
||||||
let connector_name = types::Connector::from_str(name)
|
let connector_name = api_enums::Connector::from_str(name)
|
||||||
.into_report()
|
.into_report()
|
||||||
.change_context(errors::ConnectorError::InvalidConnectorName)
|
.change_context(errors::ConnectorError::InvalidConnectorName)
|
||||||
.attach_printable_lazy(|| format!("unable to parse connector name {connector:?}"))
|
.attach_printable_lazy(|| format!("unable to parse connector name {connector:?}"))
|
||||||
|
|||||||
@ -1,14 +1 @@
|
|||||||
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, strum::Display, strum::EnumString)]
|
|
||||||
#[strum(serialize_all = "snake_case")]
|
|
||||||
pub enum Connector {
|
|
||||||
Adyen,
|
|
||||||
Stripe,
|
|
||||||
Checkout,
|
|
||||||
Aci,
|
|
||||||
Authorizedotnet,
|
|
||||||
Braintree,
|
|
||||||
Klarna,
|
|
||||||
Applepay,
|
|
||||||
#[default]
|
|
||||||
Dummy,
|
|
||||||
}
|
|
||||||
|
|||||||
@ -289,6 +289,7 @@ async fn payments_create_core() {
|
|||||||
)),
|
)),
|
||||||
merchant_id: Some("jarnura".to_string()),
|
merchant_id: Some("jarnura".to_string()),
|
||||||
amount: Some(6540.into()),
|
amount: Some(6540.into()),
|
||||||
|
connector: None,
|
||||||
currency: Some("USD".to_string()),
|
currency: Some("USD".to_string()),
|
||||||
capture_method: Some(api_enums::CaptureMethod::Automatic),
|
capture_method: Some(api_enums::CaptureMethod::Automatic),
|
||||||
amount_to_capture: Some(6540),
|
amount_to_capture: Some(6540),
|
||||||
@ -354,6 +355,7 @@ async fn payments_create_core() {
|
|||||||
payments::PaymentCreate,
|
payments::PaymentCreate,
|
||||||
req,
|
req,
|
||||||
services::AuthFlow::Merchant,
|
services::AuthFlow::Merchant,
|
||||||
|
None,
|
||||||
payments::CallConnectorAction::Trigger,
|
payments::CallConnectorAction::Trigger,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@ -446,6 +448,7 @@ async fn payments_create_core_adyen_no_redirect() {
|
|||||||
payment_id: Some(api::PaymentIdType::PaymentIntentId(payment_id.clone())),
|
payment_id: Some(api::PaymentIdType::PaymentIntentId(payment_id.clone())),
|
||||||
merchant_id: Some(merchant_id.clone()),
|
merchant_id: Some(merchant_id.clone()),
|
||||||
amount: Some(6540.into()),
|
amount: Some(6540.into()),
|
||||||
|
connector: None,
|
||||||
currency: Some("USD".to_string()),
|
currency: Some("USD".to_string()),
|
||||||
capture_method: Some(api_enums::CaptureMethod::Automatic),
|
capture_method: Some(api_enums::CaptureMethod::Automatic),
|
||||||
amount_to_capture: Some(6540),
|
amount_to_capture: Some(6540),
|
||||||
@ -510,6 +513,7 @@ async fn payments_create_core_adyen_no_redirect() {
|
|||||||
payments::PaymentCreate,
|
payments::PaymentCreate,
|
||||||
req,
|
req,
|
||||||
services::AuthFlow::Merchant,
|
services::AuthFlow::Merchant,
|
||||||
|
None,
|
||||||
payments::CallConnectorAction::Trigger,
|
payments::CallConnectorAction::Trigger,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
|||||||
@ -106,6 +106,7 @@ async fn payments_create_core() {
|
|||||||
payments::PaymentCreate,
|
payments::PaymentCreate,
|
||||||
req,
|
req,
|
||||||
services::AuthFlow::Merchant,
|
services::AuthFlow::Merchant,
|
||||||
|
None,
|
||||||
payments::CallConnectorAction::Trigger,
|
payments::CallConnectorAction::Trigger,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@ -201,6 +202,7 @@ async fn payments_create_core_adyen_no_redirect() {
|
|||||||
payment_id: Some(api::PaymentIdType::PaymentIntentId(payment_id.clone())),
|
payment_id: Some(api::PaymentIdType::PaymentIntentId(payment_id.clone())),
|
||||||
merchant_id: Some(merchant_id.clone()),
|
merchant_id: Some(merchant_id.clone()),
|
||||||
amount: Some(6540.into()),
|
amount: Some(6540.into()),
|
||||||
|
connector: None,
|
||||||
currency: Some("USD".to_string()),
|
currency: Some("USD".to_string()),
|
||||||
capture_method: Some(api_enums::CaptureMethod::Automatic),
|
capture_method: Some(api_enums::CaptureMethod::Automatic),
|
||||||
amount_to_capture: Some(6540),
|
amount_to_capture: Some(6540),
|
||||||
@ -265,6 +267,7 @@ async fn payments_create_core_adyen_no_redirect() {
|
|||||||
payments::PaymentCreate,
|
payments::PaymentCreate,
|
||||||
req,
|
req,
|
||||||
services::AuthFlow::Merchant,
|
services::AuthFlow::Merchant,
|
||||||
|
None,
|
||||||
payments::CallConnectorAction::Trigger,
|
payments::CallConnectorAction::Trigger,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
|||||||
Reference in New Issue
Block a user