Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(router): added dispute accept api, file module apis and dispute evidence submission api #900

Merged
merged 71 commits into from
Apr 24, 2023
Merged
Show file tree
Hide file tree
Changes from 69 commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
e05d385
api contract for bank redirect
Sangamesh26 Feb 9, 2023
b31bb01
contract change for sofort
Sangamesh26 Feb 10, 2023
f95cec3
changed in migration for payment_method from type to varchar
Sangamesh26 Feb 22, 2023
b078ab6
Initial commit
Feb 24, 2023
bd03936
Merge branch 'bank-redirect-api-contract' of https://github.com/juspa…
Feb 24, 2023
f17ef01
Added bank transfers
Feb 27, 2023
8d86767
Added refunds and refund sync for trustpay
Mar 2, 2023
503cf0f
Merge branch 'main' of https://github.com/juspay/hyperswitch into fea…
Mar 2, 2023
f8cee46
added trustpay refunds, refundsync
Mar 6, 2023
6471368
Merge branch 'main' of https://github.com/juspay/hyperswitch into fea…
Mar 6, 2023
05bab31
added tests for trustpay
Mar 6, 2023
16833ba
revered unnecessary changes
Mar 6, 2023
ccb1639
reverted unnecessary changes
Mar 6, 2023
610a45c
Refactoring and resolved comments
Mar 7, 2023
9109e80
Merge branch 'main' of https://github.com/juspay/hyperswitch into fea…
Mar 7, 2023
8b4e07f
Refactor and resolving comments
Mar 8, 2023
bd8ebe0
resolved comments
Mar 9, 2023
f93a808
resolved comments
Mar 9, 2023
247ec86
Merge branch 'main' into feat/add_connector_trustpay
jarnura Mar 10, 2023
2e76e6b
added rsync for bank redirects
Mar 11, 2023
822b92e
fixed bank redirect sync, refund sync and resolved comments
Mar 11, 2023
d7ffed3
Merge branch 'feat/add_connector_trustpay' of https://github.com/jusp…
Mar 11, 2023
a6bf5d6
refactored and resolved comments
Mar 12, 2023
b05a0c3
Merge branch 'main' of https://github.com/juspay/hyperswitch into fea…
Mar 12, 2023
273e0bb
resolved comments
Mar 13, 2023
d439e93
added webhooks for trustpay
Mar 13, 2023
17982b1
added signature verification for trustpay webhooks
Mar 14, 2023
a4d8888
merged main
Mar 14, 2023
f7d9bdb
removed unnecessary changes
Mar 14, 2023
f2cfd8e
resolved comments
Mar 15, 2023
9cec5ef
fixed connector template
Mar 15, 2023
96c0f63
added dispute webhooks flow
Mar 17, 2023
e211a0d
merge latest main
Mar 20, 2023
31ec38b
fixed spell check
sai-harsha-vardhan Mar 20, 2023
cec0ed6
Merge branch 'main' of https://github.com/juspay/hyperswitch into fea…
sai-harsha-vardhan Mar 20, 2023
1891a11
latest main merge
sai-harsha-vardhan Mar 20, 2023
5b108de
added dispute webhooks flow for adyen
sai-harsha-vardhan Mar 20, 2023
4414d52
added dispute retrieve and list apis
sai-harsha-vardhan Mar 23, 2023
95c3fda
added filters for list api
sai-harsha-vardhan Mar 27, 2023
b8f0a69
pull latest changes
sai-harsha-vardhan Apr 5, 2023
14889b1
fixed code formatting
sai-harsha-vardhan Apr 5, 2023
93ab086
fixed utopia issues
sai-harsha-vardhan Apr 5, 2023
ed7093b
Merge branch 'main' of github.com:juspay/hyperswitch into feat/disput…
sai-harsha-vardhan Apr 5, 2023
5609392
fixed index and authentication for apis
sai-harsha-vardhan Apr 6, 2023
a637429
spell check fix
sai-harsha-vardhan Apr 6, 2023
9c57d20
fix diesel migrations
sai-harsha-vardhan Apr 6, 2023
d153362
fix dispute schema issue
sai-harsha-vardhan Apr 6, 2023
1aa16ac
added flow for accept dispute api
sai-harsha-vardhan Apr 8, 2023
9500808
added accept dispute api flow for checkout
sai-harsha-vardhan Apr 9, 2023
2e012a5
added file upload api
sai-harsha-vardhan Apr 12, 2023
ce56cff
added file delete and retrieve apis
sai-harsha-vardhan Apr 14, 2023
6f6a11f
added s3 as feature and implemented local file system crd
sai-harsha-vardhan Apr 17, 2023
b9eb0b7
merged latest main
sai-harsha-vardhan Apr 17, 2023
b631774
reverted lock file
sai-harsha-vardhan Apr 17, 2023
94a7077
spell check fix
sai-harsha-vardhan Apr 17, 2023
1b17f4d
added files directory and fixed content type
sai-harsha-vardhan Apr 17, 2023
a85e2a1
Merge branch 'main' of github.com:juspay/hyperswitch into feat/disput…
sai-harsha-vardhan Apr 19, 2023
e3019eb
added submit evidence api, connector files uploads and resolved comments
sai-harsha-vardhan Apr 19, 2023
43beacd
resolved comments
sai-harsha-vardhan Apr 20, 2023
74a2c4d
Merge branch 'main' into feat/dispute-evidence-apis
sai-harsha-vardhan Apr 20, 2023
c5bfb2d
Merge branch 'main' into feat/dispute-evidence-apis
jarnura Apr 20, 2023
fa814a6
resolved comments
sai-harsha-vardhan Apr 20, 2023
8d407f5
Merge branch 'feat/dispute-evidence-apis' of github.com:juspay/hypers…
sai-harsha-vardhan Apr 20, 2023
8962c11
logged errors, refactor and resolved comments
sai-harsha-vardhan Apr 21, 2023
a855901
spell fix and changed primary key of file_metadata
sai-harsha-vardhan Apr 21, 2023
f9ae729
Merge branch 'main' of github.com:juspay/hyperswitch into feat/disput…
sai-harsha-vardhan Apr 21, 2023
84484c1
resolved clippy warnings
sai-harsha-vardhan Apr 21, 2023
c089711
used change_context instead of map_err and resolved comments
sai-harsha-vardhan Apr 21, 2023
671168e
merge latest main
sai-harsha-vardhan Apr 21, 2023
177bf2b
resolved comments
sai-harsha-vardhan Apr 24, 2023
cae51f0
Merge branch 'main' of github.com:juspay/hyperswitch into feat/disput…
sai-harsha-vardhan Apr 24, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ payu.base_url = "https://secure.snd.payu.com/"
rapyd.base_url = "https://sandboxapi.rapyd.net"
shift4.base_url = "https://api.shift4.com/"
stripe.base_url = "https://api.stripe.com/"
stripe.base_url_file_upload = "https://files.stripe.com/"
worldline.base_url = "https://eu.sandbox.api-ingenico.com/"
worldpay.base_url = "https://try.access.worldpay.com/"
trustpay.base_url = "https://test-tpgw.trustpay.eu/"
Expand Down
5 changes: 5 additions & 0 deletions config/development.toml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ payu.base_url = "https://secure.snd.payu.com/"
rapyd.base_url = "https://sandboxapi.rapyd.net"
shift4.base_url = "https://api.shift4.com/"
stripe.base_url = "https://api.stripe.com/"
stripe.base_url_file_upload = "https://files.stripe.com/"
worldline.base_url = "https://eu.sandbox.api-ingenico.com/"
worldpay.base_url = "https://try.access.worldpay.com/"
trustpay.base_url = "https://test-tpgw.trustpay.eu/"
Expand Down Expand Up @@ -185,6 +186,10 @@ paypal = { currency = "CHF,DKK,EUR,GBP,NOK,PLN,SEK,USD,AUD,NZD,CAD" }
google_pay = { country = "AL,DZ,AS,AO,AG,AR,AU,AT,AZ,BH,BY,BE,BR,BG,CA,CL,CO,HR,CZ,DK,DO,EG,EE,FI,FR,DE,GR,HK,HU,IN,ID,IE,IL,IT,JP,JO,KZ,KE,KW,LV,LB,LT,LU,MY,MX,NL,NZ,NO,OM,PK,PA,PE,PH,PL,PT,QA,RO,RU,SA,SG,SK,ZA,ES,LK,SE,CH,TW,TH,TR,UA,AE,GB,US,UY,VN" }
apple_pay = { country = "AU,CN,HK,JP,MO,MY,NZ,SG,TW,AM,AT,AZ,BY,BE,BG,HR,CY,CZ,DK,EE,FO,FI,FR,GE,DE,GR,GL,GG,HU,IS,IE,IM,IT,KZ,JE,LV,LI,LT,LU,MT,MD,MC,ME,NL,NO,PL,PT,RO,SM,RS,SK,SI,ES,SE,CH,UA,GB,AR,CO,CR,BR,MX,PE,BH,IL,JO,KW,PS,QA,SA,AE,CA,UM,US" }

