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): Add payment_methods_session_delete_payment_method endpoint [V2] #7409

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
openapi: delete /v2/payment-method-session/:id
---
3 changes: 2 additions & 1 deletion api-reference-v2/mint.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@
"api-reference/payment-method-session/payment-method-session--retrieve",
"api-reference/payment-method-session/payment-method-session--list-payment-methods",
"api-reference/payment-method-session/payment-method-session--update-a-saved-payment-method",
"api-reference/payment-method-session/payment-method-session--confirm-a-payment-method-session"
"api-reference/payment-method-session/payment-method-session--confirm-a-payment-method-session",
"api-reference/payment-method-session/payment-method-session--delete-a-saved-payment-method"
]
},
{
Expand Down
108 changes: 103 additions & 5 deletions api-reference-v2/openapi_spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -2960,6 +2960,62 @@
"ephemeral_key": []
}
]
},
"delete": {
"tags": [
"Payment Method Session"
],
"summary": "Payment Method Session - Delete a saved payment method",
"description": "Delete a saved payment method from the given payment method session.",
"operationId": "Delete a saved payment method",
"parameters": [
{
"name": "id",
"in": "path",
"description": "The unique identifier for the Payment Method Session",
"required": true,
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PaymentMethodSessionDeleteSavedPaymentMethod"
},
"examples": {
"Update the card holder name": {
"value": {
"payment_method_id": "12345_pm_0194b1ecabc172e28aeb71f70a4daba3"
}
}
}
}
},
"required": true
},
"responses": {
"200": {
"description": "The payment method has been updated successfully",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PaymentMethodDeleteResponse"
}
}
}
},
"404": {
"description": "The request is invalid"
}
},
"security": [
{
"ephemeral_key": []
}
]
}
},
"/v2/payment-method-session/:id/list-payment-methods": {
Expand Down Expand Up @@ -4453,6 +4509,25 @@
"unified_authentication_service"
]
},
"AuthenticationDetails": {
"type": "object",
"required": [
"status"
],
"properties": {
"status": {
"$ref": "#/components/schemas/IntentStatus"
},
"error": {
"allOf": [
{
"$ref": "#/components/schemas/ErrorDetails"
}
],
"nullable": true
}
}
},
"AuthenticationStatus": {
"type": "string",
"enum": [
Expand Down Expand Up @@ -12587,6 +12662,14 @@
"type": "string",
"description": "The url for Qr code given by the connector"
},
"display_text": {
"type": "string",
"nullable": true
},
"border_color": {
"type": "string",
"nullable": true
},
"type": {
"type": "string",
"enum": [
Expand Down Expand Up @@ -14853,13 +14936,18 @@
"PaymentMethodDeleteResponse": {
"type": "object",
"required": [
"id"
"id",
"deleted"
],
"properties": {
"id": {
"type": "string",
"description": "The unique identifier of the Payment method",
"example": "12345_pm_01926c58bc6e77c09e809964e72af8c8"
},
"deleted": {
"type": "boolean",
"description": "Whether payment method was deleted or not"
}
}
},
Expand Down Expand Up @@ -15193,6 +15281,19 @@
}
}
},
"PaymentMethodSessionDeleteSavedPaymentMethod": {
"type": "object",
"required": [
"payment_method_id"
],
"properties": {
"payment_method_id": {
"type": "string",
"description": "The payment method id of the payment method to be updated",
"example": "12345_pm_01926c58bc6e77c09e809964e72af8c8"
}
}
},
"PaymentMethodSessionRequest": {
"type": "object",
"required": [
Expand Down Expand Up @@ -15318,10 +15419,7 @@
"nullable": true
},
"associated_payment_methods": {
"type": "array",
"items": {
"$ref": "#/components/schemas/id_type.GlobalPaymentMethodId"
},
"type": "string",
"description": "The payment method that was created using this payment method session",
"nullable": true
}
Expand Down
14 changes: 14 additions & 0 deletions crates/api_models/src/payment_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1906,6 +1906,9 @@ pub struct PaymentMethodDeleteResponse {
/// The unique identifier of the Payment method
#[schema(value_type = String, example = "12345_pm_01926c58bc6e77c09e809964e72af8c8")]
pub id: id_type::GlobalPaymentMethodId,

/// Whether payment method was deleted or not
pub deleted: bool,
}

#[cfg(feature = "v1")]
Expand Down Expand Up @@ -2601,6 +2604,14 @@ pub struct PaymentMethodSessionUpdateSavedPaymentMethod {
pub payment_method_update_request: PaymentMethodUpdate,
}

#[cfg(feature = "v2")]
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, ToSchema)]
pub struct PaymentMethodSessionDeleteSavedPaymentMethod {
/// The payment method id of the payment method to be updated
#[schema(value_type = String, example = "12345_pm_01926c58bc6e77c09e809964e72af8c8")]
pub payment_method_id: id_type::GlobalPaymentMethodId,
}

