Skip to content

Commit

Permalink
Merge branch 'main' into add-incremental-authorization-api
Browse files Browse the repository at this point in the history
  • Loading branch information
sai-harsha-vardhan authored Dec 4, 2023
2 parents c560b3d + 3ce04ab commit 07dbd49
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 36 deletions.
11 changes: 8 additions & 3 deletions crates/api_models/src/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,9 @@ pub struct PaymentsRequest {
#[schema(example = "187282ab-40ef-47a9-9206-5099ba31e432")]
pub payment_token: Option<String>,

/// This is used when payment is to be confirmed and the card is not saved
#[schema(value_type = Option<String>)]
/// This is used when payment is to be confirmed and the card is not saved.
/// This field will be deprecated soon, use the CardToken object instead
#[schema(value_type = Option<String>, deprecated)]
pub card_cvc: Option<Secret<String>>,

/// The shipping address for the payment
Expand Down Expand Up @@ -720,12 +721,16 @@ pub struct Card {
pub nick_name: Option<Secret<String>>,
}

#[derive(Eq, PartialEq, Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema)]
#[derive(Eq, PartialEq, Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema, Default)]
#[serde(rename_all = "snake_case")]
pub struct CardToken {
/// The card holder's name
#[schema(value_type = String, example = "John Test")]
pub card_holder_name: Option<Secret<String>>,

/// The CVC number for the card
#[schema(value_type = Option<String>)]
pub card_cvc: Option<Secret<String>>,
}

#[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)]
Expand Down
6 changes: 0 additions & 6 deletions crates/router/src/core/payment_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ pub trait PaymentMethodRetrieve {
key_store: &domain::MerchantKeyStore,
token: &storage::PaymentTokenData,
payment_intent: &PaymentIntent,
card_cvc: Option<masking::Secret<String>>,
card_token_data: Option<&CardToken>,
) -> RouterResult<Option<(payments::PaymentMethodData, enums::PaymentMethod)>>;
}
Expand Down Expand Up @@ -126,7 +125,6 @@ impl PaymentMethodRetrieve for Oss {
merchant_key_store: &domain::MerchantKeyStore,
token_data: &storage::PaymentTokenData,
payment_intent: &PaymentIntent,
card_cvc: Option<masking::Secret<String>>,
card_token_data: Option<&CardToken>,
) -> RouterResult<Option<(payments::PaymentMethodData, enums::PaymentMethod)>> {
match token_data {
Expand All @@ -135,7 +133,6 @@ impl PaymentMethodRetrieve for Oss {
state,
&generic_token.token,
payment_intent,
card_cvc,
merchant_key_store,
card_token_data,
)
Expand All @@ -147,7 +144,6 @@ impl PaymentMethodRetrieve for Oss {
state,
&generic_token.token,
payment_intent,
card_cvc,
merchant_key_store,
card_token_data,
)
Expand All @@ -159,7 +155,6 @@ impl PaymentMethodRetrieve for Oss {
state,
&card_token.token,
payment_intent,
card_cvc,
card_token_data,
)
.await
Expand All @@ -171,7 +166,6 @@ impl PaymentMethodRetrieve for Oss {
state,
&card_token.token,
payment_intent,
card_cvc,
card_token_data,
)
.await
Expand Down
84 changes: 74 additions & 10 deletions crates/router/src/core/payment_methods/cards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,12 +225,21 @@ pub async fn add_card_to_locker(
)
.await
.map_err(|error| {
metrics::CARD_LOCKER_FAILURES.add(&metrics::CONTEXT, 1, &[]);
metrics::CARD_LOCKER_FAILURES.add(
&metrics::CONTEXT,
1,
&[
router_env::opentelemetry::KeyValue::new("locker", "basilisk"),
router_env::opentelemetry::KeyValue::new("operation", "add"),
],
);
error
})
},
&metrics::CARD_ADD_TIME,
&[],
&[router_env::opentelemetry::KeyValue::new(
"locker", "basilisk",
)],
)
.await?;
logger::debug!("card added to basilisk locker");
Expand All @@ -248,22 +257,45 @@ pub async fn add_card_to_locker(
)
.await
.map_err(|error| {
metrics::CARD_LOCKER_FAILURES.add(&metrics::CONTEXT, 1, &[]);
metrics::CARD_LOCKER_FAILURES.add(
&metrics::CONTEXT,
1,
&[
router_env::opentelemetry::KeyValue::new("locker", "rust"),
router_env::opentelemetry::KeyValue::new("operation", "add"),
],
);
error
})
},
&metrics::CARD_ADD_TIME,
&[],
&[router_env::opentelemetry::KeyValue::new("locker", "rust")],
)
.await;

