mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 09:07:09 +08:00
feat(core): [NETWORK TOKENIZATION] Check Network Token Status API (#9443)
This commit is contained in:
@ -284,6 +284,12 @@
|
||||
"v2/payment-methods/list-saved-payment-methods-for-a-customer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Network Tokenization",
|
||||
"pages": [
|
||||
"v2/payment-methods/check-network-token-status"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Payment Method Session",
|
||||
"pages": [
|
||||
|
||||
@ -2891,6 +2891,47 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v2/payment-methods/{payment_method_id}/check-network-token-status": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Payment Methods"
|
||||
],
|
||||
"summary": "Payment Method - Check Network Token Status",
|
||||
"description": "Check the status of a network token for a saved payment method",
|
||||
"operationId": "Check Network Token Status",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "payment_method_id",
|
||||
"in": "path",
|
||||
"description": "The unique identifier for the Payment Method",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Network Token Status Retrieved",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/NetworkTokenStatusCheckResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Payment Method Not Found"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"api_key": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v2/customers/{id}/saved-payment-methods": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@ -15305,6 +15346,115 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"NetworkTokenStatusCheckFailureResponse": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"error_message"
|
||||
],
|
||||
"properties": {
|
||||
"error_message": {
|
||||
"type": "string",
|
||||
"description": "Error message describing what went wrong"
|
||||
}
|
||||
}
|
||||
},
|
||||
"NetworkTokenStatusCheckResponse": {
|
||||
"oneOf": [
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/NetworkTokenStatusCheckSuccessResponse"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"success_response"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/NetworkTokenStatusCheckFailureResponse"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"failure_response"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"discriminator": {
|
||||
"propertyName": "type"
|
||||
}
|
||||
},
|
||||
"NetworkTokenStatusCheckSuccessResponse": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"status",
|
||||
"token_expiry_month",
|
||||
"token_expiry_year",
|
||||
"card_last_four",
|
||||
"token_last_four",
|
||||
"card_expiry",
|
||||
"payment_method_id",
|
||||
"customer_id"
|
||||
],
|
||||
"properties": {
|
||||
"status": {
|
||||
"$ref": "#/components/schemas/TokenStatus"
|
||||
},
|
||||
"token_expiry_month": {
|
||||
"type": "string",
|
||||
"description": "The expiry month of the network token if active"
|
||||
},
|
||||
"token_expiry_year": {
|
||||
"type": "string",
|
||||
"description": "The expiry year of the network token if active"
|
||||
},
|
||||
"card_last_four": {
|
||||
"type": "string",
|
||||
"description": "The last four digits of the card"
|
||||
},
|
||||
"token_last_four": {
|
||||
"type": "string",
|
||||
"description": "The last four digits of the network token"
|
||||
},
|
||||
"card_expiry": {
|
||||
"type": "string",
|
||||
"description": "The expiry date of the card in MM/YY format"
|
||||
},
|
||||
"payment_method_id": {
|
||||
"type": "string",
|
||||
"description": "The payment method ID that was checked",
|
||||
"example": "12345_pm_019959146f92737389eb6927ce1eb7dc"
|
||||
},
|
||||
"customer_id": {
|
||||
"type": "string",
|
||||
"description": "The customer ID associated with the payment method",
|
||||
"example": "12345_cus_0195dc62bb8e7312a44484536da76aef"
|
||||
}
|
||||
}
|
||||
},
|
||||
"NetworkTokenization": {
|
||||
"type": "object",
|
||||
"description": "The network tokenization configuration for creating the payment method session",
|
||||
@ -26042,6 +26192,14 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"TokenStatus": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"ACTIVE",
|
||||
"SUSPENDED",
|
||||
"DEACTIVATED"
|
||||
]
|
||||
},
|
||||
"TokenType": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
|
||||
@ -492,3 +492,29 @@ impl From<PermissionScope> for ReconPermissionScope {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "v2")]
|
||||
#[derive(
|
||||
Clone,
|
||||
Copy,
|
||||
Debug,
|
||||
Eq,
|
||||
Hash,
|
||||
PartialEq,
|
||||
ToSchema,
|
||||
serde::Deserialize,
|
||||
serde::Serialize,
|
||||
strum::Display,
|
||||
strum::EnumIter,
|
||||
strum::EnumString,
|
||||
)]
|
||||
#[serde(rename_all = "UPPERCASE")]
|
||||
#[strum(serialize_all = "UPPERCASE")]
|
||||
pub enum TokenStatus {
|
||||
/// Indicates that the token is active and can be used for payments
|
||||
Active,
|
||||
/// Indicates that the token is suspended from network's end for some reason and can't be used for payments until it is re-activated
|
||||
Suspended,
|
||||
/// Indicates that the token is deactivated and further can't be used for payments
|
||||
Deactivated,
|
||||
}
|
||||
|
||||
@ -3262,3 +3262,56 @@ pub struct AuthenticationDetails {
|
||||
#[schema(value_type = Option<ErrorDetails>)]
|
||||
pub error: Option<payments::ErrorDetails>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "v2")]
|
||||
#[derive(Debug, serde::Serialize, ToSchema)]
|
||||
pub struct NetworkTokenStatusCheckSuccessResponse {
|
||||
/// The status of the network token
|
||||
#[schema(value_type = TokenStatus)]
|
||||
pub status: api_enums::TokenStatus,
|
||||
|
||||
/// The expiry month of the network token if active
|
||||
#[schema(value_type = String)]
|
||||
pub token_expiry_month: masking::Secret<String>,
|
||||
|
||||
/// The expiry year of the network token if active
|
||||
#[schema(value_type = String)]
|
||||
pub token_expiry_year: masking::Secret<String>,
|
||||
|
||||
/// The last four digits of the card
|
||||
pub card_last_four: String,
|
||||
|
||||
/// The last four digits of the network token
|
||||
pub token_last_four: String,
|
||||
|
||||
/// The expiry date of the card in MM/YY format
|
||||
pub card_expiry: String,
|
||||
|
||||
/// The payment method ID that was checked
|
||||
#[schema(value_type = String, example = "12345_pm_019959146f92737389eb6927ce1eb7dc")]
|
||||
pub payment_method_id: id_type::GlobalPaymentMethodId,
|
||||
|
||||
/// The customer ID associated with the payment method
|
||||
#[schema(value_type = String, example = "12345_cus_0195dc62bb8e7312a44484536da76aef")]
|
||||
pub customer_id: id_type::GlobalCustomerId,
|
||||
}
|
||||
|
||||
#[cfg(feature = "v2")]
|
||||
impl common_utils::events::ApiEventMetric for NetworkTokenStatusCheckResponse {}
|
||||
|
||||
#[cfg(feature = "v2")]
|
||||
#[derive(Debug, serde::Serialize, ToSchema)]
|
||||
pub struct NetworkTokenStatusCheckFailureResponse {
|
||||
/// Error message describing what went wrong
|
||||
pub error_message: String,
|
||||
}
|
||||
|
||||
#[cfg(feature = "v2")]
|
||||
#[derive(Debug, serde::Serialize, ToSchema)]
|
||||
#[serde(tag = "type", rename_all = "snake_case")]
|
||||
pub enum NetworkTokenStatusCheckResponse {
|
||||
/// Successful network token status check response
|
||||
SuccessResponse(NetworkTokenStatusCheckSuccessResponse),
|
||||
/// Error response for network token status check
|
||||
FailureResponse(NetworkTokenStatusCheckFailureResponse),
|
||||
}
|
||||
|
||||
@ -137,6 +137,7 @@ Never share your secret api keys. Keep them guarded and secure.
|
||||
routes::payment_method::payment_method_update_api,
|
||||
routes::payment_method::payment_method_retrieve_api,
|
||||
routes::payment_method::payment_method_delete_api,
|
||||
routes::payment_method::network_token_status_check_api,
|
||||
routes::payment_method::list_customer_payment_method_api,
|
||||
|
||||
//Routes for payment method session
|
||||
@ -273,6 +274,10 @@ Never share your secret api keys. Keep them guarded and secure.
|
||||
api_models::payment_methods::RequestPaymentMethodTypes,
|
||||
api_models::payment_methods::CardType,
|
||||
api_models::payment_methods::PaymentMethodListData,
|
||||
api_models::payment_methods::NetworkTokenStatusCheckResponse,
|
||||
api_models::payment_methods::NetworkTokenStatusCheckSuccessResponse,
|
||||
api_models::payment_methods::NetworkTokenStatusCheckFailureResponse,
|
||||
api_models::enums::TokenStatus,
|
||||
api_models::poll::PollResponse,
|
||||
api_models::poll::PollStatus,
|
||||
api_models::customers::CustomerResponse,
|
||||
|
||||
@ -325,6 +325,26 @@ pub async fn payment_method_update_api() {}
|
||||
#[cfg(feature = "v2")]
|
||||
pub async fn payment_method_delete_api() {}
|
||||
|
||||
/// Payment Method - Check Network Token Status
|
||||
///
|
||||
/// Check the status of a network token for a saved payment method
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/v2/payment-methods/{payment_method_id}/check-network-token-status",
|
||||
params (
|
||||
("payment_method_id" = String, Path, description = "The unique identifier for the Payment Method"),
|
||||
),
|
||||
responses(
|
||||
(status = 200, description = "Network Token Status Retrieved", body = NetworkTokenStatusCheckResponse),
|
||||
(status = 404, description = "Payment Method Not Found"),
|
||||
),
|
||||
tag = "Payment Methods",
|
||||
operation_id = "Check Network Token Status",
|
||||
security(("api_key" = []))
|
||||
)]
|
||||
#[cfg(feature = "v2")]
|
||||
pub async fn network_token_status_check_api() {}
|
||||
|
||||
/// Payment Method - List Customer Saved Payment Methods
|
||||
///
|
||||
/// List the payment methods saved for a customer
|
||||
|
||||
@ -3913,3 +3913,99 @@ async fn get_single_use_token_from_store(
|
||||
.change_context(errors::StorageError::KVError)
|
||||
.attach_printable("Failed to get payment method token from redis")
|
||||
}
|
||||
|
||||
#[cfg(feature = "v2")]
|
||||
#[instrument(skip_all)]
|
||||
async fn fetch_payment_method(
|
||||
state: &SessionState,
|
||||
merchant_context: &domain::MerchantContext,
|
||||
payment_method_id: &id_type::GlobalPaymentMethodId,
|
||||
) -> RouterResult<domain::PaymentMethod> {
|
||||
let db = &state.store;
|
||||
let key_manager_state = &state.into();
|
||||
let merchant_account = merchant_context.get_merchant_account();
|
||||
let key_store = merchant_context.get_merchant_key_store();
|
||||
|
||||
db.find_payment_method(
|
||||
key_manager_state,
|
||||
key_store,
|
||||
payment_method_id,
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::PaymentMethodNotFound)
|
||||
.attach_printable("Payment method not found for network token status check")
|
||||
}
|
||||
|
||||
#[cfg(feature = "v2")]
|
||||
pub async fn check_network_token_status(
|
||||
state: SessionState,
|
||||
merchant_context: domain::MerchantContext,
|
||||
payment_method_id: id_type::GlobalPaymentMethodId,
|
||||
) -> RouterResponse<payment_methods::NetworkTokenStatusCheckResponse> {
|
||||
// Retrieve the payment method from the database
|
||||
let payment_method =
|
||||
fetch_payment_method(&state, &merchant_context, &payment_method_id).await?;
|
||||
|
||||
// Call the network token status check function
|
||||
let network_token_status_check_response = if payment_method.status
|
||||
== common_enums::PaymentMethodStatus::Active
|
||||
{
|
||||
// Check if the payment method has network token data
|
||||
when(
|
||||
payment_method
|
||||
.network_token_requestor_reference_id
|
||||
.is_none(),
|
||||
|| {
|
||||
Err(errors::ApiErrorResponse::InvalidDataValue {
|
||||
field_name: "payment_method_id",
|
||||
})
|
||||
},
|
||||
)?;
|
||||
match network_tokenization::do_status_check_for_network_token(&state, &payment_method).await
|
||||
{
|
||||
Ok(network_token_details) => {
|
||||
let status = match network_token_details.token_status {
|
||||
pm_types::TokenStatus::Active => api_enums::TokenStatus::Active,
|
||||
pm_types::TokenStatus::Suspended => api_enums::TokenStatus::Suspended,
|
||||
pm_types::TokenStatus::Deactivated => api_enums::TokenStatus::Deactivated,
|
||||
};
|
||||
|
||||
payment_methods::NetworkTokenStatusCheckResponse::SuccessResponse(
|
||||
payment_methods::NetworkTokenStatusCheckSuccessResponse {
|
||||
status,
|
||||
token_expiry_month: network_token_details.token_expiry_month,
|
||||
token_expiry_year: network_token_details.token_expiry_year,
|
||||
card_last_four: network_token_details.card_last_4,
|
||||
card_expiry: network_token_details.card_expiry,
|
||||
token_last_four: network_token_details.token_last_4,
|
||||
payment_method_id,
|
||||
customer_id: payment_method.customer_id,
|
||||
},
|
||||
)
|
||||
}
|
||||
Err(e) => {
|
||||
let err_message = e.current_context().to_string();
|
||||
logger::debug!("Network token status check failed: {:?}", e);
|
||||
|
||||
payment_methods::NetworkTokenStatusCheckResponse::FailureResponse(
|
||||
payment_methods::NetworkTokenStatusCheckFailureResponse {
|
||||
error_message: err_message,
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let err_message = "Payment Method is not active".to_string();
|
||||
logger::debug!("Payment Method is not active");
|
||||
|
||||
payment_methods::NetworkTokenStatusCheckResponse::FailureResponse(
|
||||
payment_methods::NetworkTokenStatusCheckFailureResponse {
|
||||
error_message: err_message,
|
||||
},
|
||||
)
|
||||
};
|
||||
Ok(services::ApplicationResponse::Json(
|
||||
network_token_status_check_response,
|
||||
))
|
||||
}
|
||||
|
||||
@ -778,24 +778,125 @@ pub async fn check_token_status_with_tokenization_service(
|
||||
.parse_struct("Delete Network Tokenization Response")
|
||||
.change_context(errors::NetworkTokenizationError::ResponseDeserializationFailed)?;
|
||||
|
||||
match check_token_status_response.payload.token_status {
|
||||
match check_token_status_response.token_status {
|
||||
pm_types::TokenStatus::Active => Ok((
|
||||
Some(check_token_status_response.payload.token_expiry_month),
|
||||
Some(check_token_status_response.payload.token_expiry_year),
|
||||
Some(check_token_status_response.token_expiry_month),
|
||||
Some(check_token_status_response.token_expiry_year),
|
||||
)),
|
||||
pm_types::TokenStatus::Inactive => Ok((None, None)),
|
||||
_ => Ok((None, None)),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "v2")]
|
||||
pub async fn check_token_status_with_tokenization_service(
|
||||
_state: &routes::SessionState,
|
||||
_customer_id: &id_type::GlobalCustomerId,
|
||||
_network_token_requestor_reference_id: String,
|
||||
_tokenization_service: &settings::NetworkTokenizationService,
|
||||
) -> CustomResult<(Option<Secret<String>>, Option<Secret<String>>), errors::NetworkTokenizationError>
|
||||
{
|
||||
todo!()
|
||||
state: &routes::SessionState,
|
||||
customer_id: &id_type::GlobalCustomerId,
|
||||
network_token_requestor_reference_id: String,
|
||||
tokenization_service: &settings::NetworkTokenizationService,
|
||||
) -> CustomResult<pm_types::CheckTokenStatusResponse, errors::NetworkTokenizationError> {
|
||||
let mut request = services::Request::new(
|
||||
services::Method::Post,
|
||||
tokenization_service.check_token_status_url.as_str(),
|
||||
);
|
||||
let payload = pm_types::CheckTokenStatus {
|
||||
card_reference: network_token_requestor_reference_id,
|
||||
customer_id: customer_id.clone(),
|
||||
};
|
||||
|
||||
request.add_header(headers::CONTENT_TYPE, "application/json".into());
|
||||
request.add_header(
|
||||
headers::AUTHORIZATION,
|
||||
tokenization_service
|
||||
.token_service_api_key
|
||||
.clone()
|
||||
.peek()
|
||||
.clone()
|
||||
.into_masked(),
|
||||
);
|
||||
request.add_default_headers();
|
||||
request.set_body(RequestContent::Json(Box::new(payload)));
|
||||
|
||||
// Send the request using `call_connector_api`
|
||||
let response = services::call_connector_api(state, request, "Check Network token Status")
|
||||
.await
|
||||
.change_context(errors::NetworkTokenizationError::ApiError);
|
||||
let res = response
|
||||
.change_context(errors::NetworkTokenizationError::ResponseDeserializationFailed)
|
||||
.attach_printable("Error while receiving response")
|
||||
.and_then(|inner| match inner {
|
||||
Err(err_res) => {
|
||||
let parsed_error: pm_types::NetworkTokenErrorResponse = err_res
|
||||
.response
|
||||
.parse_struct("Network Tokenization Error Response")
|
||||
.change_context(
|
||||
errors::NetworkTokenizationError::ResponseDeserializationFailed,
|
||||
)?;
|
||||
logger::error!(
|
||||
error_code = %parsed_error.error_info.code,
|
||||
developer_message = %parsed_error.error_info.developer_message,
|
||||
"Network tokenization error: {}",
|
||||
parsed_error.error_message
|
||||
);
|
||||
Err(errors::NetworkTokenizationError::ResponseDeserializationFailed)
|
||||
.attach_printable(format!("Response Deserialization Failed: {err_res:?}"))
|
||||
}
|
||||
Ok(res) => Ok(res),
|
||||
})
|
||||
.inspect_err(|err| {
|
||||
logger::error!("Error while deserializing response: {:?}", err);
|
||||
})?;
|
||||
|
||||
let check_token_status_response: pm_types::CheckTokenStatusResponse = res
|
||||
.response
|
||||
.parse_struct("CheckTokenStatusResponse")
|
||||
.change_context(errors::NetworkTokenizationError::ResponseDeserializationFailed)?;
|
||||
|
||||
Ok(check_token_status_response)
|
||||
}
|
||||
|
||||
#[cfg(feature = "v2")]
|
||||
pub async fn do_status_check_for_network_token(
|
||||
state: &routes::SessionState,
|
||||
payment_method_info: &domain::PaymentMethod,
|
||||
) -> CustomResult<pm_types::CheckTokenStatusResponse, errors::NetworkTokenizationError> {
|
||||
let network_token_requestor_reference_id = payment_method_info
|
||||
.network_token_requestor_reference_id
|
||||
.clone();
|
||||
|
||||
if let Some(ref_id) = network_token_requestor_reference_id {
|
||||
if let Some(network_tokenization_service) = &state.conf.network_tokenization_service {
|
||||
let network_token_details = record_operation_time(
|
||||
async {
|
||||
check_token_status_with_tokenization_service(
|
||||
state,
|
||||
&payment_method_info.customer_id,
|
||||
ref_id,
|
||||
network_tokenization_service.get_inner(),
|
||||
)
|
||||
.await
|
||||
.inspect_err(
|
||||
|e| logger::error!(error=?e, "Error while fetching token from tokenization service")
|
||||
)
|
||||
.attach_printable(
|
||||
"Check network token status with tokenization service failed",
|
||||
)
|
||||
},
|
||||
&metrics::CHECK_NETWORK_TOKEN_STATUS_TIME,
|
||||
&[],
|
||||
)
|
||||
.await?;
|
||||
Ok(network_token_details)
|
||||
} else {
|
||||
Err(errors::NetworkTokenizationError::NetworkTokenizationServiceNotConfigured)
|
||||
.attach_printable("Network Tokenization Service not configured")
|
||||
.inspect_err(|_| {
|
||||
logger::error!("Network Tokenization Service not configured");
|
||||
})
|
||||
}
|
||||
} else {
|
||||
Err(errors::NetworkTokenizationError::FetchNetworkTokenFailed)
|
||||
.attach_printable("Check network token status failed")?
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "v1")]
|
||||
|
||||
@ -1455,6 +1455,10 @@ impl PaymentMethods {
|
||||
.service(
|
||||
web::resource("/create-intent")
|
||||
.route(web::post().to(payment_methods::create_payment_method_intent_api)),
|
||||
)
|
||||
.service(
|
||||
web::resource("/{payment_method_id}/check-network-token-status")
|
||||
.route(web::get().to(payment_methods::network_token_status_check_api)),
|
||||
);
|
||||
|
||||
route = route.service(
|
||||
|
||||
@ -126,6 +126,7 @@ impl From<Flow> for ApiIdentifier {
|
||||
| Flow::PaymentMethodsRetrieve
|
||||
| Flow::PaymentMethodsUpdate
|
||||
| Flow::PaymentMethodsDelete
|
||||
| Flow::NetworkTokenStatusCheck
|
||||
| Flow::PaymentMethodCollectLink
|
||||
| Flow::ValidatePaymentMethod
|
||||
| Flow::ListCountriesCurrencies
|
||||
|
||||
@ -1559,3 +1559,37 @@ pub async fn payment_method_session_delete_saved_payment_method(
|
||||
))
|
||||
.await
|
||||
}
|
||||
|
||||
#[cfg(feature = "v2")]
|
||||
#[instrument(skip_all, fields(flow = ?Flow::NetworkTokenStatusCheck))]
|
||||
pub async fn network_token_status_check_api(
|
||||
state: web::Data<AppState>,
|
||||
req: HttpRequest,
|
||||
path: web::Path<id_type::GlobalPaymentMethodId>,
|
||||
) -> HttpResponse {
|
||||
let flow = Flow::NetworkTokenStatusCheck;
|
||||
let payment_method_id = path.into_inner();
|
||||
|
||||
Box::pin(api::server_wrap(
|
||||
flow,
|
||||
state,
|
||||
&req,
|
||||
payment_method_id,
|
||||
|state, auth: auth::AuthenticationData, payment_method_id, _| {
|
||||
let merchant_context = domain::MerchantContext::NormalMerchant(Box::new(
|
||||
domain::Context(auth.merchant_account, auth.key_store),
|
||||
));
|
||||
payment_methods_routes::check_network_token_status(
|
||||
state,
|
||||
merchant_context,
|
||||
payment_method_id,
|
||||
)
|
||||
},
|
||||
&auth::V2ApiKeyAuth {
|
||||
is_connected_allowed: false,
|
||||
is_platform_allowed: false,
|
||||
},
|
||||
api_locking::LockAction::NotApplicable,
|
||||
))
|
||||
.await
|
||||
}
|
||||
|
||||
@ -344,24 +344,23 @@ pub struct CheckTokenStatus {
|
||||
pub customer_id: id_type::GlobalCustomerId,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
#[serde(rename_all = "UPPERCASE")]
|
||||
pub enum TokenStatus {
|
||||
Active,
|
||||
Inactive,
|
||||
Suspended,
|
||||
Deactivated,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CheckTokenStatusResponsePayload {
|
||||
pub struct CheckTokenStatusResponse {
|
||||
pub token_status: TokenStatus,
|
||||
pub token_expiry_month: Secret<String>,
|
||||
pub token_expiry_year: Secret<String>,
|
||||
pub token_status: TokenStatus,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct CheckTokenStatusResponse {
|
||||
pub payload: CheckTokenStatusResponsePayload,
|
||||
pub card_last_4: String,
|
||||
pub card_expiry: String,
|
||||
pub token_last_4: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
|
||||
@ -140,6 +140,8 @@ pub enum Flow {
|
||||
PaymentMethodsUpdate,
|
||||
/// Payment methods delete flow.
|
||||
PaymentMethodsDelete,
|
||||
/// Network token status check flow.
|
||||
NetworkTokenStatusCheck,
|
||||
/// Default Payment method flow.
|
||||
DefaultPaymentMethodsSet,
|
||||
/// Payments create flow.
|
||||
|
||||
Reference in New Issue
Block a user