Skip to content

Commit 38aa9ea

Browse files
feat(router): added retrieval flow for connector file uploads and added support for stripe connector (#990)
1 parent d6e71b9 commit 38aa9ea

File tree

16 files changed

+388
-66
lines changed

16 files changed

+388
-66
lines changed

crates/common_enums/src/enums.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,3 +313,25 @@ pub enum Country {
313313
Zambia,
314314
Zimbabwe,
315315
}
316+
317+
#[derive(
318+
Clone,
319+
Copy,
320+
Debug,
321+
Eq,
322+
PartialEq,
323+
Default,
324+
serde::Deserialize,
325+
serde::Serialize,
326+
strum::Display,
327+
strum::EnumString,
328+
)]
329+
#[router_derive::diesel_enum(storage_type = "text")]
330+
#[serde(rename_all = "snake_case")]
331+
#[strum(serialize_all = "snake_case")]
332+
pub enum FileUploadProvider {
333+
#[default]
334+
Router,
335+
Stripe,
336+
Checkout,
337+
}

crates/router/src/connector/checkout.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ impl api::ConnectorAccessToken for Checkout {}
118118
impl api::AcceptDispute for Checkout {}
119119
impl api::PaymentToken for Checkout {}
120120
impl api::Dispute for Checkout {}
121+
impl api::RetrieveFile for Checkout {}
121122
impl api::DefendDispute for Checkout {}
122123

123124
impl
@@ -773,6 +774,12 @@ impl
773774

774775
impl api::UploadFile for Checkout {}
775776

777+
impl
778+
ConnectorIntegration<api::Retrieve, types::RetrieveFileRequestData, types::RetrieveFileResponse>
779+
for Checkout
780+
{
781+
}
782+
776783
#[async_trait::async_trait]
777784
impl api::FileUpload for Checkout {
778785
fn validate_file_upload(

crates/router/src/connector/stripe.rs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,6 +1199,98 @@ impl
11991199
}
12001200
}
12011201

1202+
impl api::RetrieveFile for Stripe {}
1203+
1204+
impl
1205+
services::ConnectorIntegration<
1206+
api::Retrieve,
1207+
types::RetrieveFileRequestData,
1208+
types::RetrieveFileResponse,
1209+
> for Stripe
1210+
{
1211+
fn get_headers(
1212+
&self,
1213+
req: &types::RouterData<
1214+
api::Retrieve,
1215+
types::RetrieveFileRequestData,
1216+
types::RetrieveFileResponse,
1217+
>,
1218+
_connectors: &settings::Connectors,
1219+
) -> CustomResult<Vec<(String, String)>, errors::ConnectorError> {
1220+
self.get_auth_header(&req.connector_auth_type)
1221+
}
1222+
1223+
fn get_url(
1224+
&self,
1225+
req: &types::RetrieveFileRouterData,
1226+
connectors: &settings::Connectors,
1227+
) -> CustomResult<String, errors::ConnectorError> {
1228+
Ok(format!(
1229+
"{}v1/files/{}/contents",
1230+
connectors.stripe.base_url_file_upload, req.request.provider_file_id
1231+
))
1232+
}
1233+
1234+
fn build_request(
1235+
&self,
1236+
req: &types::RetrieveFileRouterData,
1237+
connectors: &settings::Connectors,
1238+
) -> CustomResult<Option<services::Request>, errors::ConnectorError> {
1239+
Ok(Some(
1240+
services::RequestBuilder::new()
1241+
.method(services::Method::Get)
1242+
.url(&types::RetrieveFileType::get_url(self, req, connectors)?)
1243+
.attach_default_headers()
1244+
.headers(types::RetrieveFileType::get_headers(self, req, connectors)?)
1245+
.build(),
1246+
))
1247+
}
1248+
1249+
#[instrument(skip_all)]
1250+
fn handle_response(
1251+
&self,
1252+
data: &types::RetrieveFileRouterData,
1253+
res: types::Response,
1254+
) -> CustomResult<
1255+
types::RouterData<
1256+
api::Retrieve,
1257+
types::RetrieveFileRequestData,
1258+
types::RetrieveFileResponse,
1259+
>,
1260+
errors::ConnectorError,
1261+
> {
1262+
let response = res.response;
1263+
Ok(types::RetrieveFileRouterData {
1264+
response: Ok(types::RetrieveFileResponse {
1265+
file_data: response.to_vec(),
1266+
}),
1267+
..data.clone()
1268+
})
1269+
}
1270+
1271+
fn get_error_response(
1272+
&self,
1273+
res: types::Response,
1274+
) -> CustomResult<types::ErrorResponse, errors::ConnectorError> {
1275+
let response: stripe::ErrorResponse = res
1276+
.response
1277+
.parse_struct("ErrorResponse")
1278+
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
1279+
Ok(types::ErrorResponse {
1280+
status_code: res.status_code,
1281+
code: response
1282+
.error
1283+
.code
1284+
.unwrap_or_else(|| consts::NO_ERROR_CODE.to_string()),
1285+
message: response
1286+
.error
1287+
.message
1288+
.unwrap_or_else(|| consts::NO_ERROR_MESSAGE.to_string()),
1289+
reason: None,
1290+
})
1291+
}
1292+
}
1293+
12021294
impl api::SubmitEvidence for Stripe {}
12031295