match add_card_to_rs_resp {
value @ Ok(_) => {
logger::debug!("Card added successfully");
logger::debug!("card added to rust locker");
let _ = &metrics::CARD_LOCKER_SUCCESSFUL_RESPONSE.add(
&metrics::CONTEXT,
1,
&[
router_env::opentelemetry::KeyValue::new("locker", "rust"),
router_env::opentelemetry::KeyValue::new("operation", "add"),
],
);
value
}
Err(err) => {
logger::debug!(error =? err,"failed to add card");
logger::debug!(error =? err,"failed to add card to rust locker");
let _ = &metrics::CARD_LOCKER_SUCCESSFUL_RESPONSE.add(
&metrics::CONTEXT,
1,
&[
router_env::opentelemetry::KeyValue::new("locker", "basilisk"),
router_env::opentelemetry::KeyValue::new("operation", "add"),
],
);
Ok(add_card_to_hs_resp)
}
}
Expand All @@ -290,12 +322,19 @@ pub async fn get_card_from_locker(
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Failed while getting card from basilisk_hs")
.map_err(|error| {
metrics::CARD_LOCKER_FAILURES.add(&metrics::CONTEXT, 1, &[]);
metrics::CARD_LOCKER_FAILURES.add(
&metrics::CONTEXT,
1,
&[
router_env::opentelemetry::KeyValue::new("locker", "rust"),
router_env::opentelemetry::KeyValue::new("operation", "get"),
],
);
error
})
},
&metrics::CARD_GET_TIME,
&[],
&[router_env::opentelemetry::KeyValue::new("locker", "rust")],
)
.await;

Expand All @@ -313,20 +352,45 @@ pub async fn get_card_from_locker(
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Failed while getting card from basilisk_hs")
.map_err(|error| {
metrics::CARD_LOCKER_FAILURES.add(&metrics::CONTEXT, 1, &[]);
metrics::CARD_LOCKER_FAILURES.add(
&metrics::CONTEXT,
1,
&[
router_env::opentelemetry::KeyValue::new("locker", "basilisk"),
router_env::opentelemetry::KeyValue::new("operation", "get"),
],
);
error
})
},
&metrics::CARD_GET_TIME,
&[],
&[router_env::opentelemetry::KeyValue::new(
"locker", "basilisk",
)],
)
.await
.map(|inner_card| {
logger::debug!("card retrieved from basilisk locker");
let _ = &metrics::CARD_LOCKER_SUCCESSFUL_RESPONSE.add(
&metrics::CONTEXT,
1,
&[
router_env::opentelemetry::KeyValue::new("locker", "basilisk"),
router_env::opentelemetry::KeyValue::new("operation", "get"),
],
);
inner_card
}),
Ok(_) => {
logger::debug!("card retrieved from rust locker");
let _ = &metrics::CARD_LOCKER_SUCCESSFUL_RESPONSE.add(
&metrics::CONTEXT,
1,
&[
router_env::opentelemetry::KeyValue::new("locker", "rust"),
router_env::opentelemetry::KeyValue::new("operation", "get"),
],
);
get_card_from_rs_locker_resp
}
}
Expand Down
43 changes: 28 additions & 15 deletions crates/router/src/core/payments/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1354,7 +1354,6 @@ pub async fn retrieve_payment_method_with_temporary_token(
state: &AppState,
token: &str,
payment_intent: &PaymentIntent,
card_cvc: Option<masking::Secret<String>>,
merchant_key_store: &domain::MerchantKeyStore,
card_token_data: Option<&CardToken>,
) -> RouterResult<Option<(api::PaymentMethodData, enums::PaymentMethod)>> {
Expand Down Expand Up @@ -1395,10 +1394,13 @@ pub async fn retrieve_payment_method_with_temporary_token(
updated_card.card_holder_name = name_on_card;
}

if let Some(cvc) = card_cvc {
is_card_updated = true;
updated_card.card_cvc = cvc;
if let Some(token_data) = card_token_data {
if let Some(cvc) = token_data.card_cvc.clone() {
is_card_updated = true;
updated_card.card_cvc = cvc;
}
}

if is_card_updated {
let updated_pm = api::PaymentMethodData::Card(updated_card);
vault::Vault::store_payment_method_data_in_locker(
Expand Down Expand Up @@ -1444,7 +1446,6 @@ pub async fn retrieve_card_with_permanent_token(
state: &AppState,
token: &str,
payment_intent: &PaymentIntent,
card_cvc: Option<masking::Secret<String>>,
card_token_data: Option<&CardToken>,
) -> RouterResult<api::PaymentMethodData> {
let customer_id = payment_intent
Expand Down Expand Up @@ -1479,7 +1480,11 @@ pub async fn retrieve_card_with_permanent_token(
card_holder_name: name_on_card.unwrap_or(masking::Secret::from("".to_string())),
card_exp_month: card.card_exp_month,
card_exp_year: card.card_exp_year,
card_cvc: card_cvc.unwrap_or_default(),
card_cvc: card_token_data
.cloned()
.unwrap_or_default()
.card_cvc
.unwrap_or_default(),
card_issuer: card.card_brand,
nick_name: card.nick_name.map(masking::Secret::new),
card_network: None,
Expand All @@ -1501,6 +1506,22 @@ pub async fn make_pm_data<'a, F: Clone, R, Ctx: PaymentMethodRetrieve>(
Option<api::PaymentMethodData>,
)> {
let request = &payment_data.payment_method_data.clone();

let mut card_token_data = payment_data
.payment_method_data
.clone()
.and_then(|pmd| match pmd {
api_models::payments::PaymentMethodData::CardToken(token_data) => Some(token_data),
_ => None,
})
.or(Some(CardToken::default()));

if let Some(cvc) = payment_data.card_cvc.clone() {
if let Some(token_data) = card_token_data.as_mut() {
token_data.card_cvc = Some(cvc);
}
}

let token = payment_data.token.clone();

let hyperswitch_token = match payment_data.mandate_id {
Expand Down Expand Up @@ -1560,13 +1581,6 @@ pub async fn make_pm_data<'a, F: Clone, R, Ctx: PaymentMethodRetrieve>(
}
};

let card_cvc = payment_data.card_cvc.clone();

let card_token_data = request.as_ref().and_then(|pmd| match pmd {
api_models::payments::PaymentMethodData::CardToken(token_data) => Some(token_data),
_ => None,
});

// TODO: Handle case where payment method and token both are present in request properly.
let payment_method = match (request, hyperswitch_token) {
(_, Some(hyperswitch_token)) => {
Expand All @@ -1575,8 +1589,7 @@ pub async fn make_pm_data<'a, F: Clone, R, Ctx: PaymentMethodRetrieve>(
merchant_key_store,
&hyperswitch_token,
&payment_data.payment_intent,
card_cvc,
card_token_data,
card_token_data.as_ref(),
)
.await
.attach_printable("in 'make_pm_data'")?;
Expand Down
1 change: 1 addition & 0 deletions crates/router/src/routes/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ counter_metric!(CONNECTOR_HTTP_STATUS_CODE_5XX_COUNT, GLOBAL_METER);

// Service Level
counter_metric!(CARD_LOCKER_FAILURES, GLOBAL_METER);
counter_metric!(CARD_LOCKER_SUCCESSFUL_RESPONSE, GLOBAL_METER);
counter_metric!(TEMP_LOCKER_FAILURES, GLOBAL_METER);
histogram_metric!(CARD_ADD_TIME, GLOBAL_METER);
histogram_metric!(CARD_GET_TIME, GLOBAL_METER);
Expand Down
11 changes: 9 additions & 2 deletions openapi/openapi_spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -4357,6 +4357,11 @@
"type": "string",
"description": "The card holder's name",
"example": "John Test"
},
"card_cvc": {
"type": "string",
"description": "The CVC number for the card",
"nullable": true
}
}
},
Expand Down Expand Up @@ -9586,7 +9591,8 @@
},
"card_cvc": {
"type": "string",
"description": "This is used when payment is to be confirmed and the card is not saved",
"description": "This is used when payment is to be confirmed and the card is not saved.\nThis field will be deprecated soon, use the CardToken object instead",
"deprecated": true,
"nullable": true
},
"shipping": {
Expand Down Expand Up @@ -9955,7 +9961,8 @@
},
"card_cvc": {
"type": "string",
"description": "This is used when payment is to be confirmed and the card is not saved",
"description": "This is used when payment is to be confirmed and the card is not saved.\nThis field will be deprecated soon, use the CardToken object instead",
"deprecated": true,
"nullable": true
},
"shipping": {
Expand Down

0 comments on commit 07dbd49

Please sign in to comment.