mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-01 19:42:27 +08:00
refactor: Replace Bach with Application on every naming (#292)
This commit is contained in:
@ -40,6 +40,10 @@ locker_decryption_key2 = ""
|
|||||||
wallets = ["klarna", "braintree", "applepay"]
|
wallets = ["klarna", "braintree", "applepay"]
|
||||||
cards = ["stripe", "adyen", "authorizedotnet", "checkout", "braintree", "aci", "shift4", "cybersource", "worldpay"]
|
cards = ["stripe", "adyen", "authorizedotnet", "checkout", "braintree", "aci", "shift4", "cybersource", "worldpay"]
|
||||||
|
|
||||||
|
[refund]
|
||||||
|
max_attempts = 10
|
||||||
|
max_age = 365
|
||||||
|
|
||||||
[eph_key]
|
[eph_key]
|
||||||
validity = 1
|
validity = 1
|
||||||
|
|
||||||
|
|||||||
@ -89,6 +89,11 @@ locker_decryption_key1 = "" # private key 1 in pem format, corresponding public
|
|||||||
locker_decryption_key2 = "" # private key 2 in pem format, corresponding public key in basilisk
|
locker_decryption_key2 = "" # private key 2 in pem format, corresponding public key in basilisk
|
||||||
|
|
||||||
|
|
||||||
|
# Refund configuration
|
||||||
|
[refund]
|
||||||
|
max_attempts = 10 # Number of refund attempts allowed
|
||||||
|
max_age = 365 # Max age of a refund in days.
|
||||||
|
|
||||||
# Validity of an Ephemeral Key in Hours
|
# Validity of an Ephemeral Key in Hours
|
||||||
[eph_key]
|
[eph_key]
|
||||||
validity = 1
|
validity = 1
|
||||||
|
|||||||
@ -52,6 +52,10 @@ port = 6379
|
|||||||
cluster_enabled = true
|
cluster_enabled = true
|
||||||
cluster_urls = ["redis-queue:6379"]
|
cluster_urls = ["redis-queue:6379"]
|
||||||
|
|
||||||
|
[refund]
|
||||||
|
max_attempts = 10
|
||||||
|
max_age = 365
|
||||||
|
|
||||||
[connectors.aci]
|
[connectors.aci]
|
||||||
base_url = "https://eu-test.oppwa.com/"
|
base_url = "https://eu-test.oppwa.com/"
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
use router::{
|
use router::{
|
||||||
configs::settings::{CmdLineConf, Settings, Subcommand},
|
configs::settings::{CmdLineConf, Settings, Subcommand},
|
||||||
core::errors::{BachError, BachResult},
|
core::errors::{ApplicationError, ApplicationResult},
|
||||||
logger,
|
logger,
|
||||||
};
|
};
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
|
||||||
#[actix_web::main]
|
#[actix_web::main]
|
||||||
async fn main() -> BachResult<()> {
|
async fn main() -> ApplicationResult<()> {
|
||||||
// get commandline config before initializing config
|
// get commandline config before initializing config
|
||||||
let cmd_line = CmdLineConf::from_args();
|
let cmd_line = CmdLineConf::from_args();
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ async fn main() -> BachResult<()> {
|
|||||||
|
|
||||||
state.store.close().await;
|
state.store.close().await;
|
||||||
|
|
||||||
Err(BachError::from(std::io::Error::new(
|
Err(ApplicationError::from(std::io::Error::new(
|
||||||
std::io::ErrorKind::Other,
|
std::io::ErrorKind::Other,
|
||||||
"Server shut down",
|
"Server shut down",
|
||||||
)))
|
)))
|
||||||
|
|||||||
@ -21,7 +21,7 @@ pub async fn compatibility_api_wrap<'a, 'b, U, T, Q, F, Fut, S, E>(
|
|||||||
) -> HttpResponse
|
) -> HttpResponse
|
||||||
where
|
where
|
||||||
F: Fn(&'b routes::AppState, U, T) -> Fut,
|
F: Fn(&'b routes::AppState, U, T) -> Fut,
|
||||||
Fut: Future<Output = RouterResult<api::BachResponse<Q>>>,
|
Fut: Future<Output = RouterResult<api::ApplicationResponse<Q>>>,
|
||||||
Q: Serialize + std::fmt::Debug + 'a,
|
Q: Serialize + std::fmt::Debug + 'a,
|
||||||
S: From<Q> + Serialize,
|
S: From<Q> + Serialize,
|
||||||
E: From<errors::ApiErrorResponse> + Serialize + error_stack::Context + actix_web::ResponseError,
|
E: From<errors::ApiErrorResponse> + Serialize + error_stack::Context + actix_web::ResponseError,
|
||||||
@ -29,7 +29,7 @@ where
|
|||||||
{
|
{
|
||||||
let resp = api::server_wrap_util(state, request, payload, func, api_authentication).await;
|
let resp = api::server_wrap_util(state, request, payload, func, api_authentication).await;
|
||||||
match resp {
|
match resp {
|
||||||
Ok(api::BachResponse::Json(router_resp)) => {
|
Ok(api::ApplicationResponse::Json(router_resp)) => {
|
||||||
let pg_resp = S::try_from(router_resp);
|
let pg_resp = S::try_from(router_resp);
|
||||||
match pg_resp {
|
match pg_resp {
|
||||||
Ok(pg_resp) => match serde_json::to_string(&pg_resp) {
|
Ok(pg_resp) => match serde_json::to_string(&pg_resp) {
|
||||||
@ -51,9 +51,9 @@ where
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(api::BachResponse::StatusOk) => api::http_response_ok(),
|
Ok(api::ApplicationResponse::StatusOk) => api::http_response_ok(),
|
||||||
Ok(api::BachResponse::TextPlain(text)) => api::http_response_plaintext(text),
|
Ok(api::ApplicationResponse::TextPlain(text)) => api::http_response_plaintext(text),
|
||||||
Ok(api::BachResponse::JsonForRedirection(response)) => {
|
Ok(api::ApplicationResponse::JsonForRedirection(response)) => {
|
||||||
match serde_json::to_string(&response) {
|
match serde_json::to_string(&response) {
|
||||||
Ok(res) => api::http_redirect_response(res, response),
|
Ok(res) => api::http_redirect_response(res, response),
|
||||||
Err(_) => api::http_response_err(
|
Err(_) => api::http_response_err(
|
||||||
@ -65,7 +65,7 @@ where
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(api::BachResponse::Form(form_data)) => api::build_redirection_form(&form_data)
|
Ok(api::ApplicationResponse::Form(form_data)) => api::build_redirection_form(&form_data)
|
||||||
.respond_to(request)
|
.respond_to(request)
|
||||||
.map_into_boxed_body(),
|
.map_into_boxed_body(),
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
|
|||||||
@ -42,6 +42,10 @@ jwt_secret="secret"
|
|||||||
[eph_key]
|
[eph_key]
|
||||||
validity = 1
|
validity = 1
|
||||||
|
|
||||||
|
[refund]
|
||||||
|
max_attempts = 10
|
||||||
|
max_age = 365
|
||||||
|
|
||||||
[scheduler]
|
[scheduler]
|
||||||
stream = "SCHEDULER_STREAM"
|
stream = "SCHEDULER_STREAM"
|
||||||
consumer_group = "SCHEDULER_GROUP"
|
consumer_group = "SCHEDULER_GROUP"
|
||||||
|
|||||||
@ -7,7 +7,7 @@ use serde::Deserialize;
|
|||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
core::errors::{BachError, BachResult},
|
core::errors::{ApplicationError, ApplicationResult},
|
||||||
env::{self, logger, Env},
|
env::{self, logger, Env},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -42,6 +42,7 @@ pub struct Settings {
|
|||||||
pub keys: Keys, //remove this during refactoring
|
pub keys: Keys, //remove this during refactoring
|
||||||
pub locker: Locker,
|
pub locker: Locker,
|
||||||
pub connectors: Connectors,
|
pub connectors: Connectors,
|
||||||
|
pub refund: Refund,
|
||||||
pub eph_key: EphemeralConfig,
|
pub eph_key: EphemeralConfig,
|
||||||
pub scheduler: Option<SchedulerSettings>,
|
pub scheduler: Option<SchedulerSettings>,
|
||||||
#[cfg(feature = "kv_store")]
|
#[cfg(feature = "kv_store")]
|
||||||
@ -67,6 +68,12 @@ pub struct Locker {
|
|||||||
pub basilisk_host: String,
|
pub basilisk_host: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Clone)]
|
||||||
|
pub struct Refund {
|
||||||
|
pub max_attempts: usize,
|
||||||
|
pub max_age: i64,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Clone)]
|
#[derive(Debug, Deserialize, Clone)]
|
||||||
pub struct EphemeralConfig {
|
pub struct EphemeralConfig {
|
||||||
pub validity: i64,
|
pub validity: i64,
|
||||||
@ -163,11 +170,11 @@ pub struct DrainerSettings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Settings {
|
impl Settings {
|
||||||
pub fn new() -> BachResult<Self> {
|
pub fn new() -> ApplicationResult<Self> {
|
||||||
Self::with_config_path(None)
|
Self::with_config_path(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_config_path(config_path: Option<PathBuf>) -> BachResult<Self> {
|
pub fn with_config_path(config_path: Option<PathBuf>) -> ApplicationResult<Self> {
|
||||||
let environment = env::which();
|
let environment = env::which();
|
||||||
let config_path = router_env::Config::config_path(&environment.to_string(), config_path);
|
let config_path = router_env::Config::config_path(&environment.to_string(), config_path);
|
||||||
|
|
||||||
@ -199,7 +206,7 @@ impl Settings {
|
|||||||
serde_path_to_error::deserialize(config).map_err(|error| {
|
serde_path_to_error::deserialize(config).map_err(|error| {
|
||||||
logger::error!(%error, "Unable to deserialize application configuration");
|
logger::error!(%error, "Unable to deserialize application configuration");
|
||||||
eprintln!("Unable to deserialize application configuration: {error}");
|
eprintln!("Unable to deserialize application configuration: {error}");
|
||||||
BachError::from(error.into_inner())
|
ApplicationError::from(error.into_inner())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -720,8 +720,9 @@ impl api::IncomingWebhook for Adyen {
|
|||||||
|
|
||||||
fn get_webhook_api_response(
|
fn get_webhook_api_response(
|
||||||
&self,
|
&self,
|
||||||
) -> CustomResult<services::api::BachResponse<serde_json::Value>, errors::ConnectorError> {
|
) -> CustomResult<services::api::ApplicationResponse<serde_json::Value>, errors::ConnectorError>
|
||||||
Ok(services::api::BachResponse::TextPlain(
|
{
|
||||||
|
Ok(services::api::ApplicationResponse::TextPlain(
|
||||||
"[accepted]".to_string(),
|
"[accepted]".to_string(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -78,7 +78,7 @@ pub async fn create_merchant_account(
|
|||||||
.map_err(|error| {
|
.map_err(|error| {
|
||||||
error.to_duplicate_response(errors::ApiErrorResponse::DuplicateMerchantAccount)
|
error.to_duplicate_response(errors::ApiErrorResponse::DuplicateMerchantAccount)
|
||||||
})?;
|
})?;
|
||||||
Ok(service_api::BachResponse::Json(response))
|
Ok(service_api::ApplicationResponse::Json(response))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_merchant_account(
|
pub async fn get_merchant_account(
|
||||||
@ -128,7 +128,7 @@ pub async fn get_merchant_account(
|
|||||||
publishable_key: merchant_account.publishable_key,
|
publishable_key: merchant_account.publishable_key,
|
||||||
locker_id: merchant_account.locker_id,
|
locker_id: merchant_account.locker_id,
|
||||||
};
|
};
|
||||||
Ok(service_api::BachResponse::Json(response))
|
Ok(service_api::ApplicationResponse::Json(response))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn merchant_account_update(
|
pub async fn merchant_account_update(
|
||||||
@ -226,7 +226,7 @@ pub async fn merchant_account_update(
|
|||||||
db.update_merchant(merchant_account, updated_merchant_account)
|
db.update_merchant(merchant_account, updated_merchant_account)
|
||||||
.await
|
.await
|
||||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||||
Ok(service_api::BachResponse::Json(response))
|
Ok(service_api::ApplicationResponse::Json(response))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn merchant_account_delete(
|
pub async fn merchant_account_delete(
|
||||||
@ -243,7 +243,7 @@ pub async fn merchant_account_delete(
|
|||||||
merchant_id,
|
merchant_id,
|
||||||
deleted: is_deleted,
|
deleted: is_deleted,
|
||||||
};
|
};
|
||||||
Ok(service_api::BachResponse::Json(response))
|
Ok(service_api::ApplicationResponse::Json(response))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_parent_merchant(
|
async fn get_parent_merchant(
|
||||||
@ -340,7 +340,7 @@ pub async fn create_payment_connector(
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
response.merchant_connector_id = Some(mca.merchant_connector_id);
|
response.merchant_connector_id = Some(mca.merchant_connector_id);
|
||||||
Ok(service_api::BachResponse::Json(response))
|
Ok(service_api::ApplicationResponse::Json(response))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn retrieve_payment_connector(
|
pub async fn retrieve_payment_connector(
|
||||||
@ -365,7 +365,9 @@ pub async fn retrieve_payment_connector(
|
|||||||
error.to_not_found_response(errors::ApiErrorResponse::MerchantConnectorAccountNotFound)
|
error.to_not_found_response(errors::ApiErrorResponse::MerchantConnectorAccountNotFound)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(service_api::BachResponse::Json(mca.foreign_try_into()?))
|
Ok(service_api::ApplicationResponse::Json(
|
||||||
|
mca.foreign_try_into()?,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn list_payment_connectors(
|
pub async fn list_payment_connectors(
|
||||||
@ -393,7 +395,7 @@ pub async fn list_payment_connectors(
|
|||||||
response.push(mca.foreign_try_into()?);
|
response.push(mca.foreign_try_into()?);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(service_api::BachResponse::Json(response))
|
Ok(service_api::ApplicationResponse::Json(response))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_payment_connector(
|
pub async fn update_payment_connector(
|
||||||
@ -460,7 +462,7 @@ pub async fn update_payment_connector(
|
|||||||
payment_methods_enabled: req.payment_methods_enabled,
|
payment_methods_enabled: req.payment_methods_enabled,
|
||||||
metadata: req.metadata,
|
metadata: req.metadata,
|
||||||
};
|
};
|
||||||
Ok(service_api::BachResponse::Json(response))
|
Ok(service_api::ApplicationResponse::Json(response))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_payment_connector(
|
pub async fn delete_payment_connector(
|
||||||
@ -489,5 +491,5 @@ pub async fn delete_payment_connector(
|
|||||||
merchant_connector_id,
|
merchant_connector_id,
|
||||||
deleted: is_deleted,
|
deleted: is_deleted,
|
||||||
};
|
};
|
||||||
Ok(service_api::BachResponse::Json(response))
|
Ok(service_api::ApplicationResponse::Json(response))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -80,7 +80,7 @@ pub async fn create_customer(
|
|||||||
let mut customer_response: customers::CustomerResponse = customer.into();
|
let mut customer_response: customers::CustomerResponse = customer.into();
|
||||||
customer_response.address = customer_data.address;
|
customer_response.address = customer_data.address;
|
||||||
|
|
||||||
Ok(services::BachResponse::Json(customer_response))
|
Ok(services::ApplicationResponse::Json(customer_response))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(db))]
|
#[instrument(skip(db))]
|
||||||
@ -94,7 +94,7 @@ pub async fn retrieve_customer(
|
|||||||
.await
|
.await
|
||||||
.map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::CustomerNotFound))?;
|
.map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::CustomerNotFound))?;
|
||||||
|
|
||||||
Ok(services::BachResponse::Json(response.into()))
|
Ok(services::ApplicationResponse::Json(response.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
@ -190,7 +190,7 @@ pub async fn delete_customer(
|
|||||||
address_deleted: true,
|
address_deleted: true,
|
||||||
payment_methods_deleted: true,
|
payment_methods_deleted: true,
|
||||||
};
|
};
|
||||||
Ok(services::BachResponse::Json(response))
|
Ok(services::ApplicationResponse::Json(response))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip(db))]
|
#[instrument(skip(db))]
|
||||||
@ -247,5 +247,7 @@ pub async fn update_customer(
|
|||||||
|
|
||||||
let mut customer_update_response: customers::CustomerResponse = response.into();
|
let mut customer_update_response: customers::CustomerResponse = response.into();
|
||||||
customer_update_response.address = update_customer.address;
|
customer_update_response.address = update_customer.address;
|
||||||
Ok(services::BachResponse::Json(customer_update_response))
|
Ok(services::ApplicationResponse::Json(
|
||||||
|
customer_update_response,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,11 +16,10 @@ pub use self::api_error_response::ApiErrorResponse;
|
|||||||
pub(crate) use self::utils::{ConnectorErrorExt, StorageErrorExt};
|
pub(crate) use self::utils::{ConnectorErrorExt, StorageErrorExt};
|
||||||
use crate::services;
|
use crate::services;
|
||||||
pub type RouterResult<T> = CustomResult<T, ApiErrorResponse>;
|
pub type RouterResult<T> = CustomResult<T, ApiErrorResponse>;
|
||||||
pub type RouterResponse<T> = CustomResult<services::BachResponse<T>, ApiErrorResponse>;
|
pub type RouterResponse<T> = CustomResult<services::ApplicationResponse<T>, ApiErrorResponse>;
|
||||||
|
|
||||||
// FIXME: Phase out BachResult and BachResponse
|
pub type ApplicationResult<T> = Result<T, ApplicationError>;
|
||||||
pub type BachResult<T> = Result<T, BachError>;
|
pub type ApplicationResponse<T> = ApplicationResult<services::ApplicationResponse<T>>;
|
||||||
pub type BachResponse<T> = BachResult<services::BachResponse<T>>;
|
|
||||||
|
|
||||||
macro_rules! impl_error_display {
|
macro_rules! impl_error_display {
|
||||||
($st: ident, $arg: tt) => {
|
($st: ident, $arg: tt) => {
|
||||||
@ -50,7 +49,7 @@ macro_rules! impl_error_type {
|
|||||||
// FIXME: Make this a derive macro instead
|
// FIXME: Make this a derive macro instead
|
||||||
macro_rules! router_error_error_stack_specific {
|
macro_rules! router_error_error_stack_specific {
|
||||||
($($path: ident)::+ < $st: ident >, $($path2:ident)::* ($($inner_path2:ident)::+ <$st2:ident>) ) => {
|
($($path: ident)::+ < $st: ident >, $($path2:ident)::* ($($inner_path2:ident)::+ <$st2:ident>) ) => {
|
||||||
impl From<$($path)::+ <$st>> for BachError {
|
impl From<$($path)::+ <$st>> for ApplicationError {
|
||||||
fn from(err: $($path)::+ <$st> ) -> Self {
|
fn from(err: $($path)::+ <$st> ) -> Self {
|
||||||
$($path2)::*(err)
|
$($path2)::*(err)
|
||||||
}
|
}
|
||||||
@ -58,7 +57,7 @@ macro_rules! router_error_error_stack_specific {
|
|||||||
};
|
};
|
||||||
|
|
||||||
($($path: ident)::+ <$($inner_path:ident)::+>, $($path2:ident)::* ($($inner_path2:ident)::+ <$st2:ident>) ) => {
|
($($path: ident)::+ <$($inner_path:ident)::+>, $($path2:ident)::* ($($inner_path2:ident)::+ <$st2:ident>) ) => {
|
||||||
impl<'a> From< $($path)::+ <$($inner_path)::+> > for BachError {
|
impl<'a> From< $($path)::+ <$($inner_path)::+> > for ApplicationError {
|
||||||
fn from(err: $($path)::+ <$($inner_path)::+> ) -> Self {
|
fn from(err: $($path)::+ <$($inner_path)::+> ) -> Self {
|
||||||
$($path2)::*(err)
|
$($path2)::*(err)
|
||||||
}
|
}
|
||||||
@ -114,7 +113,7 @@ impl_error_type!(EncryptionError, "Encryption error");
|
|||||||
impl_error_type!(UnexpectedError, "Unexpected error");
|
impl_error_type!(UnexpectedError, "Unexpected error");
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub enum BachError {
|
pub enum ApplicationError {
|
||||||
// Display's impl can be overridden by the attribute error marco.
|
// Display's impl can be overridden by the attribute error marco.
|
||||||
// Don't use Debug here, Debug gives error stack in response.
|
// Don't use Debug here, Debug gives error stack in response.
|
||||||
#[error("{{ error_description: Error while Authenticating, error_message: {0} }}")]
|
#[error("{{ error_description: Error while Authenticating, error_message: {0} }}")]
|
||||||
@ -150,32 +149,32 @@ pub enum BachError {
|
|||||||
|
|
||||||
router_error_error_stack_specific!(
|
router_error_error_stack_specific!(
|
||||||
error_stack::Report<storage_errors::DatabaseError>,
|
error_stack::Report<storage_errors::DatabaseError>,
|
||||||
BachError::EDatabaseError(error_stack::Report<DatabaseError>)
|
ApplicationError::EDatabaseError(error_stack::Report<DatabaseError>)
|
||||||
);
|
);
|
||||||
router_error_error_stack_specific!(
|
router_error_error_stack_specific!(
|
||||||
error_stack::Report<AuthenticationError>,
|
error_stack::Report<AuthenticationError>,
|
||||||
BachError::EAuthenticationError(error_stack::Report<AuthenticationError>)
|
ApplicationError::EAuthenticationError(error_stack::Report<AuthenticationError>)
|
||||||
);
|
);
|
||||||
router_error_error_stack_specific!(
|
router_error_error_stack_specific!(
|
||||||
error_stack::Report<UnexpectedError>,
|
error_stack::Report<UnexpectedError>,
|
||||||
BachError::EUnexpectedError(error_stack::Report<UnexpectedError>)
|
ApplicationError::EUnexpectedError(error_stack::Report<UnexpectedError>)
|
||||||
);
|
);
|
||||||
router_error_error_stack_specific!(
|
router_error_error_stack_specific!(
|
||||||
error_stack::Report<ParsingError>,
|
error_stack::Report<ParsingError>,
|
||||||
BachError::EParsingError(error_stack::Report<ParsingError>)
|
ApplicationError::EParsingError(error_stack::Report<ParsingError>)
|
||||||
);
|
);
|
||||||
router_error_error_stack_specific!(
|
router_error_error_stack_specific!(
|
||||||
error_stack::Report<EncryptionError>,
|
error_stack::Report<EncryptionError>,
|
||||||
BachError::EEncryptionError(error_stack::Report<EncryptionError>)
|
ApplicationError::EEncryptionError(error_stack::Report<EncryptionError>)
|
||||||
);
|
);
|
||||||
|
|
||||||
impl From<MetricsError> for BachError {
|
impl From<MetricsError> for ApplicationError {
|
||||||
fn from(err: MetricsError) -> Self {
|
fn from(err: MetricsError) -> Self {
|
||||||
Self::EMetrics(err)
|
Self::EMetrics(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<std::io::Error> for BachError {
|
impl From<std::io::Error> for ApplicationError {
|
||||||
fn from(err: std::io::Error) -> Self {
|
fn from(err: std::io::Error) -> Self {
|
||||||
Self::EIo(err)
|
Self::EIo(err)
|
||||||
}
|
}
|
||||||
@ -187,7 +186,7 @@ impl From<ring::error::Unspecified> for EncryptionError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ConfigError> for BachError {
|
impl From<ConfigError> for ApplicationError {
|
||||||
fn from(err: ConfigError) -> Self {
|
fn from(err: ConfigError) -> Self {
|
||||||
Self::ConfigurationError(err)
|
Self::ConfigurationError(err)
|
||||||
}
|
}
|
||||||
@ -202,7 +201,7 @@ fn error_response<T: Display>(err: &T) -> actix_web::HttpResponse {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ResponseError for BachError {
|
impl ResponseError for ApplicationError {
|
||||||
fn status_code(&self) -> StatusCode {
|
fn status_code(&self) -> StatusCode {
|
||||||
match self {
|
match self {
|
||||||
Self::EParsingError(_)
|
Self::EParsingError(_)
|
||||||
|
|||||||
@ -30,7 +30,7 @@ pub async fn get_mandate(
|
|||||||
.find_mandate_by_merchant_id_mandate_id(&merchant_account.merchant_id, &req.mandate_id)
|
.find_mandate_by_merchant_id_mandate_id(&merchant_account.merchant_id, &req.mandate_id)
|
||||||
.await
|
.await
|
||||||
.map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::MandateNotFound))?;
|
.map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::MandateNotFound))?;
|
||||||
Ok(services::BachResponse::Json(
|
Ok(services::ApplicationResponse::Json(
|
||||||
mandates::MandateResponse::from_db_mandate(state, mandate, &merchant_account).await?,
|
mandates::MandateResponse::from_db_mandate(state, mandate, &merchant_account).await?,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -52,7 +52,7 @@ pub async fn revoke_mandate(
|
|||||||
.await
|
.await
|
||||||
.map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::MandateNotFound))?;
|
.map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::MandateNotFound))?;
|
||||||
|
|
||||||
Ok(services::BachResponse::Json(
|
Ok(services::ApplicationResponse::Json(
|
||||||
mandates::MandateRevokedResponse {
|
mandates::MandateRevokedResponse {
|
||||||
mandate_id: mandate.mandate_id,
|
mandate_id: mandate.mandate_id,
|
||||||
status: mandate.mandate_status.foreign_into(),
|
status: mandate.mandate_status.foreign_into(),
|
||||||
@ -82,7 +82,7 @@ pub async fn get_customer_mandates(
|
|||||||
.await?,
|
.await?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Ok(services::BachResponse::Json(response_vec))
|
Ok(services::ApplicationResponse::Json(response_vec))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -92,7 +92,7 @@ pub async fn add_payment_method(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.map(services::BachResponse::Json)
|
.map(services::ApplicationResponse::Json)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
@ -383,7 +383,7 @@ pub async fn list_payment_methods(
|
|||||||
response
|
response
|
||||||
.is_empty()
|
.is_empty()
|
||||||
.then(|| Err(report!(errors::ApiErrorResponse::PaymentMethodNotFound)))
|
.then(|| Err(report!(errors::ApiErrorResponse::PaymentMethodNotFound)))
|
||||||
.unwrap_or(Ok(services::BachResponse::Json(response)))
|
.unwrap_or(Ok(services::ApplicationResponse::Json(response)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter_payment_methods(
|
fn filter_payment_methods(
|
||||||
@ -568,7 +568,7 @@ pub async fn list_customer_payment_method(
|
|||||||
customer_payment_methods: vec,
|
customer_payment_methods: vec,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(services::BachResponse::Json(response))
|
Ok(services::ApplicationResponse::Json(response))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_lookup_key_from_locker(
|
pub async fn get_lookup_key_from_locker(
|
||||||
@ -751,23 +751,27 @@ pub async fn retrieve_payment_method(
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
Ok(services::BachResponse::Json(api::PaymentMethodResponse {
|
Ok(services::ApplicationResponse::Json(
|
||||||
merchant_id: pm.merchant_id,
|
api::PaymentMethodResponse {
|
||||||
customer_id: Some(pm.customer_id),
|
merchant_id: pm.merchant_id,
|
||||||
payment_method_id: pm.payment_method_id,
|
customer_id: Some(pm.customer_id),
|
||||||
payment_method: pm.payment_method.foreign_into(),
|
payment_method_id: pm.payment_method_id,
|
||||||
payment_method_type: pm.payment_method_type.map(ForeignInto::foreign_into),
|
payment_method: pm.payment_method.foreign_into(),
|
||||||
payment_method_issuer: pm.payment_method_issuer,
|
payment_method_type: pm.payment_method_type.map(ForeignInto::foreign_into),
|
||||||
card,
|
payment_method_issuer: pm.payment_method_issuer,
|
||||||
metadata: pm.metadata,
|
card,
|
||||||
created: Some(pm.created_at),
|
metadata: pm.metadata,
|
||||||
payment_method_issuer_code: pm.payment_method_issuer_code.map(ForeignInto::foreign_into),
|
created: Some(pm.created_at),
|
||||||
recurring_enabled: false, //TODO
|
payment_method_issuer_code: pm
|
||||||
installment_payment_enabled: false, //TODO
|
.payment_method_issuer_code
|
||||||
payment_experience: Some(vec![
|
.map(ForeignInto::foreign_into),
|
||||||
api_models::payment_methods::PaymentExperience::RedirectToUrl,
|
recurring_enabled: false, //TODO
|
||||||
]), //TODO,
|
installment_payment_enabled: false, //TODO
|
||||||
}))
|
payment_experience: Some(vec![
|
||||||
|
api_models::payment_methods::PaymentExperience::RedirectToUrl,
|
||||||
|
]), //TODO,
|
||||||
|
},
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
@ -801,7 +805,7 @@ pub async fn delete_payment_method(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(services::BachResponse::Json(
|
Ok(services::ApplicationResponse::Json(
|
||||||
api::DeletePaymentMethodResponse {
|
api::DeletePaymentMethodResponse {
|
||||||
payment_method_id: pm.payment_method_id,
|
payment_method_id: pm.payment_method_id,
|
||||||
deleted: true,
|
deleted: true,
|
||||||
|
|||||||
@ -247,7 +247,7 @@ where
|
|||||||
|
|
||||||
let payments_response =
|
let payments_response =
|
||||||
match response.change_context(errors::ApiErrorResponse::NotImplemented)? {
|
match response.change_context(errors::ApiErrorResponse::NotImplemented)? {
|
||||||
services::BachResponse::Json(response) => Ok(response),
|
services::ApplicationResponse::Json(response) => Ok(response),
|
||||||
_ => Err(errors::ApiErrorResponse::InternalServerError)
|
_ => Err(errors::ApiErrorResponse::InternalServerError)
|
||||||
.into_report()
|
.into_report()
|
||||||
.attach_printable("Failed to get the response in json"),
|
.attach_printable("Failed to get the response in json"),
|
||||||
@ -261,7 +261,7 @@ where
|
|||||||
)
|
)
|
||||||
.attach_printable("No redirection response")?;
|
.attach_printable("No redirection response")?;
|
||||||
|
|
||||||
Ok(services::BachResponse::JsonForRedirection(result))
|
Ok(services::ApplicationResponse::JsonForRedirection(result))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn payments_response_for_redirection_flows<'a>(
|
pub async fn payments_response_for_redirection_flows<'a>(
|
||||||
@ -562,10 +562,12 @@ pub async fn list_payments(
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.map(ForeignInto::foreign_into)
|
.map(ForeignInto::foreign_into)
|
||||||
.collect();
|
.collect();
|
||||||
Ok(services::BachResponse::Json(api::PaymentListResponse {
|
Ok(services::ApplicationResponse::Json(
|
||||||
size: data.len(),
|
api::PaymentListResponse {
|
||||||
data,
|
size: data.len(),
|
||||||
}))
|
data,
|
||||||
|
},
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn add_process_sync_task(
|
pub async fn add_process_sync_task(
|
||||||
|
|||||||
@ -547,7 +547,7 @@ pub(crate) async fn call_payment_method(
|
|||||||
.await
|
.await
|
||||||
.attach_printable("Error on adding payment method")?;
|
.attach_printable("Error on adding payment method")?;
|
||||||
match resp {
|
match resp {
|
||||||
crate::services::BachResponse::Json(payment_method) => {
|
crate::services::ApplicationResponse::Json(payment_method) => {
|
||||||
Ok(payment_method)
|
Ok(payment_method)
|
||||||
}
|
}
|
||||||
_ => Err(report!(errors::ApiErrorResponse::InternalServerError)
|
_ => Err(report!(errors::ApiErrorResponse::InternalServerError)
|
||||||
@ -575,7 +575,9 @@ pub(crate) async fn call_payment_method(
|
|||||||
.await
|
.await
|
||||||
.attach_printable("Error on adding payment method")?;
|
.attach_printable("Error on adding payment method")?;
|
||||||
match resp {
|
match resp {
|
||||||
crate::services::BachResponse::Json(payment_method) => Ok(payment_method),
|
crate::services::ApplicationResponse::Json(payment_method) => {
|
||||||
|
Ok(payment_method)
|
||||||
|
}
|
||||||
_ => Err(report!(errors::ApiErrorResponse::InternalServerError)
|
_ => Err(report!(errors::ApiErrorResponse::InternalServerError)
|
||||||
.attach_printable("Error on adding payment method")),
|
.attach_printable("Error on adding payment method")),
|
||||||
}
|
}
|
||||||
@ -1156,7 +1158,7 @@ pub async fn make_ephemeral_key(
|
|||||||
.await
|
.await
|
||||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||||
.attach_printable("Unable to create ephemeral key")?;
|
.attach_printable("Unable to create ephemeral key")?;
|
||||||
Ok(services::BachResponse::Json(ek))
|
Ok(services::ApplicationResponse::Json(ek))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_ephemeral_key(
|
pub async fn delete_ephemeral_key(
|
||||||
@ -1168,7 +1170,7 @@ pub async fn delete_ephemeral_key(
|
|||||||
.await
|
.await
|
||||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||||
.attach_printable("Unable to delete ephemeral key")?;
|
.attach_printable("Unable to delete ephemeral key")?;
|
||||||
Ok(services::BachResponse::Json(ek))
|
Ok(services::ApplicationResponse::Json(ek))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_pg_redirect_response(
|
pub fn make_pg_redirect_response(
|
||||||
|
|||||||
@ -160,7 +160,7 @@ where
|
|||||||
_server: &Server,
|
_server: &Server,
|
||||||
_operation: Op,
|
_operation: Op,
|
||||||
) -> RouterResponse<Self> {
|
) -> RouterResponse<Self> {
|
||||||
Ok(services::BachResponse::Json(Self {
|
Ok(services::ApplicationResponse::Json(Self {
|
||||||
session_token: payment_data.sessions_token,
|
session_token: payment_data.sessions_token,
|
||||||
payment_id: payment_data.payment_attempt.payment_id,
|
payment_id: payment_data.payment_attempt.payment_id,
|
||||||
client_secret: payment_data
|
client_secret: payment_data
|
||||||
@ -186,7 +186,7 @@ where
|
|||||||
_server: &Server,
|
_server: &Server,
|
||||||
_operation: Op,
|
_operation: Op,
|
||||||
) -> RouterResponse<Self> {
|
) -> RouterResponse<Self> {
|
||||||
Ok(services::BachResponse::Json(Self {
|
Ok(services::ApplicationResponse::Json(Self {
|
||||||
verify_id: Some(data.payment_intent.payment_id),
|
verify_id: Some(data.payment_intent.payment_id),
|
||||||
merchant_id: Some(data.payment_intent.merchant_id),
|
merchant_id: Some(data.payment_intent.merchant_id),
|
||||||
client_secret: data.payment_intent.client_secret.map(masking::Secret::new),
|
client_secret: data.payment_intent.client_secret.map(masking::Secret::new),
|
||||||
@ -254,7 +254,7 @@ where
|
|||||||
let redirection_data = redirection_data.get_required_value("redirection_data")?;
|
let redirection_data = redirection_data.get_required_value("redirection_data")?;
|
||||||
let form: RedirectForm = serde_json::from_value(redirection_data)
|
let form: RedirectForm = serde_json::from_value(redirection_data)
|
||||||
.map_err(|_| errors::ApiErrorResponse::InternalServerError)?;
|
.map_err(|_| errors::ApiErrorResponse::InternalServerError)?;
|
||||||
services::BachResponse::Form(form)
|
services::ApplicationResponse::Form(form)
|
||||||
} else {
|
} else {
|
||||||
let mut response: api::PaymentsResponse = request
|
let mut response: api::PaymentsResponse = request
|
||||||
.try_into()
|
.try_into()
|
||||||
@ -271,7 +271,7 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
services::BachResponse::Json(
|
services::ApplicationResponse::Json(
|
||||||
response
|
response
|
||||||
.set_payment_id(Some(payment_attempt.payment_id))
|
.set_payment_id(Some(payment_attempt.payment_id))
|
||||||
.set_merchant_id(Some(payment_attempt.merchant_id))
|
.set_merchant_id(Some(payment_attempt.merchant_id))
|
||||||
@ -341,7 +341,7 @@ where
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => services::BachResponse::Json(api::PaymentsResponse {
|
None => services::ApplicationResponse::Json(api::PaymentsResponse {
|
||||||
payment_id: Some(payment_attempt.payment_id),
|
payment_id: Some(payment_attempt.payment_id),
|
||||||
merchant_id: Some(payment_attempt.merchant_id),
|
merchant_id: Some(payment_attempt.merchant_id),
|
||||||
status: payment_intent.status.foreign_into(),
|
status: payment_intent.status.foreign_into(),
|
||||||
|
|||||||
@ -2,9 +2,9 @@ pub mod validator;
|
|||||||
|
|
||||||
use error_stack::{report, IntoReport, ResultExt};
|
use error_stack::{report, IntoReport, ResultExt};
|
||||||
use router_env::{instrument, tracing};
|
use router_env::{instrument, tracing};
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
consts,
|
||||||
core::{
|
core::{
|
||||||
errors::{self, ConnectorErrorExt, RouterResponse, RouterResult, StorageErrorExt},
|
errors::{self, ConnectorErrorExt, RouterResponse, RouterResult, StorageErrorExt},
|
||||||
payments, utils as core_utils,
|
payments, utils as core_utils,
|
||||||
@ -45,9 +45,9 @@ pub async fn refund_create_core(
|
|||||||
.change_context(errors::ApiErrorResponse::SuccessfulPaymentNotFound)?;
|
.change_context(errors::ApiErrorResponse::SuccessfulPaymentNotFound)?;
|
||||||
|
|
||||||
// Amount is not passed in request refer from payment attempt.
|
// Amount is not passed in request refer from payment attempt.
|
||||||
amount = req.amount.unwrap_or(payment_attempt.amount); // FIXME: Need to that capture amount
|
amount = req.amount.unwrap_or(payment_attempt.amount); // [#298]: Need to that capture amount
|
||||||
|
|
||||||
//TODO: Can we change the flow based on some workflow idea
|
//[#299]: Can we change the flow based on some workflow idea
|
||||||
utils::when(amount <= 0, || {
|
utils::when(amount <= 0, || {
|
||||||
Err(report!(errors::ApiErrorResponse::InvalidDataFormat {
|
Err(report!(errors::ApiErrorResponse::InvalidDataFormat {
|
||||||
field_name: "amount".to_string(),
|
field_name: "amount".to_string(),
|
||||||
@ -82,7 +82,7 @@ pub async fn refund_create_core(
|
|||||||
req,
|
req,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map(services::BachResponse::Json)
|
.map(services::ApplicationResponse::Json)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
@ -180,7 +180,7 @@ where
|
|||||||
Fut: futures::Future<Output = RouterResult<T>>,
|
Fut: futures::Future<Output = RouterResult<T>>,
|
||||||
T: ForeignInto<refunds::RefundResponse>,
|
T: ForeignInto<refunds::RefundResponse>,
|
||||||
{
|
{
|
||||||
Ok(services::BachResponse::Json(
|
Ok(services::ApplicationResponse::Json(
|
||||||
f(state, merchant_account, refund_id).await?.foreign_into(),
|
f(state, merchant_account, refund_id).await?.foreign_into(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -337,7 +337,7 @@ pub async fn refund_update_core(
|
|||||||
.await
|
.await
|
||||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||||
|
|
||||||
Ok(services::BachResponse::Json(response.foreign_into()))
|
Ok(services::ApplicationResponse::Json(response.foreign_into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ********************************************** VALIDATIONS **********************************************
|
// ********************************************** VALIDATIONS **********************************************
|
||||||
@ -402,37 +402,52 @@ pub async fn validate_and_create_refund(
|
|||||||
.attach_printable("Failed to fetch refund")?;
|
.attach_printable("Failed to fetch refund")?;
|
||||||
currency = payment_attempt.currency.get_required_value("currency")?;
|
currency = payment_attempt.currency.get_required_value("currency")?;
|
||||||
|
|
||||||
// TODO: Add Connector Based Validation here.
|
//[#249]: Add Connector Based Validation here.
|
||||||
validator::validate_payment_order_age(&payment_intent.created_at).change_context(
|
validator::validate_payment_order_age(
|
||||||
errors::ApiErrorResponse::InvalidDataFormat {
|
&payment_intent.created_at,
|
||||||
field_name: "created_at".to_string(),
|
state.conf.refund.max_age,
|
||||||
expected_format: format!(
|
)
|
||||||
"created_at not older than {} days",
|
.change_context(errors::ApiErrorResponse::InvalidDataFormat {
|
||||||
validator::REFUND_MAX_AGE
|
field_name: "created_at".to_string(),
|
||||||
),
|
expected_format: format!(
|
||||||
},
|
"created_at not older than {} days",
|
||||||
)?;
|
state.conf.refund.max_age,
|
||||||
|
),
|
||||||
|
})?;
|
||||||
|
|
||||||
validator::validate_refund_amount(payment_attempt.amount, &all_refunds, refund_amount)
|
validator::validate_refund_amount(payment_attempt.amount, &all_refunds, refund_amount)
|
||||||
.change_context(errors::ApiErrorResponse::RefundAmountExceedsPaymentAmount)?;
|
.change_context(errors::ApiErrorResponse::RefundAmountExceedsPaymentAmount)?;
|
||||||
|
|
||||||
validator::validate_maximum_refund_against_payment_attempt(&all_refunds)
|
validator::validate_maximum_refund_against_payment_attempt(
|
||||||
.change_context(errors::ApiErrorResponse::MaximumRefundCount)?;
|
&all_refunds,
|
||||||
|
state.conf.refund.max_attempts,
|
||||||
|
)
|
||||||
|
.change_context(errors::ApiErrorResponse::MaximumRefundCount)?;
|
||||||
|
|
||||||
let connector = payment_attempt.connector.clone().ok_or_else(|| {
|
let connector = payment_attempt.connector.clone().ok_or_else(|| {
|
||||||
report!(errors::ApiErrorResponse::InternalServerError)
|
report!(errors::ApiErrorResponse::InternalServerError)
|
||||||
.attach_printable("connector not populated in payment attempt.")
|
.attach_printable("connector not populated in payment attempt.")
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
refund_create_req = mk_new_refund(
|
refund_create_req = storage::RefundNew::default()
|
||||||
req,
|
.set_refund_id(refund_id.to_string())
|
||||||
connector,
|
.set_internal_reference_id(utils::generate_id(consts::ID_LENGTH, "refid"))
|
||||||
payment_attempt,
|
.set_external_reference_id(Some(refund_id))
|
||||||
currency,
|
.set_payment_id(req.payment_id)
|
||||||
&refund_id,
|
.set_merchant_id(merchant_account.merchant_id.clone())
|
||||||
&merchant_account.merchant_id,
|
.set_connector_transaction_id(connecter_transaction_id.to_string())
|
||||||
refund_amount,
|
.set_connector(connector)
|
||||||
);
|
.set_refund_type(enums::RefundType::RegularRefund)
|
||||||
|
.set_total_amount(refund_amount)
|
||||||
|
.set_currency(currency)
|
||||||
|
.set_created_at(Some(common_utils::date_time::now()))
|
||||||
|
.set_modified_at(Some(common_utils::date_time::now()))
|
||||||
|
.set_refund_status(enums::RefundStatus::Pending)
|
||||||
|
.set_metadata(req.metadata)
|
||||||
|
.set_description(req.reason.clone())
|
||||||
|
.set_attempt_id(payment_attempt.attempt_id.clone())
|
||||||
|
.set_refund_reason(req.reason)
|
||||||
|
.to_owned();
|
||||||
|
|
||||||
refund = db
|
refund = db
|
||||||
.insert_refund(refund_create_req, merchant_account.storage_scheme)
|
.insert_refund(refund_create_req, merchant_account.storage_scheme)
|
||||||
@ -484,53 +499,11 @@ pub async fn refund_list(
|
|||||||
utils::when(data.is_empty(), || {
|
utils::when(data.is_empty(), || {
|
||||||
Err(errors::ApiErrorResponse::RefundNotFound)
|
Err(errors::ApiErrorResponse::RefundNotFound)
|
||||||
})?;
|
})?;
|
||||||
Ok(services::BachResponse::Json(
|
Ok(services::ApplicationResponse::Json(
|
||||||
api_models::refunds::RefundListResponse { data },
|
api_models::refunds::RefundListResponse { data },
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ********************************************** UTILS **********************************************
|
|
||||||
|
|
||||||
// FIXME: function should not have more than 3 arguments.
|
|
||||||
// Consider to use builder pattern.
|
|
||||||
#[instrument]
|
|
||||||
fn mk_new_refund(
|
|
||||||
request: refunds::RefundRequest,
|
|
||||||
connector: String,
|
|
||||||
payment_attempt: &storage::PaymentAttempt,
|
|
||||||
currency: enums::Currency,
|
|
||||||
refund_id: &str,
|
|
||||||
merchant_id: &str,
|
|
||||||
refund_amount: i64,
|
|
||||||
) -> storage::RefundNew {
|
|
||||||
let current_time = common_utils::date_time::now();
|
|
||||||
let connecter_transaction_id = match &payment_attempt.connector_transaction_id {
|
|
||||||
Some(id) => id,
|
|
||||||
None => "",
|
|
||||||
};
|
|
||||||
storage::RefundNew {
|
|
||||||
refund_id: refund_id.to_string(),
|
|
||||||
internal_reference_id: Uuid::new_v4().to_string(),
|
|
||||||
external_reference_id: Some(refund_id.to_string()),
|
|
||||||
payment_id: request.payment_id,
|
|
||||||
merchant_id: merchant_id.to_string(),
|
|
||||||
// FIXME: remove the default.
|
|
||||||
connector_transaction_id: connecter_transaction_id.to_string(),
|
|
||||||
connector,
|
|
||||||
refund_type: enums::RefundType::RegularRefund,
|
|
||||||
total_amount: refund_amount,
|
|
||||||
currency,
|
|
||||||
refund_amount,
|
|
||||||
created_at: Some(current_time),
|
|
||||||
modified_at: Some(current_time),
|
|
||||||
refund_status: enums::RefundStatus::Pending,
|
|
||||||
metadata: request.metadata,
|
|
||||||
description: request.reason,
|
|
||||||
attempt_id: payment_attempt.attempt_id.clone(),
|
|
||||||
..storage::RefundNew::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<F> TryFrom<types::RefundsRouterData<F>> for refunds::RefundResponse {
|
impl<F> TryFrom<types::RefundsRouterData<F>> for refunds::RefundResponse {
|
||||||
type Error = error_stack::Report<errors::ApiErrorResponse>;
|
type Error = error_stack::Report<errors::ApiErrorResponse>;
|
||||||
|
|
||||||
@ -548,7 +521,7 @@ impl<F> TryFrom<types::RefundsRouterData<F>> for refunds::RefundResponse {
|
|||||||
refund_id,
|
refund_id,
|
||||||
amount: data.request.amount / 100,
|
amount: data.request.amount / 100,
|
||||||
currency: data.request.currency.to_string(),
|
currency: data.request.currency.to_string(),
|
||||||
reason: Some("TODO: Not propagated".to_string()), // TODO: Not propagated
|
reason: data.request.reason,
|
||||||
status,
|
status,
|
||||||
metadata: None,
|
metadata: None,
|
||||||
error_message,
|
error_message,
|
||||||
@ -622,7 +595,7 @@ pub async fn schedule_refund_execution(
|
|||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// Sync the refund for status check
|
// Sync the refund for status check
|
||||||
//TODO: return refund status response
|
//[#300]: return refund status response
|
||||||
match refund_type {
|
match refund_type {
|
||||||
api_models::refunds::RefundType::Scheduled => {
|
api_models::refunds::RefundType::Scheduled => {
|
||||||
add_refund_sync_task(db, &refund, runner)
|
add_refund_sync_task(db, &refund, runner)
|
||||||
@ -661,25 +634,6 @@ pub async fn sync_refund_with_gateway_workflow(
|
|||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let merchant_account = state
|
|
||||||
.store
|
|
||||||
.find_merchant_account_by_merchant_id(&refund_core.merchant_id)
|
|
||||||
.await
|
|
||||||
.map_err(|error| {
|
|
||||||
error.to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
// FIXME we actually don't use this?
|
|
||||||
let _refund = state
|
|
||||||
.store
|
|
||||||
.find_refund_by_internal_reference_id_merchant_id(
|
|
||||||
&refund_core.refund_internal_reference_id,
|
|
||||||
&refund_core.merchant_id,
|
|
||||||
merchant_account.storage_scheme,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::RefundNotFound))?;
|
|
||||||
|
|
||||||
let merchant_account = state
|
let merchant_account = state
|
||||||
.store
|
.store
|
||||||
.find_merchant_account_by_merchant_id(&refund_core.merchant_id)
|
.find_merchant_account_by_merchant_id(&refund_core.merchant_id)
|
||||||
@ -763,7 +717,6 @@ pub async fn trigger_refund_execute_workflow(
|
|||||||
.await
|
.await
|
||||||
.map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::RefundNotFound))?;
|
.map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::RefundNotFound))?;
|
||||||
match (&refund.sent_to_gateway, &refund.refund_status) {
|
match (&refund.sent_to_gateway, &refund.refund_status) {
|
||||||
//FIXME: Conversion should come from trait
|
|
||||||
(false, enums::RefundStatus::Pending) => {
|
(false, enums::RefundStatus::Pending) => {
|
||||||
let merchant_account = db
|
let merchant_account = db
|
||||||
.find_merchant_account_by_merchant_id(&refund.merchant_id)
|
.find_merchant_account_by_merchant_id(&refund.merchant_id)
|
||||||
|
|||||||
@ -10,9 +10,6 @@ use crate::{
|
|||||||
utils,
|
utils,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(super) const REFUND_MAX_AGE: i64 = 365;
|
|
||||||
pub(super) const REFUND_MAX_ATTEMPTS: usize = 10;
|
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub enum RefundValidationError {
|
pub enum RefundValidationError {
|
||||||
#[error("The payment attempt was not successful")]
|
#[error("The payment attempt was not successful")]
|
||||||
@ -38,7 +35,6 @@ pub fn validate_success_transaction(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
//todo: max refund request count
|
|
||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
pub fn validate_refund_amount(
|
pub fn validate_refund_amount(
|
||||||
payment_attempt_amount: i64, // &storage::PaymentAttempt,
|
payment_attempt_amount: i64, // &storage::PaymentAttempt,
|
||||||
@ -71,11 +67,12 @@ pub fn validate_refund_amount(
|
|||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
pub fn validate_payment_order_age(
|
pub fn validate_payment_order_age(
|
||||||
created_at: &PrimitiveDateTime,
|
created_at: &PrimitiveDateTime,
|
||||||
|
refund_max_age: i64,
|
||||||
) -> CustomResult<(), RefundValidationError> {
|
) -> CustomResult<(), RefundValidationError> {
|
||||||
let current_time = common_utils::date_time::now();
|
let current_time = common_utils::date_time::now();
|
||||||
|
|
||||||
utils::when(
|
utils::when(
|
||||||
(current_time - *created_at).whole_days() > REFUND_MAX_AGE,
|
(current_time - *created_at).whole_days() > refund_max_age,
|
||||||
|| Err(report!(RefundValidationError::OrderExpired)),
|
|| Err(report!(RefundValidationError::OrderExpired)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -83,9 +80,9 @@ pub fn validate_payment_order_age(
|
|||||||
#[instrument(skip_all)]
|
#[instrument(skip_all)]
|
||||||
pub fn validate_maximum_refund_against_payment_attempt(
|
pub fn validate_maximum_refund_against_payment_attempt(
|
||||||
all_refunds: &[storage::Refund],
|
all_refunds: &[storage::Refund],
|
||||||
|
refund_max_attempts: usize,
|
||||||
) -> CustomResult<(), RefundValidationError> {
|
) -> CustomResult<(), RefundValidationError> {
|
||||||
// TODO: Make this configurable
|
utils::when(all_refunds.len() > refund_max_attempts, || {
|
||||||
utils::when(all_refunds.len() > REFUND_MAX_ATTEMPTS, || {
|
|
||||||
Err(report!(RefundValidationError::MaxRefundCountReached))
|
Err(report!(RefundValidationError::MaxRefundCountReached))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,7 +28,6 @@ pub async fn construct_refund_router_data<'a, F>(
|
|||||||
refund: &'a storage::Refund,
|
refund: &'a storage::Refund,
|
||||||
) -> RouterResult<types::RefundsRouterData<F>> {
|
) -> RouterResult<types::RefundsRouterData<F>> {
|
||||||
let db = &*state.store;
|
let db = &*state.store;
|
||||||
//TODO: everytime parsing the json may have impact?
|
|
||||||
let merchant_connector_account = db
|
let merchant_connector_account = db
|
||||||
.find_merchant_connector_account_by_merchant_id_connector(
|
.find_merchant_connector_account_by_merchant_id_connector(
|
||||||
&merchant_account.merchant_id,
|
&merchant_account.merchant_id,
|
||||||
@ -86,6 +85,7 @@ pub async fn construct_refund_router_data<'a, F>(
|
|||||||
refund_amount: refund.refund_amount,
|
refund_amount: refund.refund_amount,
|
||||||
currency,
|
currency,
|
||||||
amount,
|
amount,
|
||||||
|
reason: refund.refund_reason.clone(),
|
||||||
},
|
},
|
||||||
|
|
||||||
response: Ok(types::RefundsResponseData {
|
response: Ok(types::RefundsResponseData {
|
||||||
|
|||||||
@ -59,7 +59,7 @@ async fn payments_incoming_webhook_flow(
|
|||||||
.change_context(errors::WebhooksFlowError::PaymentsCoreFailed)?;
|
.change_context(errors::WebhooksFlowError::PaymentsCoreFailed)?;
|
||||||
|
|
||||||
match payments_response {
|
match payments_response {
|
||||||
services::BachResponse::Json(payments_response) => {
|
services::ApplicationResponse::Json(payments_response) => {
|
||||||
let payment_id = payments_response
|
let payment_id = payments_response
|
||||||
.payment_id
|
.payment_id
|
||||||
.clone()
|
.clone()
|
||||||
|
|||||||
@ -290,6 +290,7 @@ mod storage {
|
|||||||
created_at: new.created_at.unwrap_or_else(date_time::now),
|
created_at: new.created_at.unwrap_or_else(date_time::now),
|
||||||
updated_at: new.created_at.unwrap_or_else(date_time::now),
|
updated_at: new.created_at.unwrap_or_else(date_time::now),
|
||||||
description: new.description.clone(),
|
description: new.description.clone(),
|
||||||
|
refund_reason: new.refund_reason.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let field = format!(
|
let field = format!(
|
||||||
@ -640,6 +641,7 @@ impl RefundInterface for MockDb {
|
|||||||
created_at: new.created_at.unwrap_or(current_time),
|
created_at: new.created_at.unwrap_or(current_time),
|
||||||
updated_at: current_time,
|
updated_at: current_time,
|
||||||
description: new.description,
|
description: new.description,
|
||||||
|
refund_reason: new.refund_reason.clone(),
|
||||||
};
|
};
|
||||||
refunds.push(refund.clone());
|
refunds.push(refund.clone());
|
||||||
Ok(refund)
|
Ok(refund)
|
||||||
|
|||||||
@ -32,7 +32,7 @@ use routes::AppState;
|
|||||||
pub use self::env::logger;
|
pub use self::env::logger;
|
||||||
use crate::{
|
use crate::{
|
||||||
configs::settings::Settings,
|
configs::settings::Settings,
|
||||||
core::errors::{self, BachResult},
|
core::errors::{self, ApplicationResult},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "mimalloc")]
|
#[cfg(feature = "mimalloc")]
|
||||||
@ -110,7 +110,7 @@ pub fn mk_app(
|
|||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Unwrap used because without the value we can't start the server
|
/// Unwrap used because without the value we can't start the server
|
||||||
pub async fn start_server(conf: Settings) -> BachResult<(Server, AppState)> {
|
pub async fn start_server(conf: Settings) -> ApplicationResult<(Server, AppState)> {
|
||||||
logger::debug!(startup_config=?conf);
|
logger::debug!(startup_config=?conf);
|
||||||
let server = conf.server.clone();
|
let server = conf.server.clone();
|
||||||
let state = routes::AppState::new(conf).await;
|
let state = routes::AppState::new(conf).await;
|
||||||
|
|||||||
@ -320,7 +320,7 @@ async fn handle_response(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub enum BachResponse<R> {
|
pub enum ApplicationResponse<R> {
|
||||||
Json(R),
|
Json(R),
|
||||||
StatusOk,
|
StatusOk,
|
||||||
TextPlain(String),
|
TextPlain(String),
|
||||||
@ -329,11 +329,11 @@ pub enum BachResponse<R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Serialize)]
|
#[derive(Debug, Eq, PartialEq, Serialize)]
|
||||||
pub struct BachRedirectResponse {
|
pub struct ApplicationRedirectResponse {
|
||||||
pub url: String,
|
pub url: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&storage::PaymentAttempt> for BachRedirectResponse {
|
impl From<&storage::PaymentAttempt> for ApplicationRedirectResponse {
|
||||||
fn from(payment_attempt: &storage::PaymentAttempt) -> Self {
|
fn from(payment_attempt: &storage::PaymentAttempt) -> Self {
|
||||||
Self {
|
Self {
|
||||||
url: format!(
|
url: format!(
|
||||||
@ -376,7 +376,7 @@ pub async fn server_wrap_util<'a, 'b, U, T, Q, F, Fut>(
|
|||||||
payload: T,
|
payload: T,
|
||||||
func: F,
|
func: F,
|
||||||
api_auth: &dyn auth::AuthenticateAndFetch<U>,
|
api_auth: &dyn auth::AuthenticateAndFetch<U>,
|
||||||
) -> RouterResult<BachResponse<Q>>
|
) -> RouterResult<ApplicationResponse<Q>>
|
||||||
where
|
where
|
||||||
F: Fn(&'b AppState, U, T) -> Fut,
|
F: Fn(&'b AppState, U, T) -> Fut,
|
||||||
Fut: Future<Output = RouterResponse<Q>>,
|
Fut: Future<Output = RouterResponse<Q>>,
|
||||||
@ -402,7 +402,7 @@ pub async fn server_wrap<'a, 'b, T, U, Q, F, Fut>(
|
|||||||
) -> HttpResponse
|
) -> HttpResponse
|
||||||
where
|
where
|
||||||
F: Fn(&'b AppState, U, T) -> Fut,
|
F: Fn(&'b AppState, U, T) -> Fut,
|
||||||
Fut: Future<Output = RouterResult<BachResponse<Q>>>,
|
Fut: Future<Output = RouterResult<ApplicationResponse<Q>>>,
|
||||||
Q: Serialize + Debug + 'a,
|
Q: Serialize + Debug + 'a,
|
||||||
T: Debug,
|
T: Debug,
|
||||||
{
|
{
|
||||||
@ -415,7 +415,7 @@ where
|
|||||||
logger::info!(tag = ?Tag::BeginRequest);
|
logger::info!(tag = ?Tag::BeginRequest);
|
||||||
|
|
||||||
let res = match server_wrap_util(state, request, payload, func, api_auth).await {
|
let res = match server_wrap_util(state, request, payload, func, api_auth).await {
|
||||||
Ok(BachResponse::Json(response)) => match serde_json::to_string(&response) {
|
Ok(ApplicationResponse::Json(response)) => match serde_json::to_string(&response) {
|
||||||
Ok(res) => http_response_json(res),
|
Ok(res) => http_response_json(res),
|
||||||
Err(_) => http_response_err(
|
Err(_) => http_response_err(
|
||||||
r#"{
|
r#"{
|
||||||
@ -425,19 +425,21 @@ where
|
|||||||
}"#,
|
}"#,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
Ok(BachResponse::StatusOk) => http_response_ok(),
|
Ok(ApplicationResponse::StatusOk) => http_response_ok(),
|
||||||
Ok(BachResponse::TextPlain(text)) => http_response_plaintext(text),
|
Ok(ApplicationResponse::TextPlain(text)) => http_response_plaintext(text),
|
||||||
Ok(BachResponse::JsonForRedirection(response)) => match serde_json::to_string(&response) {
|
Ok(ApplicationResponse::JsonForRedirection(response)) => {
|
||||||
Ok(res) => http_redirect_response(res, response),
|
match serde_json::to_string(&response) {
|
||||||
Err(_) => http_response_err(
|
Ok(res) => http_redirect_response(res, response),
|
||||||
r#"{
|
Err(_) => http_response_err(
|
||||||
|
r#"{
|
||||||
"error": {
|
"error": {
|
||||||
"message": "Error serializing response from connector"
|
"message": "Error serializing response from connector"
|
||||||
}
|
}
|
||||||
}"#,
|
}"#,
|
||||||
),
|
),
|
||||||
},
|
}
|
||||||
Ok(BachResponse::Form(response)) => build_redirection_form(&response)
|
}
|
||||||
|
Ok(ApplicationResponse::Form(response)) => build_redirection_form(&response)
|
||||||
.respond_to(request)
|
.respond_to(request)
|
||||||
.map_into_boxed_body(),
|
.map_into_boxed_body(),
|
||||||
|
|
||||||
|
|||||||
@ -200,6 +200,7 @@ pub struct RefundsData {
|
|||||||
pub currency: storage_enums::Currency,
|
pub currency: storage_enums::Currency,
|
||||||
/// Amount for the payment against which this refund is issued
|
/// Amount for the payment against which this refund is issued
|
||||||
pub amount: i64,
|
pub amount: i64,
|
||||||
|
pub reason: Option<String>,
|
||||||
/// Amount to be refunded
|
/// Amount to be refunded
|
||||||
pub refund_amount: i64,
|
pub refund_amount: i64,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -136,7 +136,8 @@ pub trait IncomingWebhook: ConnectorCommon + Sync {
|
|||||||
|
|
||||||
fn get_webhook_api_response(
|
fn get_webhook_api_response(
|
||||||
&self,
|
&self,
|
||||||
) -> CustomResult<services::api::BachResponse<serde_json::Value>, errors::ConnectorError> {
|
) -> CustomResult<services::api::ApplicationResponse<serde_json::Value>, errors::ConnectorError>
|
||||||
Ok(services::api::BachResponse::StatusOk)
|
{
|
||||||
|
Ok(services::api::ApplicationResponse::StatusOk)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -91,6 +91,7 @@ fn construct_refund_router_data<F>() -> types::RefundsRouterData<F> {
|
|||||||
}),
|
}),
|
||||||
connector_transaction_id: String::new(),
|
connector_transaction_id: String::new(),
|
||||||
refund_amount: 100,
|
refund_amount: 100,
|
||||||
|
reason: None,
|
||||||
},
|
},
|
||||||
payment_method_id: None,
|
payment_method_id: None,
|
||||||
response: Err(types::ErrorResponse::default()),
|
response: Err(types::ErrorResponse::default()),
|
||||||
|
|||||||
@ -91,6 +91,7 @@ fn construct_refund_router_data<F>() -> types::RefundsRouterData<F> {
|
|||||||
}),
|
}),
|
||||||
connector_transaction_id: String::new(),
|
connector_transaction_id: String::new(),
|
||||||
refund_amount: 1,
|
refund_amount: 1,
|
||||||
|
reason: None,
|
||||||
},
|
},
|
||||||
response: Err(types::ErrorResponse::default()),
|
response: Err(types::ErrorResponse::default()),
|
||||||
payment_method_id: None,
|
payment_method_id: None,
|
||||||
|
|||||||
@ -88,6 +88,7 @@ fn construct_refund_router_data<F>() -> types::RefundsRouterData<F> {
|
|||||||
}),
|
}),
|
||||||
connector_transaction_id: String::new(),
|
connector_transaction_id: String::new(),
|
||||||
refund_amount: 10,
|
refund_amount: 10,
|
||||||
|
reason: None,
|
||||||
},
|
},
|
||||||
response: Err(types::ErrorResponse::default()),
|
response: Err(types::ErrorResponse::default()),
|
||||||
payment_method_id: None,
|
payment_method_id: None,
|
||||||
|
|||||||
@ -117,6 +117,7 @@ pub trait ConnectorActions: Connector {
|
|||||||
payment_method_data: types::api::PaymentMethod::Card(CCardType::default().0),
|
payment_method_data: types::api::PaymentMethod::Card(CCardType::default().0),
|
||||||
connector_transaction_id: transaction_id,
|
connector_transaction_id: transaction_id,
|
||||||
refund_amount: 100,
|
refund_amount: 100,
|
||||||
|
reason: None,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
call_connector(request, integration).await
|
call_connector(request, integration).await
|
||||||
@ -139,6 +140,7 @@ pub trait ConnectorActions: Connector {
|
|||||||
payment_method_data: types::api::PaymentMethod::Card(CCardType::default().0),
|
payment_method_data: types::api::PaymentMethod::Card(CCardType::default().0),
|
||||||
connector_transaction_id: transaction_id,
|
connector_transaction_id: transaction_id,
|
||||||
refund_amount: 100,
|
refund_amount: 100,
|
||||||
|
reason: None,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
call_connector(request, integration).await
|
call_connector(request, integration).await
|
||||||
@ -249,6 +251,7 @@ impl Default for PaymentRefundType {
|
|||||||
payment_method_data: types::api::PaymentMethod::Card(CCardType::default().0),
|
payment_method_data: types::api::PaymentMethod::Card(CCardType::default().0),
|
||||||
connector_transaction_id: String::new(),
|
connector_transaction_id: String::new(),
|
||||||
refund_amount: 100,
|
refund_amount: 100,
|
||||||
|
reason: None,
|
||||||
};
|
};
|
||||||
Self(data)
|
Self(data)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -347,7 +347,7 @@ async fn payments_create_core() {
|
|||||||
mandate_id: None,
|
mandate_id: None,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let expected_response = services::BachResponse::Json(expected_response);
|
let expected_response = services::ApplicationResponse::Json(expected_response);
|
||||||
let actual_response =
|
let actual_response =
|
||||||
payments::payments_core::<api::Authorize, api::PaymentsResponse, _, _, _>(
|
payments::payments_core::<api::Authorize, api::PaymentsResponse, _, _, _>(
|
||||||
&state,
|
&state,
|
||||||
@ -406,7 +406,7 @@ async fn payments_create_core() {
|
|||||||
// .update(&state.pg_conn, payment_intent_update)
|
// .update(&state.pg_conn, payment_intent_update)
|
||||||
// .unwrap();
|
// .unwrap();
|
||||||
|
|
||||||
// let expected_response = services::BachResponse::Form(services::RedirectForm {
|
// let expected_response = services::ApplicationResponse::Form(services::RedirectForm {
|
||||||
// url: "http://example.com/payments".to_string(),
|
// url: "http://example.com/payments".to_string(),
|
||||||
// method: services::Method::Post,
|
// method: services::Method::Post,
|
||||||
// form_fields: HashMap::from([("payment_id".to_string(), payment_id.clone())]),
|
// form_fields: HashMap::from([("payment_id".to_string(), payment_id.clone())]),
|
||||||
@ -491,7 +491,7 @@ async fn payments_create_core_adyen_no_redirect() {
|
|||||||
browser_info: None,
|
browser_info: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let expected_response = services::BachResponse::Json(api::PaymentsResponse {
|
let expected_response = services::ApplicationResponse::Json(api::PaymentsResponse {
|
||||||
payment_id: Some(payment_id.clone()),
|
payment_id: Some(payment_id.clone()),
|
||||||
status: api_enums::IntentStatus::Processing,
|
status: api_enums::IntentStatus::Processing,
|
||||||
amount: 6540,
|
amount: 6540,
|
||||||
|
|||||||
@ -98,7 +98,7 @@ async fn payments_create_core() {
|
|||||||
mandate_id: None,
|
mandate_id: None,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let expected_response = services::BachResponse::Json(expected_response);
|
let expected_response = services::ApplicationResponse::Json(expected_response);
|
||||||
let actual_response =
|
let actual_response =
|
||||||
router::core::payments::payments_core::<api::Authorize, api::PaymentsResponse, _, _, _>(
|
router::core::payments::payments_core::<api::Authorize, api::PaymentsResponse, _, _, _>(
|
||||||
&state,
|
&state,
|
||||||
@ -162,7 +162,7 @@ async fn payments_create_core() {
|
|||||||
// .await
|
// .await
|
||||||
// .unwrap();
|
// .unwrap();
|
||||||
//
|
//
|
||||||
// let expected_response = services::BachResponse::Form(services::RedirectForm {
|
// let expected_response = services::ApplicationResponse::Form(services::RedirectForm {
|
||||||
// url: "http://example.com/payments".to_string(),
|
// url: "http://example.com/payments".to_string(),
|
||||||
// method: services::Method::Post,
|
// method: services::Method::Post,
|
||||||
// form_fields: HashMap::from([("payment_id".to_string(), payment_id.clone())]),
|
// form_fields: HashMap::from([("payment_id".to_string(), payment_id.clone())]),
|
||||||
@ -245,7 +245,7 @@ async fn payments_create_core_adyen_no_redirect() {
|
|||||||
browser_info: None,
|
browser_info: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let expected_response = services::BachResponse::Json(api::PaymentsResponse {
|
let expected_response = services::ApplicationResponse::Json(api::PaymentsResponse {
|
||||||
payment_id: Some(payment_id.clone()),
|
payment_id: Some(payment_id.clone()),
|
||||||
status: api_enums::IntentStatus::Processing,
|
status: api_enums::IntentStatus::Processing,
|
||||||
amount: 6540,
|
amount: 6540,
|
||||||
|
|||||||
@ -31,6 +31,7 @@ pub struct Refund {
|
|||||||
pub updated_at: PrimitiveDateTime,
|
pub updated_at: PrimitiveDateTime,
|
||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
pub attempt_id: String,
|
pub attempt_id: String,
|
||||||
|
pub refund_reason: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
@ -43,6 +44,7 @@ pub struct Refund {
|
|||||||
router_derive::DebugAsDisplay,
|
router_derive::DebugAsDisplay,
|
||||||
serde::Serialize,
|
serde::Serialize,
|
||||||
serde::Deserialize,
|
serde::Deserialize,
|
||||||
|
router_derive::Setter,
|
||||||
)]
|
)]
|
||||||
#[diesel(table_name = refund)]
|
#[diesel(table_name = refund)]
|
||||||
pub struct RefundNew {
|
pub struct RefundNew {
|
||||||
@ -67,6 +69,7 @@ pub struct RefundNew {
|
|||||||
pub modified_at: Option<PrimitiveDateTime>,
|
pub modified_at: Option<PrimitiveDateTime>,
|
||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
pub attempt_id: String,
|
pub attempt_id: String,
|
||||||
|
pub refund_reason: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||||
|
|||||||
@ -327,6 +327,7 @@ diesel::table! {
|
|||||||
modified_at -> Timestamp,
|
modified_at -> Timestamp,
|
||||||
description -> Nullable<Varchar>,
|
description -> Nullable<Varchar>,
|
||||||
attempt_id -> Varchar,
|
attempt_id -> Varchar,
|
||||||
|
refund_reason -> Nullable<Varchar>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -34,6 +34,10 @@ basilisk_host = ""
|
|||||||
[eph_key]
|
[eph_key]
|
||||||
validity = 1
|
validity = 1
|
||||||
|
|
||||||
|
[refund]
|
||||||
|
max_attempts = 10
|
||||||
|
max_age = 365
|
||||||
|
|
||||||
[jwekey]
|
[jwekey]
|
||||||
locker_key_identifier1 = ""
|
locker_key_identifier1 = ""
|
||||||
locker_key_identifier2 = ""
|
locker_key_identifier2 = ""
|
||||||
|
|||||||
2
migrations/2022-12-21-071825_add_refund_reason/down.sql
Normal file
2
migrations/2022-12-21-071825_add_refund_reason/down.sql
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE REFUND
|
||||||
|
DROP COLUMN refund_reason;
|
||||||
1
migrations/2022-12-21-071825_add_refund_reason/up.sql
Normal file
1
migrations/2022-12-21-071825_add_refund_reason/up.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE REFUND ADD COLUMN refund_reason VARCHAR(255) DEFAULT NULL;
|
||||||
Reference in New Issue
Block a user