[file_upload_config]
bucket_name = ""
region = ""

Comment on lines +189 to +192
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also add this fields to other config.example.toml & docker_compose.toml

@sai-harsha-vardhan

[tokenization]
stripe = { long_lived_token = false, payment_method = "wallet"}
checkout = { long_lived_token = false, payment_method = "wallet"}
1 change: 1 addition & 0 deletions config/docker_compose.toml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ payu.base_url = "https://secure.snd.payu.com/"
rapyd.base_url = "https://sandboxapi.rapyd.net"
shift4.base_url = "https://api.shift4.com/"
stripe.base_url = "https://api.stripe.com/"
stripe.base_url_file_upload = "https://files.stripe.com/"
worldline.base_url = "https://eu.sandbox.api-ingenico.com/"
worldpay.base_url = "https://try.access.worldpay.com/"
trustpay.base_url = "https://test-tpgw.trustpay.eu/"
Expand Down
54 changes: 54 additions & 0 deletions crates/api_models/src/disputes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,57 @@ pub struct DisputeListConstraints {
#[serde(rename = "received_time.gte")]
pub received_time_gte: Option<PrimitiveDateTime>,
}

#[derive(Default, Clone, Debug, Serialize, Deserialize, ToSchema)]
pub struct SubmitEvidenceRequest {
///Dispute Id
pub dispute_id: String,
/// Logs showing the usage of service by customer
pub access_activity_log: Option<String>,
/// Billing address of the customer
pub billing_address: Option<String>,
/// File Id of cancellation policy
pub cancellation_policy: Option<String>,
/// Details of showing cancellation policy to customer before purchase
pub cancellation_policy_disclosure: Option<String>,
/// Details telling why customer's subscription was not cancelled
pub cancellation_rebuttal: Option<String>,
/// File Id of customer communication
pub customer_communication: Option<String>,
/// Customer email address
pub customer_email_address: Option<String>,
/// Customer name
pub customer_name: Option<String>,
/// IP address of the customer
pub customer_purchase_ip: Option<String>,
/// Fild Id of customer signature
pub customer_signature: Option<String>,
/// Product Description
pub product_description: Option<String>,
/// File Id of receipt
pub receipt: Option<String>,
/// File Id of refund policy
pub refund_policy: Option<String>,
/// Details of showing refund policy to customer before purchase
pub refund_policy_disclosure: Option<String>,
/// Details why customer is not entitled to refund
pub refund_refusal_explanation: Option<String>,
/// Customer service date
pub service_date: Option<String>,
/// File Id service documentation
pub service_documentation: Option<String>,
/// Shipping address of the customer
pub shipping_address: Option<String>,
/// Delivery service that shipped the product
pub shipping_carrier: Option<String>,
/// Shipping date
pub shipping_date: Option<String>,
/// File Id shipping documentation
pub shipping_documentation: Option<String>,
/// Tracking number of shipped product
pub shipping_tracking_number: Option<String>,
/// Any additional supporting file
pub uncategorized_file: Option<String>,
/// Any additional evidence statements
pub uncategorized_text: Option<String>,
}
3 changes: 3 additions & 0 deletions crates/api_models/src/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,9 @@ impl Connector {
| (Self::Trustpay, PaymentMethod::BankRedirect)
)
}
pub fn supports_file_storage_module(&self) -> bool {
matches!(self, Self::Stripe)
}
}

