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(core): add columns unified error code and error message in refund table #6933

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

cookieg13
Copy link
Contributor

@cookieg13 cookieg13 commented Dec 24, 2024

Type of Change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring
  • Dependency updates
  • Documentation
  • CI/CD

Description

  1. unified_code and unified_message columns already exists for payment_attempt table, this PR adds unified_code and unified_message in refund table. During RefundUpdate::ErrorUpdate unified_code and unified_message is saved in DB, and in /refunds response and /retrieve response unified message is shown according to the locale passed in headers.

  2. This PR introduces locale in SessionState

  3. This PR introduces refund_flow
    (Flow identifier used for performing GSM operations)

Additional Changes

  • This PR modifies the API contract
  • This PR modifies the database schema
  • This PR modifies application configuration/environment variables

Motivation and Context

How did you test it?

We can test this flow by manually trigger a failure for refunds.

Steps:

  1. Make a card payment for 1000 MYR, and capture.
  2. Update DB to alter the captured amount to a greater amount say 3000 MYR.
  3. Make refunds call with 3000 MYR, connector will throw error since the real captured amount is lesser than this new amount.

1) Make card payment via Fiuu

cURL

curl --location --request POST 'http://localhost:8080/payments' \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --header 'api-key: dev_k6hN6WS14LcwHh4Q7bKCcTDRBwPRUnfQpraO5c7dW6oWiAFOmK8pdWfHlmg6adrt' \ --data-raw '{ "amount":1000, "currency": "MYR", "confirm": true, "payment_link" : false, "capture_method": "automatic", "capture_on": "2022-09-10T10:11:12Z", "amount_to_capture": 1000, "customer_id": "exampel3rewfdsvc2", "phone": "999999999", "phone_country_code": "+1", "description": "Its my first payment request", "authentication_type": "three_ds", "return_url": "https://google.com", "payment_method": "card", "payment_method_type": "credit", "payment_method_data": { "card": { "card_number": "5105105105105100", "card_exp_month": "12", "card_exp_year": "2030", "card_holder_name": "Max Mustermann", "card_cvc": "444" } }, "browser_info": { "user_agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/70.0.3538.110 Safari\/537.36", "accept_header": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/webp,image\/apng,\/;q=0.8", "language": "nl-NL", "color_depth": 24, "ip_address": "103.77.139.95", "screen_height": 723, "screen_width": 1536, "time_zone": 0, "java_enabled": true, "java_script_enabled": true }, "statement_descriptor_name": "joseph", "statement_descriptor_suffix": "JS", "metadata": { "udf1": "value1", "new_customer": "true", "login_date": "2019-09-10T10:11:12Z" } }'

Response
Screenshot 2024-12-24 at 16 54 21

2)Update DB with following commands to make captured amount greater than the real captured amount

UPDATE payment_intent
SET amount = 3000
WHERE payment_id='pay_FBXuXJ8A2WdhcwYueQCY';
UPDATE payment_intent
SET amount_captured = 3000
WHERE payment_id='pay_FBXuXJ8A2WdhcwYueQCY';

UPDATE payment_attempt
SET amount = 3000
WHERE payment_id='pay_FBXuXJ8A2WdhcwYueQCY';
UPDATE payment_attempt
SET amount_to_capture = 3000
WHERE payment_id='pay_FBXuXJ8A2WdhcwYueQCY';

3)Update gateway_status_map and unified_translations table

INSERT INTO unified_translations (unified_code, unified_message, locale, translation)
VALUES ('UE_1000', 'Issue with payment method details', 'zh-Hant', '支付方式資訊有問題');

INSERT INTO unified_translations (unified_code, unified_message, locale, translation)
VALUES ('UE_2000', 'Issue with Configurations', 'zh-Hant', '配置有問題');

INSERT INTO unified_translations (unified_code, unified_message, locale, translation)
VALUES ('UE_3000', 'Technical issue with PSP', 'zh-Hant', '支付服務提供商 (PSP) 出現技術問題');

INSERT INTO unified_translations (unified_code, unified_message, locale, translation)
VALUES ('UE_4000', 'Issue in the integration', 'zh-Hant', '整合過程中出現問題');

INSERT INTO unified_translations (unified_code, unified_message, locale, translation)
VALUES ('UE_9000', 'Something went wrong', 'zh-Hant', '授權被拒絕');

INSERT INTO
    gateway_status_map (
        connector,
        flow,
        sub_flow,
        code,
        message,
        status,
        decision,
        step_up_possible,
        unified_code,
        unified_message
    )
VALUES (
        'fiuu',
        'refund_flow',
        'sub_flow',
        'PR011',
        'Exceed refund amount for this transaction.',
        'Failure',
        'do_default',
        false,
        'UE_1000',
        'Issue with payment method details'
    );

4)a) Make refunds call with locale "zh-Hant"

cURL

curl --location --request POST 'http://localhost:8080/refunds' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_k6hN6WS14LcwHh4Q7bKCcTDRBwPRUnfQpraO5c7dW6oWiAFOmK8pdWfHlmg6adrt' \
--data-raw '{
    "payment_id": "pay_FBXuXJ8A2WdhcwYueQCY",
    "amount": 3000,
    "reason": "Customer returned product",
    "refund_type": "instant",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    }
}'

Response
Screenshot 2024-12-24 at 16 55 49

Output: We get translated unified message

4)b)Make refunds call with no locale
cURL

curl --location --request POST 'http://localhost:8080/refunds' \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --header 'api-key: dev_k6hN6WS14LcwHh4Q7bKCcTDRBwPRUnfQpraO5c7dW6oWiAFOmK8pdWfHlmg6adrt' \ --data-raw '{ "payment_id": "pay_FBXuXJ8A2WdhcwYueQCY", "amount": 3000, "reason": "Customer returned product", "refund_type": "instant", "metadata": { "udf1": "value1", "new_customer": "true", "login_date": "2019-09-10T10:11:12Z" } }'

Response
Screenshot 2024-12-24 at 16 56 28

Output: We get unified message in english

5)Make refunds retrieve call
cURL

curl --location --request GET 'http://localhost:8080/refunds/ref_rbIPXQW2jgCxEGEu56U7' \ --header 'Accept: application/json' \ --header 'Accept-Language: zh-Hant' \ --header 'api-key: dev_6ix25ZzUaYWPasgWCdTkb8PVZCJEe1X6ABALYbHQxPJT9xOAREiuxXlOAuYdlYAb' \ --header 'Content-Type: text/plain' \ --data-raw '{ "name": "", "description": null, "expiration": "2023-09-23T01:02:03.000Z" }'

Response
Uploading Screenshot 2024-12-27 at 16.31.20.png…

Output: We get unified message in locale

Checklist

  • I formatted the code cargo +nightly fmt --all
  • I addressed lints thrown by cargo clippy
  • I reviewed the submitted code
  • I added unit tests for my changes where possible

@cookieg13 cookieg13 self-assigned this Dec 24, 2024
@cookieg13 cookieg13 requested review from a team as code owners December 24, 2024 11:07
Copy link

semanticdiff-com bot commented Dec 24, 2024

Review changes with  SemanticDiff

Changed Files
File Status
  crates/router/src/services/api.rs  86% smaller
  crates/router/src/routes/payout_link.rs  49% smaller
  crates/router/src/core/payment_link.rs  43% smaller
  crates/router/src/routes/payouts.rs  36% smaller
  crates/router/src/core/refunds.rs  20% smaller
  crates/router/src/bin/scheduler.rs  17% smaller
  crates/router/src/utils.rs  2% smaller
  api-reference/openapi_spec.json  0% smaller
  crates/api_models/src/refunds.rs  0% smaller
  crates/diesel_models/src/refund.rs  0% smaller
  crates/diesel_models/src/schema.rs  0% smaller
  crates/diesel_models/src/schema_v2.rs  0% smaller
  crates/hyperswitch_connectors/src/connectors/airwallex/transformers.rs  0% smaller
  crates/router/src/consts.rs  0% smaller
  crates/router/src/core/payout_link.rs  0% smaller
  crates/router/src/core/payouts.rs  0% smaller
  crates/router/src/db/events.rs  0% smaller
  crates/router/src/db/merchant_connector_account.rs  0% smaller
  crates/router/src/db/merchant_key_store.rs  0% smaller
  crates/router/src/db/refund.rs  0% smaller
  crates/router/src/routes/app.rs  0% smaller
  crates/router/tests/cache.rs  0% smaller
  crates/router/tests/connectors/aci.rs  0% smaller
  crates/router/tests/connectors/utils.rs  0% smaller
  crates/router/tests/payments.rs  0% smaller
  crates/router/tests/payments2.rs  0% smaller
  crates/router/tests/services.rs  0% smaller
  migrations/2024-12-24-115958_add-unified-code-and-message-in-refunds/down.sql Unsupported file format
  migrations/2024-12-24-115958_add-unified-code-and-message-in-refunds/up.sql Unsupported file format

@hyperswitch-bot hyperswitch-bot bot added the M-database-changes Metadata: This PR involves database schema changes label Dec 24, 2024
@cookieg13 cookieg13 changed the title add unified error code and error message for refund table feat(core): add unified error code and error message for refund table Dec 24, 2024
@cookieg13 cookieg13 changed the title feat(core): add unified error code and error message for refund table feat(core): add unified error code and error message in refund table Dec 24, 2024
@cookieg13 cookieg13 changed the title feat(core): add unified error code and error message in refund table feat(core): add columns unified error code and error message in refund table Dec 24, 2024
@hyperswitch-bot hyperswitch-bot bot added the M-api-contract-changes Metadata: This PR involves API contract changes label Dec 24, 2024
crates/api_models/src/refunds.rs Outdated Show resolved Hide resolved
crates/diesel_models/src/schema_v2.rs Outdated Show resolved Hide resolved
crates/router/src/core/payments/helpers.rs Outdated Show resolved Hide resolved
crates/router/src/core/payments/helpers.rs Outdated Show resolved Hide resolved
crates/common_utils/src/consts.rs Outdated Show resolved Hide resolved
crates/router/src/core/payouts/helpers.rs Outdated Show resolved Hide resolved
crates/router/src/services/api.rs Outdated Show resolved Hide resolved
crates/router/src/services/api/client.rs Outdated Show resolved Hide resolved
crates/router/src/routes/app.rs Outdated Show resolved Hide resolved
@hyperswitch-bot hyperswitch-bot bot added M-api-contract-changes Metadata: This PR involves API contract changes and removed M-api-contract-changes Metadata: This PR involves API contract changes labels Dec 26, 2024
@cookieg13 cookieg13 requested a review from a team as a code owner December 26, 2024 10:39
@hyperswitch-bot hyperswitch-bot bot added M-api-contract-changes Metadata: This PR involves API contract changes and removed M-api-contract-changes Metadata: This PR involves API contract changes labels Dec 26, 2024
Copy link
Contributor

@kashif-m kashif-m left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs one change for storing the unified message in refunds table.

crates/router/src/core/refunds.rs Outdated Show resolved Hide resolved
crates/router/src/utils.rs Outdated Show resolved Hide resolved
@@ -484,6 +493,7 @@ impl AppState {
opensearch_client: Arc::clone(&self.opensearch_client),
grpc_client: Arc::clone(&self.grpc_client),
theme_storage_client: self.theme_storage_client.clone(),
request_headers: None,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may be able to pass HeaderMap to get_session_state() itself and have the field populated here. Then we need not have it as an Option either.

@jarnura What do you think, should the business logic have access to request headers (they can be accessed from SessionState), or should the request header information not leak to the business logic at all, but only be handled in the route handler layer?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, we can handle in get_session_state(), AppState won't related to a session any more since its a global application state and header is session specific one. So lets not leak that information in AppState

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added locale in SessionState
@SanchithHegde @jarnura

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cookieg13 cookieg13 force-pushed the addUnifiedCodeMsg branch 2 times, most recently from fdb39d3 to 77d5295 Compare December 27, 2024 11:05
@@ -147,12 +147,6 @@ pub struct Browser {
user_agent: String,
}

#[derive(Debug, Serialize)]
Copy link
Contributor Author

@cookieg13 cookieg13 Dec 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screenshot 2024-12-27 at 12 12 45

Location is not used anywhere, so removing it

@cookieg13 cookieg13 requested a review from kashif-m December 27, 2024 11:09
crates/router/src/routes/payouts.rs Outdated Show resolved Hide resolved
crates/router/src/routes/app.rs Outdated Show resolved Hide resolved
let (payment_link, payment_link_details, payment_link_config) = form_payment_link_data(
&state,
merchant_account,
key_store,
merchant_id,
payment_id,
locale,
Some(state.clone().locale),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need not pass locale here since form_payment_link_data() already accepts SessionState, the function can be updated to access state.locale as needed.

@@ -396,17 +393,15 @@ pub async fn initiate_payment_link_flow(
key_store: domain::MerchantKeyStore,
merchant_id: common_utils::id_type::MerchantId,
payment_id: common_utils::id_type::PaymentId,
request_headers: &header::HeaderMap,
_request_headers: &header::HeaderMap,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove the unused request_headers argument here and in get_payment_link_status() (both v1 and v2 features).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
M-api-contract-changes Metadata: This PR involves API contract changes M-database-changes Metadata: This PR involves database schema changes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants