-
Notifications
You must be signed in to change notification settings - Fork 4.6k
feat(payment_methods): payment method id retrieval from payment token for V2 #10834
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
Conversation
Changed Files
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #10834 +/- ##
=======================================
Coverage ? 6.33%
=======================================
Files ? 1273
Lines ? 322138
Branches ? 0
=======================================
Hits ? 20394
Misses ? 301744
Partials ? 0 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
…t-method-id-by-payment-token
…juspay/hyperswitch into feat/payment-method-id-by-payment-token
…juspay/hyperswitch into feat/payment-method-id-by-payment-token
…juspay/hyperswitch into feat/payment-method-id-by-payment-token
| }, | ||
| )) | ||
| } | ||
| Ok(_) => Err(errors::ApiErrorResponse::PaymentMethodNotFound.into()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we send an error in case of other kinds of token data?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in case guest checkout flow,
currently we have permenant card, but it should temporary.
@su-shivanshmathur we need to verify on how we are insert this payment method token, when storage type is volatile
| pub async fn get_data_for_token( | ||
| &self, | ||
| state: &SessionState, | ||
| ) -> CustomResult<PaymentTokenData, errors::ApiErrorResponse> { | ||
| let redis_conn = state | ||
| .store | ||
| .get_redis_conn() | ||
| .change_context(errors::ApiErrorResponse::InternalServerError) | ||
| .attach_printable("Failed to get redis connection")?; | ||
|
|
||
| logger::debug!( | ||
| "Fetching payment method token data from redis for key: {}", | ||
| self.key_for_token | ||
| ); | ||
|
|
||
| let pm_token_data = redis_conn | ||
| .get_and_deserialize_key::<PaymentTokenData>( | ||
| &self.key_for_token.as_str().into(), | ||
| "Token Data", | ||
| ) | ||
| .await | ||
| .map_err(|e| error_stack::report!(storage_impl::StorageError::from(e))) | ||
| .to_not_found_response(errors::ApiErrorResponse::GenericNotFoundError { | ||
| message: "Payment method token either expired or does not exist".to_string(), | ||
| })?; | ||
| Ok(pm_token_data) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you once check if retrieve_payment_token_data fn from crates/router/src/core/payment_methods/utils.rs can be reused here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's refactor later on to depricate this utils fn if not required. @su-shivanshmathur
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we create an issue for this?
…juspay/hyperswitch into feat/payment-method-id-by-payment-token
| "Payment Methods" | ||
| ], | ||
| "summary": "Payment Method - Get Payment Method Token Data", | ||
| "description": "Retrieve the Payment method id associated with a payment method.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| "description": "Retrieve the Payment method id associated with a payment method.", | |
| "description": "Retrieve the Payment method id associated with a payment method token.", |
|
|
||
| /// The tokenization id associated with the payment method | ||
| #[schema(value_type = String, example = "token_CSum555d9YxDOpGwYq6q")] | ||
| pub token: String, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| pub token: String, | |
| pub payment_method_token: String, |
also please modify the doc comment.
we have a different tokenization id in our service. this will create confusion
crates/router/src/routes/app.rs
Outdated
| .route(web::get().to(payment_methods::network_token_status_check_api)), | ||
| ) | ||
| .service( | ||
| web::resource("/details/{temporary_token}").route( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| web::resource("/details/{temporary_token}").route( | |
| web::resource("/token/{payment_method_token}/details").route( |
| pub async fn get_data_for_token( | ||
| &self, | ||
| state: &SessionState, | ||
| ) -> CustomResult<PaymentTokenData, errors::ApiErrorResponse> { | ||
| let redis_conn = state | ||
| .store | ||
| .get_redis_conn() | ||
| .change_context(errors::ApiErrorResponse::InternalServerError) | ||
| .attach_printable("Failed to get redis connection")?; | ||
|
|
||
| logger::debug!( | ||
| "Fetching payment method token data from redis for key: {}", | ||
| self.key_for_token | ||
| ); | ||
|
|
||
| let pm_token_data = redis_conn | ||
| .get_and_deserialize_key::<PaymentTokenData>( | ||
| &self.key_for_token.as_str().into(), | ||
| "Token Data", | ||
| ) | ||
| .await | ||
| .map_err(|e| error_stack::report!(storage_impl::StorageError::from(e))) | ||
| .to_not_found_response(errors::ApiErrorResponse::GenericNotFoundError { | ||
| message: "Payment method token either expired or does not exist".to_string(), | ||
| })?; | ||
| Ok(pm_token_data) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we create an issue for this?
| let temporary_token = temporary_token.clone(); | ||
| async move { | ||
| let platform: domain::Platform = auth.platform; | ||
| payment_methods_routes::payment_method_get_token( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
| payment_methods_routes::payment_method_get_token( | |
| payment_methods_routes::payment_method_get_token_details_core( |
…juspay/hyperswitch into feat/payment-method-id-by-payment-token
| }, | ||
| )) | ||
| } | ||
| Ok(_) => Err(errors::ApiErrorResponse::PaymentMethodNotFound.into()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in case guest checkout flow,
currently we have permenant card, but it should temporary.
@su-shivanshmathur we need to verify on how we are insert this payment method token, when storage type is volatile
… for V2 (#10834) Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
Type of Change
Adding a new API for getting Payment Method Id ( GlobalPaymentMethodId ) from the payment token provided to it
Description
There is no way of getting the Payment method ID for the given token for now, so adding an API for the usecase
Additional Changes
Motivation and Context
How did you test it?
Request
Response
{ "id": "12345_pms_019b904d507e73708c9480d1a1e050a7", "customer_id": "12345_cus_019b5979a1387ed1b3b314cbb56a656d", "billing": { "address": { "city": null, "country": null, "line1": null, "line2": null, "line3": null, "zip": null, "state": null, "first_name": "John", "last_name": "Dough", "origin_zip": null }, "phone": null, "email": "[email protected]" }, "psp_tokenization": null, "network_tokenization": null, "tokenization_data": null, "expires_at": "2026-01-05T22:50:44.638Z", "client_secret": "cs_019b904d507f7481be1d6717714526e1", "return_url": null, "next_action": null, "authentication_details": null, "associated_payment_methods": null, "associated_token_id": null, "storage_type": null }Request
Response
{ "id": "12345_pms_019b904d507e73708c9480d1a1e050a7", "customer_id": "12345_cus_019b5979a1387ed1b3b314cbb56a656d", "billing": { "address": { "city": null, "country": null, "line1": null, "line2": null, "line3": null, "zip": null, "state": null, "first_name": "John", "last_name": "Dough", "origin_zip": null }, "phone": null, "email": "[email protected]" }, "psp_tokenization": null, "network_tokenization": null, "tokenization_data": null, "expires_at": "2026-01-05T22:50:44.638Z", "client_secret": "CLIENT_SECRET_REDACTED", "return_url": null, "next_action": null, "authentication_details": null, "associated_payment_methods": [ "token_OVci7wWJf28RjQPWaJD1" ], "associated_token_id": null, "storage_type": null }{"id":"12345_pm_019b8eef5f077163a9f5b3b0973c4301","payment_method_token":"token_OVci7wWJf28RjQPWaJD1"}Checklist
cargo +nightly fmt --allcargo clippy