#[cfg(feature = "v2")]
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, ToSchema)]
pub struct PaymentMethodSessionConfirmRequest {
Expand Down Expand Up @@ -2666,12 +2677,15 @@ pub struct PaymentMethodSessionResponse {
pub authentication_details: Option<AuthenticationDetails>,

/// The payment method that was created using this payment method session
#[schema(value_type = Option<String>)]
pub associated_payment_methods: Option<Vec<id_type::GlobalPaymentMethodId>>,
}

#[cfg(feature = "v2")]
#[derive(Debug, serde::Serialize, ToSchema, Clone)]
pub struct AuthenticationDetails {
#[schema(value_type = IntentStatus)]
pub status: common_enums::IntentStatus,
#[schema(value_type = Option<ErrorDetails>)]
pub error: Option<payments::ErrorDetails>,
}
3 changes: 3 additions & 0 deletions crates/openapi/src/openapi_v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ Never share your secret api keys. Keep them guarded and secure.
routes::payment_method::payment_method_session_retrieve,
routes::payment_method::payment_method_session_list_payment_methods,
routes::payment_method::payment_method_session_update_saved_payment_method,
routes::payment_method::payment_method_session_delete_saved_payment_method,
routes::payment_method::payment_method_session_confirm,

//Routes for refunds
Expand Down Expand Up @@ -212,6 +213,7 @@ Never share your secret api keys. Keep them guarded and secure.
api_models::payment_methods::PaymentMethodCreate,
api_models::payment_methods::PaymentMethodIntentCreate,
api_models::payment_methods::PaymentMethodIntentConfirm,
api_models::payment_methods::AuthenticationDetails,
api_models::payment_methods::PaymentMethodResponse,
api_models::payment_methods::PaymentMethodResponseData,
api_models::payment_methods::CustomerPaymentMethod,
Expand Down Expand Up @@ -686,6 +688,7 @@ Never share your secret api keys. Keep them guarded and secure.
api_models::feature_matrix::CardSpecificFeatures,
api_models::feature_matrix::SupportedPaymentMethod,
api_models::payment_methods::PaymentMethodSessionUpdateSavedPaymentMethod,
api_models::payment_methods::PaymentMethodSessionDeleteSavedPaymentMethod,
common_utils::types::BrowserInformation,
api_models::enums::TokenizationType,
api_models::enums::NetworkTokenizationToggle,
Expand Down
29 changes: 29 additions & 0 deletions crates/openapi/src/routes/payment_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,35 @@ pub fn payment_method_session_list_payment_methods() {}
)]
pub fn payment_method_session_update_saved_payment_method() {}

/// Payment Method Session - Delete a saved payment method
///
/// Delete a saved payment method from the given payment method session.
#[cfg(feature = "v2")]
#[utoipa::path(
delete,
path = "/v2/payment-method-session/:id",
params (
("id" = String, Path, description = "The unique identifier for the Payment Method Session"),
),
request_body(
content = PaymentMethodSessionDeleteSavedPaymentMethod,
examples(( "Update the card holder name" = (
value =json!( {
"payment_method_id": "12345_pm_0194b1ecabc172e28aeb71f70a4daba3",
}
)
)))
),
responses(
(status = 200, description = "The payment method has been updated successfully", body = PaymentMethodDeleteResponse),
(status = 404, description = "The request is invalid")
),
tag = "Payment Method Session",
operation_id = "Delete a saved payment method",
security(("ephemeral_key" = []))
)]
pub fn payment_method_session_delete_saved_payment_method() {}

