Skip to content

Commit

Permalink
refactor(payments): add support for receiving card_holder_name field …
Browse files Browse the repository at this point in the history
…as an empty string (#3127)
  • Loading branch information
Chethan-rao authored Dec 13, 2023
1 parent be13d15 commit 4d19d8b
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 91 deletions.
58 changes: 13 additions & 45 deletions crates/router/src/core/payments/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -946,42 +946,6 @@ pub fn verify_mandate_details(
)
}

// This function validates card_holder_name field to be either null or a non-empty string
pub fn validate_card_holder_name(
payment_method_data: Option<api::PaymentMethodData>,
) -> CustomResult<(), errors::ApiErrorResponse> {
if let Some(pmd) = payment_method_data {
match pmd {
// This validation would occur during payments create
api::PaymentMethodData::Card(card) => {
if let Some(name) = &card.card_holder_name {
if name.clone().expose().is_empty() {
return Err(errors::ApiErrorResponse::InvalidRequestData {
message: "card_holder_name cannot be empty".to_string(),
})
.into_report();
}
}
}

// This validation would occur during payments confirm
api::PaymentMethodData::CardToken(card) => {
if let Some(name) = card.card_holder_name {
if name.expose().is_empty() {
return Err(errors::ApiErrorResponse::InvalidRequestData {
message: "card_holder_name cannot be empty".to_string(),
})
.into_report();
}
}
}
_ => (),
}
}

Ok(())
}

#[instrument(skip_all)]
pub fn payment_attempt_status_fsm(
payment_method_data: &Option<api::PaymentMethodData>,
Expand Down Expand Up @@ -1441,13 +1405,15 @@ pub async fn retrieve_payment_method_with_temporary_token(
let mut is_card_updated = false;

// The card_holder_name from locker retrieved card is considered if it is a non-empty string or else card_holder_name is picked
// from payment_method.card_token object
// from payment_method_data.card_token object
let name_on_card = if let Some(name) = card.card_holder_name.clone() {
if name.expose().is_empty() {
card_token_data.and_then(|token_data| {
is_card_updated = true;
token_data.card_holder_name.clone()
})
if name.clone().expose().is_empty() {
card_token_data
.and_then(|token_data| {
is_card_updated = true;
token_data.card_holder_name.clone()
})
.or(Some(name))
} else {
card.card_holder_name.clone()
}
Expand Down Expand Up @@ -1528,10 +1494,12 @@ pub async fn retrieve_card_with_permanent_token(
.attach_printable("failed to fetch card information from the permanent locker")?;

// The card_holder_name from locker retrieved card is considered if it is a non-empty string or else card_holder_name is picked
// from payment_method.card_token object
// from payment_method_data.card_token object
let name_on_card = if let Some(name) = card.name_on_card.clone() {
if name.expose().is_empty() {
card_token_data.and_then(|token_data| token_data.card_holder_name.clone())
if name.clone().expose().is_empty() {
card_token_data
.and_then(|token_data| token_data.card_holder_name.clone())
.or(Some(name))
} else {
card.name_on_card
}
Expand Down
2 changes: 0 additions & 2 deletions crates/router/src/core/payments/operations/payment_confirm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -872,8 +872,6 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve> ValidateRequest<F, api::Paymen

helpers::validate_payment_method_fields_present(request)?;

helpers::validate_card_holder_name(request.payment_method_data.clone())?;

let mandate_type =
helpers::validate_mandate(request, payments::is_operation_confirm(self))?;

Expand Down
2 changes: 0 additions & 2 deletions crates/router/src/core/payments/operations/payment_create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,8 +561,6 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve> ValidateRequest<F, api::Paymen
helpers::validate_amount_to_capture_and_capture_method(None, request)?;
helpers::validate_card_data(request.payment_method_data.clone())?;

helpers::validate_card_holder_name(request.payment_method_data.clone())?;

helpers::validate_payment_method_fields_present(request)?;

let mandate_type =
Expand Down
2 changes: 0 additions & 2 deletions crates/router/src/core/payments/operations/payment_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -656,8 +656,6 @@ impl<F: Send + Clone, Ctx: PaymentMethodRetrieve> ValidateRequest<F, api::Paymen

helpers::validate_payment_method_fields_present(request)?;

helpers::validate_card_holder_name(request.payment_method_data.clone())?;

let mandate_type = helpers::validate_mandate(request, false)?;

Ok((
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Validate status 4xx
pm.test("[POST]::/payments - Status code is 4xx", function () {
pm.response.to.be.error;
// Validate status 2xx
pm.test("[POST]::/payments - Status code is 2xx", function () {
pm.response.to.be.success;
});

// Validate if response header has matching content-type
Expand Down Expand Up @@ -63,20 +63,12 @@ if (jsonData?.client_secret) {
);
}

// Response body should have "error"
pm.test(
"[POST]::/payments/:id/confirm - Content check if 'error' exists",
function () {
pm.expect(typeof jsonData.error !== "undefined").to.be.true;
},
);

// Response body should have value "connector error" for "error type"
if (jsonData?.error?.type) {
// Response body should have value "succeeded" for "status"
if (jsonData?.status) {
pm.test(
"[POST]::/payments/:id/confirm - Content check if value for 'error.type' matches 'invalid_request'",
"[POST]::/payments/:id/confirm - Content check if value for 'status' matches 'succeeded'",
function () {
pm.expect(jsonData.error.type).to.eql("invalid_request");
pm.expect(jsonData.status).to.eql("succeeded");
},
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@ if (jsonData?.client_secret) {
);
}

// Response body should have value "requires_payment_method" for "status"
// Response body should have value "succeeded" for "status"
if (jsonData?.status) {
pm.test(
"[POST]::/payments:id - Content check if value for 'status' matches 'requires_payment_method'",
"[POST]::/payments:id - Content check if value for 'status' matches 'succeeded'",
function () {
pm.expect(jsonData.status).to.eql("requires_payment_method");
pm.expect(jsonData.status).to.eql("succeeded");
},
);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Validate status 4xx
pm.test("[POST]::/payments - Status code is 4xx", function () {
pm.response.to.be.error;
// Validate status 2xx
pm.test("[POST]::/payments - Status code is 2xx", function () {
pm.response.to.be.success;
});

// Validate if response header has matching content-type
Expand Down Expand Up @@ -63,20 +63,12 @@ if (jsonData?.client_secret) {
);
}

// Response body should have "error"
pm.test(
"[POST]::/payments/:id/confirm - Content check if 'error' exists",
function () {
pm.expect(typeof jsonData.error !== "undefined").to.be.true;
},
);

// Response body should have value "connector error" for "error type"
if (jsonData?.error?.type) {
// Response body should have value "succeeded" for "status"
if (jsonData?.status) {
pm.test(
"[POST]::/payments/:id/confirm - Content check if value for 'error.type' matches 'invalid_request'",
"[POST]::/payments/:id/confirm - Content check if value for 'status' matches 'succeeded'",
function () {
pm.expect(jsonData.error.type).to.eql("invalid_request");
pm.expect(jsonData.status).to.eql("succeeded");
},
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@ if (jsonData?.client_secret) {
);
}

// Response body should have value "requires_payment_method" for "status"
// Response body should have value "succeeded" for "status"
if (jsonData?.status) {
pm.test(
"[POST]::/payments:id - Content check if value for 'status' matches 'requires_payment_method'",
"[POST]::/payments:id - Content check if value for 'status' matches 'succeeded'",
function () {
pm.expect(jsonData.status).to.eql("requires_payment_method");
pm.expect(jsonData.status).to.eql("succeeded");
},
);
}
}

0 comments on commit 4d19d8b

Please sign in to comment.