#[derive(
Expand Down
6 changes: 6 additions & 0 deletions crates/api_models/src/files.rs
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
use utoipa::ToSchema;

#[derive(Debug, serde::Serialize, ToSchema)]
pub struct CreateFileResponse {
/// ID of the file created
pub file_id: String,
}
11 changes: 8 additions & 3 deletions crates/router/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ build = "src/build.rs"

[features]
default = ["kv_store", "stripe", "oltp", "olap", "accounts_cache"]
s3 = []
kms = ["external_services/kms"]
basilisk = ["kms"]
stripe = ["dep:serde_qs"]
sandbox = ["kms", "stripe", "basilisk"]
production = ["kms", "stripe", "basilisk"]
sandbox = ["kms", "stripe", "basilisk", "s3"]
production = ["kms", "stripe", "basilisk", "s3"]
olap = []
oltp = []
kv_store = []
Expand Down Expand Up @@ -60,7 +61,7 @@ num_cpus = "1.15.0"
once_cell = "1.17.1"
rand = "0.8.5"
regex = "1.7.3"
reqwest = { version = "0.11.16", features = ["json", "native-tls", "gzip"] }
reqwest = { version = "0.11.16", features = ["json", "native-tls", "gzip", "multipart"] }
ring = "0.16.20"
serde = { version = "1.0.160", features = ["derive"] }
serde_json = "1.0.96"
Expand Down Expand Up @@ -88,6 +89,10 @@ redis_interface = { version = "0.1.0", path = "../redis_interface" }
router_derive = { version = "0.1.0", path = "../router_derive" }
router_env = { version = "0.1.0", path = "../router_env", features = ["log_extra_implicit_fields", "log_custom_entries_to_extra"] }
storage_models = { version = "0.1.0", path = "../storage_models", features = ["kv_store"] }
actix-multipart = "0.6.0"
aws-sdk-s3 = "0.25.0"
aws-config = "0.55.1"
infer = "0.13.0"