/// Payment Method Session - Confirm a payment method session
///
/// **Confirms a payment method session object with the payment method data**
Expand Down
51 changes: 46 additions & 5 deletions crates/router/src/core/payment_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1928,12 +1928,24 @@ pub async fn delete_payment_method(
key_store: domain::MerchantKeyStore,
merchant_account: domain::MerchantAccount,
) -> RouterResponse<api::PaymentMethodDeleteResponse> {
let db = state.store.as_ref();
let key_manager_state = &(&state).into();

let pm_id = id_type::GlobalPaymentMethodId::generate_from_string(pm_id.payment_method_id)
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Unable to generate GlobalPaymentMethodId")?;
let response = delete_payment_method_core(state, pm_id, key_store, merchant_account).await?;

Ok(services::ApplicationResponse::Json(response))
}

#[cfg(all(feature = "v2", feature = "payment_methods_v2"))]
#[instrument(skip_all)]
pub async fn delete_payment_method_core(
state: SessionState,
pm_id: id_type::GlobalPaymentMethodId,
key_store: domain::MerchantKeyStore,
merchant_account: domain::MerchantAccount,
) -> RouterResult<api::PaymentMethodDeleteResponse> {
let db = state.store.as_ref();
let key_manager_state = &(&state).into();

let payment_method = db
.find_payment_method(
Expand Down Expand Up @@ -1989,9 +2001,12 @@ pub async fn delete_payment_method(
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Failed to delete payment method from vault")?;

let response = api::PaymentMethodDeleteResponse { id: pm_id };
let response = api::PaymentMethodDeleteResponse {
id: pm_id,
deleted: true,
};

Ok(services::ApplicationResponse::Json(response))
Ok(response)
}

#[cfg(feature = "v2")]
Expand Down Expand Up @@ -2322,6 +2337,32 @@ pub async fn payment_methods_session_update_payment_method(
Ok(services::ApplicationResponse::Json(updated_payment_method))
}

#[cfg(feature = "v2")]
pub async fn payment_methods_session_delete_payment_method(
state: SessionState,
key_store: domain::MerchantKeyStore,
merchant_account: domain::MerchantAccount,
pm_id: id_type::GlobalPaymentMethodId,
payment_method_session_id: id_type::GlobalPaymentMethodSessionId,
) -> RouterResponse<api::PaymentMethodDeleteResponse> {
let db = state.store.as_ref();
let key_manager_state = &(&state).into();

// Validate if the session still exists
db.get_payment_methods_session(key_manager_state, &key_store, &payment_method_session_id)
.await
.to_not_found_response(errors::ApiErrorResponse::GenericNotFoundError {
message: "payment methods session does not exist or has expired".to_string(),
})
.attach_printable("Failed to retrieve payment methods session from db")?;

let response = delete_payment_method_core(state, pm_id, key_store, merchant_account)
.await
.attach_printable("Failed to delete saved payment method")?;

Ok(services::ApplicationResponse::Json(response))
}

#[cfg(feature = "v2")]
fn construct_zero_auth_payments_request(
confirm_request: &payment_methods::PaymentMethodSessionConfirmRequest,
Expand Down
5 changes: 4 additions & 1 deletion crates/router/src/routes/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1310,7 +1310,10 @@ impl PaymentMethodSession {
.service(
web::resource("")
.route(web::get().to(payment_methods::payment_methods_session_retrieve))
.route(web::put().to(payment_methods::payment_methods_session_update)),
.route(web::put().to(payment_methods::payment_methods_session_update))
.route(web::delete().to(
payment_methods::payment_method_session_delete_saved_payment_method,
)),
)
.service(web::resource("/list-payment-methods").route(
web::get().to(payment_methods::payment_method_session_list_payment_methods),
Expand Down
1 change: 1 addition & 0 deletions crates/router/src/routes/lock_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ impl From<Flow> for ApiIdentifier {
| Flow::PaymentMethodSessionRetrieve
| Flow::PaymentMethodSessionConfirm
| Flow::PaymentMethodSessionUpdateSavedPaymentMethod
| Flow::PaymentMethodSessionDeleteSavedPaymentMethod
| Flow::PaymentMethodSessionUpdate => Self::PaymentMethodSession,
}
}
Expand Down
Loading
Loading