12041296
impl

crates/router/src/core/disputes/transformers.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use common_utils::errors::CustomResult;
33
use crate::{
44
core::{errors, files::helpers::retrieve_file_and_provider_file_id_from_file_id},
55
routes::AppState,
6-
types::SubmitEvidenceRequestData,
6+
types::{api, SubmitEvidenceRequestData},
77
};
88

99
pub async fn get_evidence_request_data(
@@ -17,47 +17,54 @@ pub async fn get_evidence_request_data(
1717
state,
1818
evidence_request.cancellation_policy,
1919
merchant_account,
20+
api::FileDataRequired::NotRequired,
2021
)
2122
.await?;
2223
let (customer_communication, customer_communication_provider_file_id) =
2324
retrieve_file_and_provider_file_id_from_file_id(
2425
state,
2526
evidence_request.customer_communication,
2627
merchant_account,
28+
api::FileDataRequired::NotRequired,
2729
)
2830
.await?;
2931
let (customer_signature, customer_signature_provider_file_id) =
3032
retrieve_file_and_provider_file_id_from_file_id(
3133
state,
3234
evidence_request.customer_signature,
3335
merchant_account,
36+
api::FileDataRequired::NotRequired,
3437
)
3538
.await?;
3639
let (receipt, receipt_provider_file_id) = retrieve_file_and_provider_file_id_from_file_id(
3740
state,
3841
evidence_request.receipt,
3942
merchant_account,
43+
api::FileDataRequired::NotRequired,
4044
)
4145
.await?;
4246
let (refund_policy, refund_policy_provider_file_id) =
4347
retrieve_file_and_provider_file_id_from_file_id(
4448
state,
4549
evidence_request.refund_policy,
4650
merchant_account,
51+
api::FileDataRequired::NotRequired,
4752
)
4853
.await?;
4954
let (service_documentation, service_documentation_provider_file_id) =
5055
retrieve_file_and_provider_file_id_from_file_id(
5156
state,
5257
evidence_request.service_documentation,
5358
merchant_account,
59+
api::FileDataRequired::NotRequired,
5460
)
5561
.await?;
5662
let (shipping_documentation, shipping_documentation_provider_file_id) =
5763
retrieve_file_and_provider_file_id_from_file_id(
5864
state,
5965
evidence_request.shipping_documentation,
6066
merchant_account,
67+
api::FileDataRequired::NotRequired,
6168
)
6269
.await?;
6370
let (
@@ -67,20 +74,23 @@ pub async fn get_evidence_request_data(
6774
state,
6875
evidence_request.invoice_showing_distinct_transactions,
6976
merchant_account,
77+
api::FileDataRequired::NotRequired,
7078
)
7179
.await?;
7280
let (recurring_transaction_agreement, recurring_transaction_agreement_provider_file_id) =
7381
retrieve_file_and_provider_file_id_from_file_id(
7482
state,
7583
evidence_request.recurring_transaction_agreement,
7684
merchant_account,
85+
api::FileDataRequired::NotRequired,
7786
)
7887
.await?;
7988
let (uncategorized_file, uncategorized_file_provider_file_id) =
8089
retrieve_file_and_provider_file_id_from_file_id(
8190
state,
8291
evidence_request.uncategorized_file,
8392
merchant_account,
93+
api::FileDataRequired::NotRequired,
8494
)
8595
.await?;
8696
Ok(SubmitEvidenceRequestData {

crates/router/src/core/files.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::{
1313
consts,
1414
routes::AppState,
1515
services::{self, ApplicationResponse},
16-
types::{api, storage, transformers::ForeignInto},
16+
types::{api, storage},
1717
};
1818

1919
pub async fn files_create_core(
@@ -37,15 +37,16 @@ pub async fn files_create_core(
3737
provider_file_id: None,
3838
file_upload_provider: None,
3939
available: false,
40+
connector_label: None,
4041
};
4142
let file_metadata_object = state
4243
.store
4344
.insert_file_metadata(file_new)
4445
.await
4546
.change_context(errors::ApiErrorResponse::InternalServerError)
4647
.attach_printable("Unable to insert file_metadata")?;
47-
let (provider_file_id, file_upload_provider) =
48-
helpers::upload_and_get_provider_provider_file_id(
48+
let (provider_file_id, file_upload_provider, connector_label) =
49+
helpers::upload_and_get_provider_provider_file_id_connector_label(
4950
state,
5051
&merchant_account,
5152
&create_file_request,
@@ -55,8 +56,9 @@ pub async fn files_create_core(
5556
//Update file metadata
5657
let update_file_metadata = storage_models::file::FileMetadataUpdate::Update {
5758
provider_file_id: Some(provider_file_id),
58-
file_upload_provider: Some(file_upload_provider.foreign_into()),
59+
file_upload_provider: Some(file_upload_provider),
5960
available: true,
61+
connector_label,
6062
};
6163
state
6264
.store
@@ -102,6 +104,7 @@ pub async fn files_retrieve_core(
102104
state,
103105
Some(req.file_id),
104106
&merchant_account,
107+
api::FileDataRequired::Required,
105108
)
106109
.await?;
107110
let content_type = file_metadata_object

0 commit comments

Comments
 (0)