[build-dependencies]
router_env = { version = "0.1.0", path = "../router_env", default-features = false }
Expand Down
33 changes: 32 additions & 1 deletion crates/router/src/compatibility/stripe/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,20 @@ pub enum StripeErrorCode {
IncorrectConnectorNameGiven,
#[error(error_type = StripeErrorType::HyperswitchError, code = "", message = "No such {object}: '{id}'")]
ResourceMissing { object: String, id: String },
#[error(error_type = StripeErrorType::HyperswitchError, code = "", message = "File validation failed")]
FileValidationFailed,
#[error(error_type = StripeErrorType::HyperswitchError, code = "", message = "File not found in the request")]
MissingFile,
#[error(error_type = StripeErrorType::HyperswitchError, code = "", message = "File puropse not found in the request")]
MissingFilePurpose,
#[error(error_type = StripeErrorType::HyperswitchError, code = "", message = "File content type not found")]
MissingFileContentType,
#[error(error_type = StripeErrorType::HyperswitchError, code = "", message = "Dispute id not found in the request")]
MissingDisputeId,
#[error(error_type = StripeErrorType::HyperswitchError, code = "", message = "File does not exists in our records")]
FileNotFound,
#[error(error_type = StripeErrorType::HyperswitchError, code = "", message = "File not available")]
FileNotAvailable,
// [#216]: https://github.com/juspay/hyperswitch/issues/216
// Implement the remaining stripe error codes

Expand Down Expand Up @@ -466,6 +480,16 @@ impl From<errors::ApiErrorResponse> for StripeErrorCode {
object: "dispute".to_owned(),
id: dispute_id,
},
errors::ApiErrorResponse::DisputeStatusValidationFailed { reason } => {
Self::InternalServerError
}
errors::ApiErrorResponse::FileValidationFailed { .. } => Self::FileValidationFailed,
errors::ApiErrorResponse::MissingFile => Self::MissingFile,
errors::ApiErrorResponse::MissingFilePurpose => Self::MissingFilePurpose,
errors::ApiErrorResponse::MissingFileContentType => Self::MissingFileContentType,
errors::ApiErrorResponse::MissingDisputeId => Self::MissingDisputeId,
errors::ApiErrorResponse::FileNotFound => Self::FileNotFound,
errors::ApiErrorResponse::FileNotAvailable => Self::FileNotAvailable,
errors::ApiErrorResponse::NotSupported { .. } => Self::InternalServerError,
}
}
Expand Down Expand Up @@ -514,7 +538,14 @@ impl actix_web::ResponseError for StripeErrorCode {
| Self::PaymentIntentUnexpectedState { .. }
| Self::DuplicatePayment { .. }
| Self::IncorrectConnectorNameGiven
| Self::ResourceMissing { .. } => StatusCode::BAD_REQUEST,
| Self::ResourceMissing { .. }
| Self::FileValidationFailed
| Self::MissingFile
| Self::MissingFileContentType
| Self::MissingFilePurpose
| Self::MissingDisputeId
| Self::FileNotFound
| Self::FileNotAvailable => StatusCode::BAD_REQUEST,
Self::RefundFailed
| Self::InternalServerError
| Self::MandateActive
Expand Down
3 changes: 3 additions & 0 deletions crates/router/src/compatibility/wrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ where
}
Ok(api::ApplicationResponse::StatusOk) => api::http_response_ok(),
Ok(api::ApplicationResponse::TextPlain(text)) => api::http_response_plaintext(text),
Ok(api::ApplicationResponse::FileData((file_data, content_type))) => {
api::http_response_file_data(file_data, content_type)
}
Ok(api::ApplicationResponse::JsonForRedirection(response)) => {
match serde_json::to_string(&response) {
Ok(res) => api::http_redirect_response(res, response),
Expand Down
24 changes: 22 additions & 2 deletions crates/router/src/configs/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ pub struct Settings {
pub api_keys: ApiKeys,
#[cfg(feature = "kms")]
pub kms: kms::KmsConfig,
#[cfg(feature = "s3")]
pub file_upload_config: FileUploadConfig,
pub tokenization: TokenizationConfig,
}

Expand Down Expand Up @@ -306,7 +308,7 @@ pub struct Connectors {
pub payu: ConnectorParams,
pub rapyd: ConnectorParams,
pub shift4: ConnectorParams,
pub stripe: ConnectorParams,
pub stripe: ConnectorParamsWithFileUploadUrl,
pub worldline: ConnectorParams,
pub worldpay: ConnectorParams,
pub trustpay: ConnectorParamsWithMoreUrls,
Expand All @@ -328,6 +330,13 @@ pub struct ConnectorParamsWithMoreUrls {
pub base_url_bank_redirects: String,
}

#[derive(Debug, Deserialize, Clone, Default)]
#[serde(default)]
pub struct ConnectorParamsWithFileUploadUrl {
pub base_url: String,
pub base_url_file_upload: String,
}

#[derive(Debug, Clone, Deserialize)]
#[serde(default)]
pub struct SchedulerSettings {
Expand Down Expand Up @@ -387,6 +396,16 @@ pub struct ApiKeys {
pub hash_key: String,
}

#[cfg(feature = "s3")]
#[derive(Debug, Deserialize, Clone, Default)]
#[serde(default)]
pub struct FileUploadConfig {
/// The AWS region to send file uploads
pub region: String,
/// The AWS s3 bucket to send file uploads
pub bucket_name: String,
}

impl Settings {
pub fn new() -> ApplicationResult<Self> {
Self::with_config_path(None)
Expand Down Expand Up @@ -465,7 +484,8 @@ impl Settings {
self.kms
.validate()
.map_err(|error| ApplicationError::InvalidConfigurationValueError(error.into()))?;

#[cfg(feature = "s3")]
self.file_upload_config.validate()?;
Ok(())
}
}
Expand Down
34 changes: 34 additions & 0 deletions crates/router/src/configs/validations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,21 @@ impl super::settings::ConnectorParams {
}
}

impl super::settings::ConnectorParamsWithFileUploadUrl {
pub fn validate(&self) -> Result<(), ApplicationError> {
common_utils::fp_utils::when(self.base_url.is_default_or_empty(), || {
Err(ApplicationError::InvalidConfigurationValueError(
"connector base URL must not be empty".into(),
))
})?;
common_utils::fp_utils::when(self.base_url_file_upload.is_default_or_empty(), || {
Err(ApplicationError::InvalidConfigurationValueError(
"connector file upload base URL must not be empty".into(),
))
})
}
}

impl super::settings::SchedulerSettings {
pub fn validate(&self) -> Result<(), ApplicationError> {
use common_utils::fp_utils::when;
Expand Down Expand Up @@ -198,6 +213,25 @@ impl super::settings::DrainerSettings {
}
}

#[cfg(feature = "s3")]
impl super::settings::FileUploadConfig {
pub fn validate(&self) -> Result<(), ApplicationError> {
use common_utils::fp_utils::when;

when(self.region.is_default_or_empty(), || {
Err(ApplicationError::InvalidConfigurationValueError(
"s3 region must not be empty".into(),
))
})?;

when(self.bucket_name.is_default_or_empty(), || {
Err(ApplicationError::InvalidConfigurationValueError(
"s3 bucket name must not be empty".into(),
))
})
}
}

impl super::settings::ApiKeys {
pub fn validate(&self) -> Result<(), ApplicationError> {
use common_utils::fp_utils::when;
Expand Down
Loading