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

fix(connectors): fix wallet token deserialization error #4133

Merged
merged 16 commits into from
Mar 27, 2024

Conversation

AkshayaFoiger
Copy link
Contributor

@AkshayaFoiger AkshayaFoiger commented Mar 19, 2024

Type of Change

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

Description

If deserialization fails for Google pay, Apple Pay and any other wallets token - Hyperswitch should respond with 4xx and proper error message

Test case

  1. Successful payment with Stripe Googlepay
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: {{}}' \
--data-raw '{
    "amount": 1800,
    "currency": "USD",
    "confirm": true,
    "capture_method": "automatic",
    "capture_on": "2022-09-10T10:11:12Z",
    "customer_id": "CustomerX",
    "email": "guest@example.com",
    "name": "John Doe",
    "phone": "999999999",
    "phone_country_code": "+1",
    "description": "Its my first payment request",
    "authentication_type": "no_three_ds",
    "return_url": "https://google.com",
    "payment_method": "wallet",
    "payment_method_type": "google_pay",
    "payment_method_data": {
        "wallet": {
            "google_pay": {
                "type": "CARD",
                "description": "Visa •••• 1111",
                "info": {
                    "card_network": "VISA",
                    "card_details": "1111"
                },
                "tokenization_data": {
  "type": "PAYMENT_GATEWAY",
  "token": ""
}
            }
        }
    },
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "Dubai",
            "zip": "94122",
            "country": "AE",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+97"
        }
    },
    "shipping": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "AE",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        }
    },
    "metadata": {
        "count_tickets": 1,
        "transaction_number": "5590043"
    }
}'

Response

{
    "payment_id": "pay_lWNd2YhWpjq1p9sRGvwk",
    "merchant_id": "merchant_1710919554",
    "status": "succeeded",
    "amount": 1800,
    "net_amount": 1800,
    "amount_capturable": 0,
    "amount_received": 1800,
    "connector": "stripe",
    "client_secret": "pay_lWNd2YhWpjq1p9sRGvwk_secret_Woiaeqo8Yr7ki2p0Abcz",
    "created": "2024-03-20T07:26:10.414Z",
    "currency": "USD",
    "customer_id": "CustomerX",
    "description": "Its my first payment request",
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": "automatic",
    "payment_method": "wallet",
    "payment_method_data": {
        "wallet": null,
        "billing": null
    },
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "San Fransico",
            "country": "AE",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": null
    },
    "billing": {
        "address": {
            "city": "San Fransico",
            "country": "AE",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "Dubai",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+97"
        },
        "email": null
    },
    "order_details": null,
    "email": "guest@example.com",
    "name": "John Doe",
    "phone": "999999999",
    "return_url": "https://google.com/",
    "authentication_type": "no_three_ds",
    "statement_descriptor_name": null,
    "statement_descriptor_suffix": null,
    "next_action": null,
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "google_pay",
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": {
        "customer_id": "CustomerX",
        "created_at": 1710919570,
        "expires": 1710923170,
        "secret": "epk_04ddeab624494488a68423727b63f2da"
    },
    "manual_retry_allowed": false,
    "connector_transaction_id": "pi_3OwJXLD5R7gDAGff1JIpNEtV",
    "frm_message": null,
    "metadata": {
        "count_tickets": 1,
        "transaction_number": "5590043"
    },
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": "pi_3OwJXLD5R7gDAGff1JIpNEtV",
    "payment_link": null,
    "profile_id": "pro_t0UBJ257xhFGAqJMu1xY",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_K91ZLTQVjEJByKfnr181",
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2024-03-20T07:41:10.414Z",
    "fingerprint": null,
    "payment_method_id": null,
    "payment_method_status": null
}

2.Create a failed stripe Googlepay payment - with wrong token struct

curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_KeNXoIYIx3E27uTqTCEbrXimCM4LR0FY9PrcPSSksjaLJdz1JW4prgKXSpIAWRiH' \
--data-raw '{
    "amount": 1800,
    "currency": "USD",
    "confirm": true,
    "capture_method": "automatic",
    "capture_on": "2022-09-10T10:11:12Z",
    "customer_id": "CustomerX",
    "email": "guest@example.com",
    "name": "John Doe",
    "phone": "999999999",
    "phone_country_code": "+1",
    "description": "Its my first payment request",
    "authentication_type": "no_three_ds",
    "return_url": "https://google.com",
    "payment_method": "wallet",
    "payment_method_type": "google_pay",
    "payment_method_data": {
        "wallet": {
            "google_pay": {
                "type": "CARD",
                "description": "Visa •••• 1111",
                "info": {
                    "card_network": "VISA",
                    "card_details": "1111"
                },
                "tokenization_data": {
                    "type": "PAYMENT_GATEWAY",
                    "token": "{\"signature\":\"MEQCIG2DFfixQYapmK983wSKYrYTLuGsBLKYTohGOuLrWoQCAiB6pRV06ZO29tJEElRQYh0coPnvMg6spPtimueQj7R29A\\u003d\\u003d\",\"protocolVersion\":\"ECv1\",\"signedMessage\":\"{\\\"encryptedMessage\\\":\\\"rO3cpLYvBLkWRHrmI0uWKOQFtekbQS4hiyKKIT5APpahmxUefzJE4URH+8liNh3+tvwthzgnnIEPwDxZfEmgoQktZ7XUe59SBcOS2CqW5jmOU1L6TGPBmGvp1cZ0SiRt8u9ovq8GE1oU6RaINUgSZJTwHwEuf+pTMIIfQmUnyr8l6TH9RCrycodx1bMmA4VfXrbc654/7gTW0/BrURAxozcD2Snu5BQYDdQ5rXe++sN0eMX9pWiW9z3Ovve3Ap6xsct2FkD9FLTF9htj6cH1GgeSn2ozWXsGgyvSt4ZtWsHy1mMSbvWj3LtUc+tyEqun6rVCYg9kozsqFQykp8O0gCDk9oiiHgbtzeUvsPOzEKpl3Fx8uiiEHubBsCviq3OCHE/moNBZWNc7me01yObbpD2sjB3XGgL0tmsVKvpJ5ndau2+pholnYJwCsAAaDQFr4bjbusxy3oRCsCzC\\\",\\\"ephemeralPublicKey\\\":\\\"BP7RtCzgPLGZZRpsSx9X/bsA/rF8Lotv+D25D0oZwVdKa/+UFfoITGQDYRG06MNErXyD0oLnMYvjcxUHPJTDS48\\\\u003d\\\",\\\"tag\\\":\\\"g9AMeqEERJRmEAorxIyNYK5VVDsfLXc/9w1usBiJ0YU\\\\u003d\\\"}\"}"
                }
            }
        }
    },
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "Dubai",
            "zip": "94122",
            "country": "AE",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+97"
        }
    },
    "shipping": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "AE",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        }
    },
    "metadata": {
        "count_tickets": 1,
        "transaction_number": "5590043"
    }
}'

Response

{
    "error": {
        "type": "invalid_request",
        "message": "Invalid Googlepay wallet token",
        "code": "IR_20"
    }
}
Screenshot 2024-03-20 at 1 02 17 PM
  1. Zen Applepay and Googlepay

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
  • I added a CHANGELOG entry if applicable

