From 8320dc07fe1b8b1c9427f70dcb9d952eef01a63b Mon Sep 17 00:00:00 2001 From: Kashif Date: Thu, 19 Sep 2024 18:54:56 +0530 Subject: [PATCH] feat(payments): store and propagate additional wallet pm details in payments response (#5869) Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com> --- api-reference-v2/openapi_spec.json | 65 ++++++++++++++++++- api-reference/openapi_spec.json | 65 ++++++++++++++++++- crates/api_models/src/payments.rs | 48 +++++++++++++- .../src/payments/additional_info.rs | 12 +++- crates/openapi/src/openapi.rs | 3 + crates/openapi/src/openapi_v2.rs | 3 + crates/router/src/core/payments/helpers.rs | 16 ++++- 7 files changed, 205 insertions(+), 7 deletions(-) diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json index 04c72b1e8a..558a319828 100644 --- a/api-reference-v2/openapi_spec.json +++ b/api-reference-v2/openapi_spec.json @@ -11912,7 +11912,7 @@ ], "properties": { "wallet": { - "type": "object" + "$ref": "#/components/schemas/WalletResponse" } } }, @@ -19124,6 +19124,28 @@ } ] }, + "WalletAdditionalDataForCard": { + "type": "object", + "required": [ + "last4", + "card_network", + "type" + ], + "properties": { + "last4": { + "type": "string", + "description": "Last 4 digits of the card number" + }, + "card_network": { + "type": "string", + "description": "The information of the payment method" + }, + "type": { + "type": "string", + "description": "The type of payment method" + } + } + }, "WalletData": { "oneOf": [ { @@ -19428,6 +19450,47 @@ } ] }, + "WalletResponse": { + "allOf": [ + { + "allOf": [ + { + "$ref": "#/components/schemas/WalletResponseData" + } + ], + "nullable": true + }, + { + "type": "object" + } + ] + }, + "WalletResponseData": { + "oneOf": [ + { + "type": "object", + "required": [ + "apple_pay" + ], + "properties": { + "apple_pay": { + "$ref": "#/components/schemas/WalletAdditionalDataForCard" + } + } + }, + { + "type": "object", + "required": [ + "google_pay" + ], + "properties": { + "google_pay": { + "$ref": "#/components/schemas/WalletAdditionalDataForCard" + } + } + } + ] + }, "WeChatPay": { "type": "object" }, diff --git a/api-reference/openapi_spec.json b/api-reference/openapi_spec.json index 7ef33c1c94..8214d3a10b 100644 --- a/api-reference/openapi_spec.json +++ b/api-reference/openapi_spec.json @@ -15726,7 +15726,7 @@ ], "properties": { "wallet": { - "type": "object" + "$ref": "#/components/schemas/WalletResponse" } } }, @@ -23465,6 +23465,28 @@ } ] }, + "WalletAdditionalDataForCard": { + "type": "object", + "required": [ + "last4", + "card_network", + "type" + ], + "properties": { + "last4": { + "type": "string", + "description": "Last 4 digits of the card number" + }, + "card_network": { + "type": "string", + "description": "The information of the payment method" + }, + "type": { + "type": "string", + "description": "The type of payment method" + } + } + }, "WalletData": { "oneOf": [ { @@ -23769,6 +23791,47 @@ } ] }, + "WalletResponse": { + "allOf": [ + { + "allOf": [ + { + "$ref": "#/components/schemas/WalletResponseData" + } + ], + "nullable": true + }, + { + "type": "object" + } + ] + }, + "WalletResponseData": { + "oneOf": [ + { + "type": "object", + "required": [ + "apple_pay" + ], + "properties": { + "apple_pay": { + "$ref": "#/components/schemas/WalletAdditionalDataForCard" + } + } + }, + { + "type": "object", + "required": [ + "google_pay" + ], + "properties": { + "google_pay": { + "$ref": "#/components/schemas/WalletAdditionalDataForCard" + } + } + } + ] + }, "WeChatPay": { "type": "object" }, diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index 20f1205e14..715bf3c354 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -2046,6 +2046,7 @@ pub enum AdditionalPaymentData { }, Wallet { apple_pay: Option, + google_pay: Option, }, PayLater { klarna_sdk: Option, @@ -3069,7 +3070,7 @@ where | PaymentMethodDataResponse::PayLater(_) | PaymentMethodDataResponse::RealTimePayment(_) | PaymentMethodDataResponse::Upi(_) - | PaymentMethodDataResponse::Wallet {} + | PaymentMethodDataResponse::Wallet(_) | PaymentMethodDataResponse::BankTransfer(_) | PaymentMethodDataResponse::OpenBanking(_) | PaymentMethodDataResponse::Voucher(_) => { @@ -3090,7 +3091,7 @@ where pub enum PaymentMethodDataResponse { Card(Box), BankTransfer(Box), - Wallet {}, + Wallet(Box), PayLater(Box), BankRedirect(Box), Crypto(Box), @@ -3187,6 +3188,21 @@ pub struct PaylaterResponse { klarna_sdk: Option, } +#[derive(Eq, PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize, ToSchema)] +pub struct WalletResponse { + #[serde(flatten)] + details: Option, +} + +#[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize, ToSchema)] +#[serde(rename_all = "snake_case")] +pub enum WalletResponseData { + #[schema(value_type = WalletAdditionalDataForCard)] + ApplePay(Box), + #[schema(value_type = WalletAdditionalDataForCard)] + GooglePay(Box), +} + #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize, ToSchema)] pub struct KlarnaSdkPaymentMethodResponse { @@ -4422,7 +4438,33 @@ impl From for PaymentMethodDataResponse { Some(sdk) => Self::PayLater(Box::new(PaylaterResponse::from(sdk))), None => Self::PayLater(Box::new(PaylaterResponse { klarna_sdk: None })), }, - AdditionalPaymentData::Wallet { .. } => Self::Wallet {}, + AdditionalPaymentData::Wallet { + apple_pay, + google_pay, + } => match (apple_pay, google_pay) { + (Some(apple_pay_pm), _) => Self::Wallet(Box::new(WalletResponse { + details: Some(WalletResponseData::ApplePay(Box::new( + additional_info::WalletAdditionalDataForCard { + last4: apple_pay_pm + .display_name + .clone() + .chars() + .rev() + .take(4) + .collect::() + .chars() + .rev() + .collect::(), + card_network: apple_pay_pm.network.clone(), + card_type: apple_pay_pm.pm_type.clone(), + }, + ))), + })), + (_, Some(google_pay_pm)) => Self::Wallet(Box::new(WalletResponse { + details: Some(WalletResponseData::GooglePay(Box::new(google_pay_pm))), + })), + _ => Self::Wallet(Box::new(WalletResponse { details: None })), + }, AdditionalPaymentData::BankRedirect { bank_name, details } => { Self::BankRedirect(Box::new(BankRedirectResponse { bank_name, details })) } diff --git a/crates/api_models/src/payments/additional_info.rs b/crates/api_models/src/payments/additional_info.rs index 77500b0edc..9e8c910cba 100644 --- a/crates/api_models/src/payments/additional_info.rs +++ b/crates/api_models/src/payments/additional_info.rs @@ -205,9 +205,19 @@ pub enum UpiAdditionalData { } #[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize, ToSchema)] -#[serde(rename_all = "snake_case")] pub struct UpiCollectAdditionalData { /// Masked VPA ID #[schema(value_type = Option, example = "ab********@okhdfcbank")] pub vpa_id: Option, } + +#[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize, ToSchema)] +pub struct WalletAdditionalDataForCard { + /// Last 4 digits of the card number + pub last4: String, + /// The information of the payment method + pub card_network: String, + /// The type of payment method + #[serde(rename = "type")] + pub card_type: String, +} diff --git a/crates/openapi/src/openapi.rs b/crates/openapi/src/openapi.rs index d71757e8f3..b626b7d441 100644 --- a/crates/openapi/src/openapi.rs +++ b/crates/openapi/src/openapi.rs @@ -613,7 +613,10 @@ Never share your secret api keys. Keep them guarded and secure. api_models::payments::additional_info::GivexGiftCardAdditionalData, api_models::payments::additional_info::UpiAdditionalData, api_models::payments::additional_info::UpiCollectAdditionalData, + api_models::payments::additional_info::WalletAdditionalDataForCard, api_models::payments::PaymentsDynamicTaxCalculationRequest, + api_models::payments::WalletResponse, + api_models::payments::WalletResponseData, api_models::payments::PaymentsDynamicTaxCalculationResponse, api_models::payments::DisplayAmountOnSdk, )), diff --git a/crates/openapi/src/openapi_v2.rs b/crates/openapi/src/openapi_v2.rs index 8a21110ae8..f12d6a7b56 100644 --- a/crates/openapi/src/openapi_v2.rs +++ b/crates/openapi/src/openapi_v2.rs @@ -530,6 +530,9 @@ Never share your secret api keys. Keep them guarded and secure. api_models::payments::additional_info::GivexGiftCardAdditionalData, api_models::payments::additional_info::UpiAdditionalData, api_models::payments::additional_info::UpiCollectAdditionalData, + api_models::payments::additional_info::WalletAdditionalDataForCard, + api_models::payments::WalletResponse, + api_models::payments::WalletResponseData, api_models::payments::PaymentsDynamicTaxCalculationRequest, api_models::payments::PaymentsDynamicTaxCalculationResponse, api_models::payments::DisplayAmountOnSdk, diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs index ce92c1ab00..81d9130db8 100644 --- a/crates/router/src/core/payments/helpers.rs +++ b/crates/router/src/core/payments/helpers.rs @@ -4261,9 +4261,23 @@ pub async fn get_additional_payment_data( network: apple_pay_wallet_data.payment_method.network.clone(), pm_type: apple_pay_wallet_data.payment_method.pm_type.clone(), }), + google_pay: None, }) } - _ => Some(api_models::payments::AdditionalPaymentData::Wallet { apple_pay: None }), + domain::WalletData::GooglePay(google_pay_pm_data) => { + Some(api_models::payments::AdditionalPaymentData::Wallet { + apple_pay: None, + google_pay: Some(payment_additional_types::WalletAdditionalDataForCard { + last4: google_pay_pm_data.info.card_details.clone(), + card_network: google_pay_pm_data.info.card_network.clone(), + card_type: google_pay_pm_data.pm_type.clone(), + }), + }) + } + _ => Some(api_models::payments::AdditionalPaymentData::Wallet { + apple_pay: None, + google_pay: None, + }), }, domain::PaymentMethodData::PayLater(_) => { Some(api_models::payments::AdditionalPaymentData::PayLater { klarna_sdk: None })