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

Refactor(core): make save_payment_method as post_update_tracker trait function #4307

Merged
merged 60 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from 50 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
39b79a8
refactor(config): update config for request entry points
prajjwalkumar17 Mar 27, 2024
3a55476
refactor(core): post_update_tracker new function init
prajjwalkumar17 Apr 3, 2024
4dc7b22
refactor: remove FData
Narayanbhat166 Apr 3, 2024
0f5e827
refactor: remove FData from to_post_update_tracker
Narayanbhat166 Apr 3, 2024
65bec8f
refactor: remove F: Clone
Narayanbhat166 Apr 3, 2024
21c342b
Merge branch 'main' into refac/domain_func_for_save_payment_method
prajjwalkumar17 Apr 4, 2024
be27022
chore: make code compile
Narayanbhat166 Apr 4, 2024
babe0fa
refactor(core): done with building trait function and calling the sam…
prajjwalkumar17 Apr 5, 2024
920a1b0
chore: run formatter
hyperswitch-bot[bot] Apr 5, 2024
8fd4889
Merge branch 'main' of https://github.com/juspay/hyperswitch into ref…
prajjwalkumar17 Apr 6, 2024
93361de
Merge branch 'refac/domain_func_for_save_payment_method' of https://g…
prajjwalkumar17 Apr 6, 2024
dc97a69
Merge branch 'main' into refac/domain_func_for_save_payment_method
prajjwalkumar17 Apr 6, 2024
6b5f1f3
Merge branch 'refac/domain_func_for_save_payment_method' of https://g…
prajjwalkumar17 Apr 6, 2024
a60ad58
refactor(core): refactored mandate_procedure
prajjwalkumar17 Apr 6, 2024
056e140
chore: run formatter
hyperswitch-bot[bot] Apr 6, 2024
048823f
chore: code with comments and routerdata error
prajjwalkumar17 Apr 7, 2024
13271f7
chore: merge main
prajjwalkumar17 Apr 7, 2024
98569d6
refactor: make router data as reference
Narayanbhat166 Apr 7, 2024
cd3185d
chore: updated lifetimes
prajjwalkumar17 Apr 8, 2024
aa2a0e3
chore: remove profile_id
prajjwalkumar17 Apr 8, 2024
dcd70c6
chore: add a todo comment
Narayanbhat166 Apr 8, 2024
b695871
chore: remove connector and made payment attempt update type
prajjwalkumar17 Apr 8, 2024
c35ebf7
chore: run formatter
hyperswitch-bot[bot] Apr 8, 2024
0d751a0
chore: made routerdata clonable and removed lifetime b from function
prajjwalkumar17 Apr 8, 2024
9e9bd2f
Merge branch 'refac/domain_func_for_save_payment_method' of https://g…
prajjwalkumar17 Apr 8, 2024
300d209
chore: run formatter
hyperswitch-bot[bot] Apr 8, 2024
1a11188
feat: implement operation trait for payment method
Narayanbhat166 Apr 8, 2024
2f561cc
chore: made db call to save pm_id
prajjwalkumar17 Apr 8, 2024
eea3ec3
refactor: use a separate struct to save pm
Narayanbhat166 Apr 9, 2024
46df8f6
chore: add Clone to F
Narayanbhat166 Apr 9, 2024
beeddba
chore: complete flow for saving payment_method
prajjwalkumar17 Apr 11, 2024
8a61d5c
chore: complete flow tested for saving payment_method
prajjwalkumar17 Apr 11, 2024
c0449da
chore: resolved conflicts
prajjwalkumar17 Apr 11, 2024
adf30a8
chore: run formatter
hyperswitch-bot[bot] Apr 11, 2024
20c9caf
chore: removed unnecessary comments
prajjwalkumar17 Apr 11, 2024
1f9f8a4
Merge branch 'refac/domain_func_for_save_payment_method' of https://g…
prajjwalkumar17 Apr 11, 2024
36b7532
chore: addressed the comments to remove clone from FData in retry flows
prajjwalkumar17 Apr 15, 2024
3c915a1
chore: addressed the comments to change customer_id to Option<String>
prajjwalkumar17 Apr 15, 2024
d45e8f8
chore: run formatter
hyperswitch-bot[bot] Apr 15, 2024
6bb3392
chore: addressed the comments
prajjwalkumar17 Apr 16, 2024
c4c4ff4
Merge branch 'refac/domain_func_for_save_payment_method' of https://g…
prajjwalkumar17 Apr 16, 2024
329b95d
chore: made changes regarding mandate_id
prajjwalkumar17 Apr 17, 2024
949d809
chore: resolved conflicts
prajjwalkumar17 Apr 17, 2024
eb7d8d9
chore: resolved stable tests
prajjwalkumar17 Apr 17, 2024
7e2de55
chore: beautification of code
prajjwalkumar17 Apr 17, 2024
109f0e1
chore: addressed the comments
prajjwalkumar17 Apr 18, 2024
14e953f
chore: addressed the comments
prajjwalkumar17 Apr 18, 2024
eb397cd
Merge branch 'refac/domain_func_for_save_payment_method' of https://g…
prajjwalkumar17 Apr 18, 2024
4b9a42d
chore: addressed the comments
prajjwalkumar17 Apr 18, 2024
53b4891
chore: addressed the comments
prajjwalkumar17 Apr 22, 2024
bf3fd80
chore: run formatter
hyperswitch-bot[bot] Apr 22, 2024
4a16ef3
chore: addressed the comments
prajjwalkumar17 Apr 22, 2024
40d6757
chore: addressed the comments
prajjwalkumar17 Apr 22, 2024
83d3edf
Merge branch 'main' into refac/domain_func_for_save_payment_method
prajjwalkumar17 Apr 22, 2024
32380a5
chore: updated the mandate_id
prajjwalkumar17 Apr 22, 2024
694586f
chore: merged main
prajjwalkumar17 Apr 22, 2024
6946999
chore: run formatter
hyperswitch-bot[bot] Apr 22, 2024
9714a5e
chore: resolved comments
prajjwalkumar17 Apr 22, 2024
c985118
Merge branch 'refac/domain_func_for_save_payment_method' of https://g…
prajjwalkumar17 Apr 22, 2024
01a4540
chore: rename variables
Narayanbhat166 Apr 22, 2024
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
4 changes: 4 additions & 0 deletions crates/data_models/src/payments/payment_attempt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,10 @@ pub enum PaymentAttemptUpdate {
error_message: Option<Option<String>>,
updated_by: String,
},
PaymentMethodDetailsUpdate {
payment_method_id: Option<String>,
updated_by: String,
},
VoidUpdate {
status: storage_enums::AttemptStatus,
cancellation_reason: Option<String>,
Expand Down
12 changes: 12 additions & 0 deletions crates/diesel_models/src/payment_attempt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,10 @@ pub enum PaymentAttemptUpdate {
cancellation_reason: Option<String>,
updated_by: String,
},
PaymentMethodDetailsUpdate {
payment_method_id: Option<String>,
updated_by: String,
},
BlocklistUpdate {
status: storage_enums::AttemptStatus,
error_code: Option<Option<String>>,
Expand Down Expand Up @@ -644,6 +648,14 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
merchant_connector_id: Some(None),
..Default::default()
},
PaymentAttemptUpdate::PaymentMethodDetailsUpdate {
payment_method_id,
updated_by,
} => Self {
payment_method_id,
updated_by,
..Default::default()
},
PaymentAttemptUpdate::ResponseUpdate {
status,
connector,
Expand Down
260 changes: 119 additions & 141 deletions crates/router/src/core/mandate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,156 +340,134 @@ where
.change_context(errors::ApiErrorResponse::MandateUpdateFailed)?;
Ok(resp)
}

pub async fn mandate_procedure<F, FData>(
state: &AppState,
mut resp: types::RouterData<F, FData, types::PaymentsResponseData>,
maybe_customer: &Option<domain::Customer>,
resp: &types::RouterData<F, FData, types::PaymentsResponseData>,
customer_id: &Option<String>,
pm_id: Option<String>,
merchant_connector_id: Option<String>,
storage_scheme: MerchantStorageScheme,
) -> errors::RouterResult<types::RouterData<F, FData, types::PaymentsResponseData>>
) -> errors::RouterResult<Option<String>>
where
FData: MandateBehaviour,
{
match resp.response {
Err(_) => {}
Ok(_) => match resp.request.get_mandate_id() {
Some(mandate_id) => {
if let Some(ref mandate_id) = mandate_id.mandate_id {
let orig_mandate = state
.store
.find_mandate_by_merchant_id_mandate_id(
resp.merchant_id.as_ref(),
mandate_id,
storage_scheme,
)
.await
.to_not_found_response(errors::ApiErrorResponse::MandateNotFound)?;
let mandate = match orig_mandate.mandate_type {
storage_enums::MandateType::SingleUse => state
.store
.update_mandate_by_merchant_id_mandate_id(
&resp.merchant_id,
mandate_id,
storage::MandateUpdate::StatusUpdate {
mandate_status: storage_enums::MandateStatus::Revoked,
},
orig_mandate,
storage_scheme,
)
.await
.change_context(errors::ApiErrorResponse::MandateUpdateFailed),
storage_enums::MandateType::MultiUse => state
.store
.update_mandate_by_merchant_id_mandate_id(
&resp.merchant_id,
mandate_id,
storage::MandateUpdate::CaptureAmountUpdate {
amount_captured: Some(
orig_mandate.amount_captured.unwrap_or(0)
+ resp.request.get_amount(),
),
},
orig_mandate,
storage_scheme,
)
.await
.change_context(errors::ApiErrorResponse::MandateUpdateFailed),
}?;
metrics::SUBSEQUENT_MANDATE_PAYMENT.add(
&metrics::CONTEXT,
1,
&[metrics::request::add_attributes(
"connector",
mandate.connector,
)],
);
resp.payment_method_id = Some(mandate.payment_method_id);
}
}
None => {
if resp.request.get_setup_mandate_details().is_some() {
resp.payment_method_id = pm_id.clone();
let (mandate_reference, network_txn_id) = match resp.response.as_ref().ok() {
Some(types::PaymentsResponseData::TransactionResponse {
mandate_reference,
network_txn_id,
..
}) => (mandate_reference.clone(), network_txn_id.clone()),
_ => (None, None),
};

let mandate_ids = mandate_reference
.as_ref()
.map(|md| {
md.encode_to_value()
.change_context(
errors::ApiErrorResponse::MandateSerializationFailed,
)
.map(masking::Secret::new)
})
.transpose()?;

if let Some(new_mandate_data) = payment_helper::generate_mandate(
resp.merchant_id.clone(),
resp.payment_id.clone(),
resp.connector.clone(),
resp.request.get_setup_mandate_details().cloned(),
maybe_customer,
pm_id.get_required_value("payment_method_id")?,
mandate_ids,
network_txn_id,
get_insensitive_payment_method_data_if_exists(&resp),
mandate_reference,
merchant_connector_id,
)? {
let connector = new_mandate_data.connector.clone();
logger::debug!("{:?}", new_mandate_data);
resp.request
.set_mandate_id(Some(api_models::payments::MandateIds {
mandate_id: Some(new_mandate_data.mandate_id.clone()),
mandate_reference_id: new_mandate_data
.connector_mandate_ids
.clone()
.map(|ids| {
Some(ids)
.parse_value::<api_models::payments::ConnectorMandateReferenceId>(
"ConnectorMandateId",
)
.change_context(errors::ApiErrorResponse::MandateDeserializationFailed)
})
.transpose()?
.map_or(
new_mandate_data.network_transaction_id.clone().map(|id| {
api_models::payments::MandateReferenceId::NetworkMandateId(
id,
)
}),
|connector_id| Some(api_models::payments::MandateReferenceId::ConnectorMandateId(
api_models::payments::ConnectorMandateReferenceId {
connector_mandate_id: connector_id.connector_mandate_id,
payment_method_id: connector_id.payment_method_id,
update_history:None,

}
)))
}));
state
.store
.insert_mandate(new_mandate_data, storage_scheme)
.await
.to_duplicate_response(errors::ApiErrorResponse::DuplicateMandate)?;
metrics::MANDATE_COUNT.add(
&metrics::CONTEXT,
1,
&[metrics::request::add_attributes("connector", connector)],
);
};
}
}
},
let Ok(ref response) = resp.response else {
return Ok(None);
};

match resp.request.get_mandate_id() {
Some(mandate_id) => {
let Some(ref mandate_id) = mandate_id.mandate_id else {
return Ok(None);
};
let orig_mandate = state
.store
.find_mandate_by_merchant_id_mandate_id(
resp.merchant_id.as_ref(),
mandate_id,
storage_scheme,
)
.await
.to_not_found_response(errors::ApiErrorResponse::MandateNotFound)?;
let mandate = match orig_mandate.mandate_type {
storage_enums::MandateType::SingleUse => state
.store
.update_mandate_by_merchant_id_mandate_id(
&resp.merchant_id,
mandate_id,
storage::MandateUpdate::StatusUpdate {
mandate_status: storage_enums::MandateStatus::Revoked,
},
orig_mandate,
storage_scheme,
)
.await
.change_context(errors::ApiErrorResponse::MandateUpdateFailed),
storage_enums::MandateType::MultiUse => state
.store
.update_mandate_by_merchant_id_mandate_id(
&resp.merchant_id,
mandate_id,
storage::MandateUpdate::CaptureAmountUpdate {
amount_captured: Some(
orig_mandate.amount_captured.unwrap_or(0)
+ resp.request.get_amount(),
),
},
orig_mandate,
storage_scheme,
)
.await
.change_context(errors::ApiErrorResponse::MandateUpdateFailed),
}?;
metrics::SUBSEQUENT_MANDATE_PAYMENT.add(
&metrics::CONTEXT,
1,
&[metrics::request::add_attributes(
"connector",
mandate.connector,
)],
);
Ok(Some(mandate_id.clone()))
}
None => {
let Some(_mandate_details) = resp.request.get_setup_mandate_details() else {
return Ok(None);
};
let (mandate_reference, network_txn_id) = match &response {
types::PaymentsResponseData::TransactionResponse {
mandate_reference,
network_txn_id,
..
} => (mandate_reference.clone(), network_txn_id.clone()),
_ => (None, None),
};

let mandate_ids = mandate_reference
.as_ref()
.map(|md| {
md.encode_to_value()
.change_context(errors::ApiErrorResponse::MandateSerializationFailed)
.map(masking::Secret::new)
})
.transpose()?;

let Some(new_mandate_data) = payment_helper::generate_mandate(
resp.merchant_id.clone(),
resp.payment_id.clone(),
resp.connector.clone(),
resp.request.get_setup_mandate_details().cloned(),
customer_id,
pm_id.get_required_value("payment_method_id")?,
mandate_ids,
network_txn_id,
get_insensitive_payment_method_data_if_exists(resp),
mandate_reference,
merchant_connector_id,
)?
else {
return Ok(None);
};

let connector = new_mandate_data.connector.clone();
logger::debug!("{:?}", new_mandate_data);

let res_mandate_id = new_mandate_data.mandate_id.clone();

state
.store
.insert_mandate(new_mandate_data, storage_scheme)
.await
.to_duplicate_response(errors::ApiErrorResponse::DuplicateMandate)?;
metrics::MANDATE_COUNT.add(
&metrics::CONTEXT,
1,
&[metrics::request::add_attributes("connector", connector)],
);
Ok(Some(res_mandate_id))
}
}
Ok(resp)
}

#[instrument(skip(state))]
Expand Down
Loading
Loading