@AkshayaFoiger AkshayaFoiger requested review from a team as code owners March 19, 2024 12:28
@AkshayaFoiger AkshayaFoiger self-assigned this Mar 19, 2024
@AkshayaFoiger AkshayaFoiger added A-connector-integration Area: Connector integration A-errors Area: error messages, structure & logging labels Mar 19, 2024
@AkshayaFoiger AkshayaFoiger changed the title refactor(connectors): fix wallet token 5xx error refactor(connectors): fix wallet token deserialization error Mar 19, 2024
@AkshayaFoiger AkshayaFoiger changed the title refactor(connectors): fix wallet token deserialization error fix(connectors): fix wallet token deserialization error Mar 20, 2024
@@ -708,7 +708,9 @@ impl TryFrom<&BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>>
Self::try_from((item, decrypt_data, apple_pay_data))
}
types::PaymentMethodToken::Token(_) => {
Err(errors::ConnectorError::InvalidWalletToken)?
Err(errors::ConnectorError::InvalidWalletToken {
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be payment method not implemented rather than InvalidWalletToken

@@ -1335,7 +1335,9 @@ impl
payment_method_id: match item.router_data.get_payment_method_token()? {
types::PaymentMethodToken::Token(token) => token.into(),
types::PaymentMethodToken::ApplePayDecrypt(_) => {
Err(errors::ConnectorError::InvalidWalletToken)?
Err(errors::ConnectorError::InvalidWalletToken {
Copy link
Contributor

Choose a reason for hiding this comment

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

Throw not implemented error

@@ -1417,7 +1419,9 @@ fn get_braintree_redirect_form(
card_token: match payment_method_token {
types::PaymentMethodToken::Token(token) => token,
types::PaymentMethodToken::ApplePayDecrypt(_) => {
Err(errors::ConnectorError::InvalidWalletToken)?
Err(errors::ConnectorError::InvalidWalletToken {
Copy link
Contributor

Choose a reason for hiding this comment

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

same here

@@ -308,7 +308,9 @@ impl TryFrom<&CheckoutRouterData<&types::PaymentsAuthorizeRouterData>> for Payme
token: match item.router_data.get_payment_method_token()? {
types::PaymentMethodToken::Token(token) => token.into(),
types::PaymentMethodToken::ApplePayDecrypt(_) => {
Err(errors::ConnectorError::InvalidWalletToken)?
Err(errors::ConnectorError::InvalidWalletToken {
Copy link
Contributor

Choose a reason for hiding this comment

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

throw not implemented error

@@ -140,7 +140,9 @@ impl TryFrom<&types::SetupMandateRouterData> for CybersourceZeroMandateRequest {
)
}
types::PaymentMethodToken::Token(_) => {
Err(errors::ConnectorError::InvalidWalletToken)?
Err(errors::ConnectorError::InvalidWalletToken {
Copy link
Contributor

Choose a reason for hiding this comment

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

throw not implemented error

@@ -921,7 +921,9 @@ impl WalletData for api::WalletData {
{
serde_json::from_str::<T>(self.get_wallet_token()?.peek())
.into_report()
.change_context(errors::ConnectorError::InvalidWalletToken)
.change_context(errors::ConnectorError::InvalidWalletToken {
wallet_name: "".to_string(),
Copy link
Contributor

Choose a reason for hiding this comment

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

Please add wallet name

let encoded_token = consts::BASE64_ENGINE.encode(token_as_vec);
Ok(encoded_token)
}
_ => Err(errors::ConnectorError::InvalidWalletToken.into()),
_ => Err(errors::ConnectorError::InvalidWalletToken {
wallet_name: "".to_string(),
Copy link
Contributor

Choose a reason for hiding this comment

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

add not implemented

)
.into_report()
.change_context(errors::ConnectorError::InvalidWalletToken)?,
.change_context(errors::ConnectorError::InvalidWalletToken {
wallet_name: "".to_string(),
Copy link
Contributor

Choose a reason for hiding this comment

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

please add wallet name

@@ -79,6 +79,11 @@ pub enum ApiErrorResponse {
message = "Access forbidden, invalid JWT token was used"
)]
InvalidJwtToken,
#[error(
error_type = ErrorType::ProcessingError, code = "IR_17",
Copy link
Contributor

Choose a reason for hiding this comment

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

Use new code

@@ -95,7 +100,7 @@ impl ErrorSwitch<api_models::errors::types::ApiErrorResponse> for ApiErrorRespon
Self::FileProviderNotSupported { message } => {
AER::BadRequest(ApiError::new("IR", 23, message.to_string(), None))
},
Self::UnprocessableEntity {message} => AER::Unprocessable(ApiError::new("IR", 23, message.to_string(), None)),
Self::UnprocessableEntity {message} => AER::Unprocessable(ApiError::new("IR", 24, message.to_string(), None)),
Copy link
Contributor

Choose a reason for hiding this comment

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

this is not required

}
types::PaymentMethodToken::ApplePayDecrypt(_) => Err(unimplemented_payment_method!(
"Apple Pay",
"Decrypt",
Copy link
Contributor

Choose a reason for hiding this comment

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

Use Simplified instead of Decrypt

ArjunKarthik
ArjunKarthik previously approved these changes Mar 26, 2024
ArjunKarthik
ArjunKarthik previously approved these changes Mar 26, 2024
@@ -384,7 +384,7 @@ impl<T> ConnectorErrorExt<T> for error_stack::Result<T, errors::ConnectorError>
| errors::ConnectorError::DateFormattingFailed
| errors::ConnectorError::InvalidDataFormat { .. }
| errors::ConnectorError::MismatchedPaymentData
| errors::ConnectorError::InvalidWalletToken
| errors::ConnectorError::InvalidWalletToken { .. }
Copy link
Contributor

Choose a reason for hiding this comment

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

Even here ConnectorError::InvalidWalletToken should be mapped to ApiErrorResponse::InvalidWalletToken

@Gnanasundari24 Gnanasundari24 added this pull request to the merge queue Mar 27, 2024
Merged via the queue into main with commit 929848f Mar 27, 2024
13 of 15 checks passed
@Gnanasundari24 Gnanasundari24 deleted the fix-wallet-5xx-error branch March 27, 2024 06:32
pixincreate added a commit that referenced this pull request Apr 1, 2024
* 'main' of github.com:juspay/hyperswitch:
  refactor(core): removed the processing status for payment_method_status (#4213)
  docs(README): remove link to outdated early access form
  build(deps): bump `error-stack` from version `0.3.1` to `0.4.1` (#4188)
  chore(version): 2024.04.01.0
  feat(mandates): allow off-session payments using `payment_method_id` (#4132)
  ci(CI-pr): determine modified crates more deterministically (#4233)
  chore(config): add billwerk base URL in deployment configs (#4243)
  feat(payment_method): API to list countries and currencies supported by a country and payment method type (#4126)
  chore(version): 2024.03.28.0
  refactor(config): allow wildcard origin for development and Docker Compose setups (#4231)
  fix(core): Amount capturable remain same for `processing` status in capture (#4229)
  fix(euclid_wasm): checkout wasm metadata issue (#4198)
  fix(trustpay): [Trustpay] Add error code mapping '800.100.100'  (#4224)
  feat(connector): [billwerk] add connector template code (#4123)
  fix(connectors): fix wallet token deserialization error  (#4133)
  fix(log): adding span metadata to `tokio` spawned futures (#4118)
  chore(version): 2024.03.27.0
  fix(connector): [CRYPTOPAY] Skip metadata serialization if none (#4205)
  fix(connector): [Trustpay] fix deserialization error for incoming webhook response for trustpay and add error code mapping '800.100.203' (#4199)
  fix(core): make eci in AuthenticationData optional (#4187)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-connector-integration Area: Connector integration A-errors Area: error messages, structure & logging
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants