diff --git a/Cargo.lock b/Cargo.lock index bd81825ee3..f93aa8d1dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1639,7 +1639,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" dependencies = [ "cfg-if", - "hashbrown", + "hashbrown 0.12.3", "lock_api", "once_cell", "parking_lot_core", @@ -1856,6 +1856,12 @@ dependencies = [ "termcolor", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "errno" version = "0.3.1" @@ -2301,7 +2307,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 1.9.3", "slab", "tokio", "tokio-util", @@ -2317,6 +2323,12 @@ dependencies = [ "ahash 0.7.6", ] +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + [[package]] name = "heck" version = "0.4.1" @@ -2555,10 +2567,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", "serde", ] +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", +] + [[package]] name = "infer" version = "0.2.3" @@ -3215,7 +3237,7 @@ dependencies = [ "fnv", "futures-channel", "futures-util", - "indexmap", + "indexmap 1.9.3", "once_cell", "pin-project-lite", "thiserror", @@ -3251,7 +3273,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" dependencies = [ "dlv-list", - "hashbrown", + "hashbrown 0.12.3", ] [[package]] @@ -4007,6 +4029,7 @@ version = "0.1.0" dependencies = [ "darling 0.14.4", "diesel", + "indexmap 2.0.0", "proc-macro2", "quote", "serde", @@ -4279,7 +4302,7 @@ version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" dependencies = [ - "indexmap", + "indexmap 1.9.3", "itoa", "ryu", "serde", @@ -4366,7 +4389,7 @@ dependencies = [ "base64 0.21.2", "chrono", "hex", - "indexmap", + "indexmap 1.9.3", "serde", "serde_json", "serde_with_macros", @@ -4975,7 +4998,7 @@ version = "0.19.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2380d56e8670370eee6566b0bfd4265f65b3f432e8c6d85623f728d4fa31f739" dependencies = [ - "indexmap", + "indexmap 1.9.3", "serde", "serde_spanned", "toml_datetime", @@ -5022,7 +5045,7 @@ checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" dependencies = [ "futures-core", "futures-util", - "indexmap", + "indexmap 1.9.3", "pin-project", "pin-project-lite", "rand 0.8.5", @@ -5279,7 +5302,7 @@ version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68ae74ef183fae36d650f063ae7bde1cacbe1cd7e72b617cbe1e985551878b98" dependencies = [ - "indexmap", + "indexmap 1.9.3", "serde", "serde_json", "utoipa-gen", diff --git a/crates/router/src/connector/authorizedotnet.rs b/crates/router/src/connector/authorizedotnet.rs index 2543d416c9..6b7ed503f9 100644 --- a/crates/router/src/connector/authorizedotnet.rs +++ b/crates/router/src/connector/authorizedotnet.rs @@ -10,12 +10,15 @@ use transformers as authorizedotnet; use crate::{ configs::settings, consts, - core::errors::{self, CustomResult}, + core::{ + errors::{self, CustomResult}, + payments, + }, headers, services::{self, request, ConnectorIntegration}, types::{ self, - api::{self, ConnectorCommon, ConnectorCommonExt}, + api::{self, ConnectorCommon, ConnectorCommonExt, PaymentsCompleteAuthorize}, }, utils::{self, BytesExt}, }; @@ -192,7 +195,7 @@ impl ConnectorIntegration &'static str { - "application/json" + self.common_get_content_type() } fn get_url( @@ -545,7 +548,7 @@ impl ConnectorIntegration &'static str { - "application/json" + self.common_get_content_type() } fn get_url( @@ -600,6 +603,100 @@ impl ConnectorIntegration CustomResult { + get_error_response(res) + } +} + +impl PaymentsCompleteAuthorize for Authorizedotnet {} + +impl + ConnectorIntegration< + api::CompleteAuthorize, + types::CompleteAuthorizeData, + types::PaymentsResponseData, + > for Authorizedotnet +{ + fn get_headers( + &self, + req: &types::PaymentsCompleteAuthorizeRouterData, + connectors: &settings::Connectors, + ) -> CustomResult)>, errors::ConnectorError> { + self.build_headers(req, connectors) + } + + fn get_content_type(&self) -> &'static str { + self.common_get_content_type() + } + + fn get_url( + &self, + _req: &types::PaymentsCompleteAuthorizeRouterData, + connectors: &settings::Connectors, + ) -> CustomResult { + Ok(self.base_url(connectors).to_string()) + } + fn get_request_body( + &self, + req: &types::PaymentsCompleteAuthorizeRouterData, + ) -> CustomResult, errors::ConnectorError> { + let connector_req = authorizedotnet::PaypalConfirmRequest::try_from(req)?; + let authorizedotnet_req = types::RequestBody::log_and_get_request_body( + &connector_req, + utils::Encode::::encode_to_string_of_json, + ) + .change_context(errors::ConnectorError::RequestEncodingFailed)?; + Ok(Some(authorizedotnet_req)) + } + + fn build_request( + &self, + req: &types::PaymentsCompleteAuthorizeRouterData, + connectors: &settings::Connectors, + ) -> CustomResult, errors::ConnectorError> { + Ok(Some( + services::RequestBuilder::new() + .method(services::Method::Post) + .url(&types::PaymentsCompleteAuthorizeType::get_url( + self, req, connectors, + )?) + .attach_default_headers() + .headers(types::PaymentsCompleteAuthorizeType::get_headers( + self, req, connectors, + )?) + .body(types::PaymentsCompleteAuthorizeType::get_request_body( + self, req, + )?) + .build(), + )) + } + + fn handle_response( + &self, + data: &types::PaymentsCompleteAuthorizeRouterData, + res: types::Response, + ) -> CustomResult { + use bytes::Buf; + + // Handle the case where response bytes contains U+FEFF (BOM) character sent by connector + let encoding = encoding_rs::UTF_8; + let intermediate_response = encoding.decode_with_bom_removal(res.response.chunk()); + let intermediate_response = + bytes::Bytes::copy_from_slice(intermediate_response.0.as_bytes()); + + let response: authorizedotnet::AuthorizedotnetPaymentsResponse = intermediate_response + .parse_struct("AuthorizedotnetPaymentsResponse") + .change_context(errors::ConnectorError::ResponseDeserializationFailed)?; types::RouterData::try_from(types::ResponseRouterData { response, @@ -754,3 +851,14 @@ fn get_error_response( } } } + +impl services::ConnectorRedirectResponse for Authorizedotnet { + fn get_flow_type( + &self, + _query_params: &str, + _json_payload: Option, + _action: services::PaymentAction, + ) -> CustomResult { + Ok(payments::CallConnectorAction::Trigger) + } +} diff --git a/crates/router/src/connector/authorizedotnet/transformers.rs b/crates/router/src/connector/authorizedotnet/transformers.rs index 7e79141a6e..e0398b0655 100644 --- a/crates/router/src/connector/authorizedotnet/transformers.rs +++ b/crates/router/src/connector/authorizedotnet/transformers.rs @@ -1,15 +1,20 @@ -use common_utils::ext_traits::{Encode, ValueExt}; -use error_stack::ResultExt; +use common_utils::{ + errors::CustomResult, + ext_traits::{Encode, ValueExt}, +}; +use error_stack::{IntoReport, ResultExt}; +use masking::{PeekInterface, Secret, StrongSecret}; use serde::{Deserialize, Serialize}; use crate::{ - connector::utils::{CardData, PaymentsSyncRequestData, RefundsRequestData}, + connector::utils::{CardData, PaymentsSyncRequestData, RefundsRequestData, WalletData}, core::errors, + services, types::{self, api, storage::enums}, utils::OptionExt, }; -#[derive(Debug, Serialize, PartialEq, Eq)] +#[derive(Debug, Serialize)] pub enum TransactionType { #[serde(rename = "authCaptureTransaction")] Payment, @@ -21,8 +26,12 @@ pub enum TransactionType { Refund, #[serde(rename = "voidTransaction")] Void, + #[serde(rename = "authOnlyContinueTransaction")] + ContinueAuthorization, + #[serde(rename = "authCaptureContinueTransaction")] + ContinueCapture, } -#[derive(Debug, Serialize, PartialEq)] +#[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] struct MerchantAuthentication { name: String, @@ -44,33 +53,49 @@ impl TryFrom<&types::ConnectorAuthType> for MerchantAuthentication { } } -#[derive(Serialize, Deserialize, PartialEq, Debug)] +#[derive(Serialize, Deserialize, Debug)] #[serde(rename_all = "camelCase")] struct CreditCardDetails { - card_number: masking::StrongSecret, - expiration_date: masking::Secret, + card_number: StrongSecret, + expiration_date: Secret, #[serde(skip_serializing_if = "Option::is_none")] - card_code: Option>, + card_code: Option>, } -#[derive(Serialize, Deserialize, PartialEq, Debug)] +#[derive(Serialize, Deserialize, Debug)] #[serde(rename_all = "camelCase")] struct BankAccountDetails { - account_number: masking::Secret, + account_number: Secret, } -#[derive(Serialize, Deserialize, PartialEq, Debug)] +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "camelCase")] enum PaymentDetails { - #[serde(rename = "creditCard")] CreditCard(CreditCardDetails), - #[serde(rename = "bankAccount")] - BankAccount(BankAccountDetails), - Wallet, - Klarna, - Paypal, - #[serde(rename = "bankRedirect")] - BankRedirect, - BankTransfer, + OpaqueData(WalletDetails), + PayPal(PayPalDetails), +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct PayPalDetails { + pub success_url: Option, + pub cancel_url: Option, +} + +#[derive(Serialize, Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct WalletDetails { + pub data_descriptor: WalletMethod, + pub data_value: String, +} + +#[derive(Serialize, Debug, Deserialize)] +pub enum WalletMethod { + #[serde(rename = "COMMON.GOOGLE.INAPP.PAYMENT")] + Googlepay, + #[serde(rename = "COMMON.APPLE.INAPP.PAYMENT")] + Applepay, } fn get_pm_and_subsequent_auth_detail( @@ -131,17 +156,12 @@ fn get_pm_and_subsequent_auth_detail( None, )) } - api::PaymentMethodData::PayLater(_) => Ok((PaymentDetails::Klarna, None, None)), - api::PaymentMethodData::Wallet(_) => Ok((PaymentDetails::Wallet, None, None)), - api::PaymentMethodData::BankRedirect(_) => { - Ok((PaymentDetails::BankRedirect, None, None)) - } - api::PaymentMethodData::Crypto(_) - | api::PaymentMethodData::BankDebit(_) - | api::PaymentMethodData::MandatePayment - | api::PaymentMethodData::BankTransfer(_) - | api::PaymentMethodData::Reward(_) - | api::PaymentMethodData::Upi(_) => Err(errors::ConnectorError::NotSupported { + api::PaymentMethodData::Wallet(ref wallet_data) => Ok(( + get_wallet_data(wallet_data, &item.request.complete_authorize_url)?, + None, + None, + )), + _ => Err(errors::ConnectorError::NotSupported { message: format!("{:?}", item.request.payment_method_data), connector: "AuthorizeDotNet", payment_experience: api_models::enums::PaymentExperience::RedirectToUrl.to_string(), @@ -150,7 +170,7 @@ fn get_pm_and_subsequent_auth_detail( } } -#[derive(Debug, Serialize, PartialEq)] +#[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] struct TransactionRequest { transaction_type: TransactionType, @@ -163,13 +183,13 @@ struct TransactionRequest { authorization_indicator_type: Option, } -#[derive(Debug, Serialize, PartialEq)] +#[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct ProcessingOptions { is_subsequent_auth: bool, } -#[derive(Debug, Serialize, PartialEq)] +#[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct SubsequentAuthInformation { original_network_trans_id: String, @@ -177,7 +197,7 @@ pub struct SubsequentAuthInformation { reason: Reason, } -#[derive(Debug, Serialize, PartialEq)] +#[derive(Debug, Serialize)] #[serde(rename_all = "lowercase")] pub enum Reason { Resubmission, @@ -188,13 +208,13 @@ pub enum Reason { NoShow, } -#[derive(Debug, Serialize, PartialEq)] +#[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] struct AuthorizationIndicator { authorization_indicator: AuthorizationType, } -#[derive(Debug, Serialize, PartialEq)] +#[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] struct TransactionVoidOrCaptureRequest { transaction_type: TransactionType, @@ -202,34 +222,34 @@ struct TransactionVoidOrCaptureRequest { ref_trans_id: String, } -#[derive(Debug, Serialize, PartialEq)] +#[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct AuthorizedotnetPaymentsRequest { merchant_authentication: MerchantAuthentication, transaction_request: TransactionRequest, } -#[derive(Debug, Serialize, PartialEq)] +#[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct AuthorizedotnetPaymentCancelOrCaptureRequest { merchant_authentication: MerchantAuthentication, transaction_request: TransactionVoidOrCaptureRequest, } -#[derive(Debug, Serialize, PartialEq)] +#[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] // The connector enforces field ordering, it expects fields to be in the same order as in their API documentation pub struct CreateTransactionRequest { create_transaction_request: AuthorizedotnetPaymentsRequest, } -#[derive(Debug, Serialize, PartialEq)] +#[derive(Debug, Serialize)] #[serde(rename_all = "camelCase")] pub struct CancelOrCaptureTransactionRequest { create_transaction_request: AuthorizedotnetPaymentCancelOrCaptureRequest, } -#[derive(Debug, Serialize, PartialEq, Eq)] +#[derive(Debug, Serialize)] #[serde(rename_all = "lowercase")] pub enum AuthorizationType { Final, @@ -315,7 +335,7 @@ impl TryFrom<&types::PaymentsCaptureRouterData> for CancelOrCaptureTransactionRe } } -#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Deserialize)] +#[derive(Debug, Clone, Default, serde::Deserialize)] pub enum AuthorizedotnetPaymentStatus { #[serde(rename = "1")] Approved, @@ -326,9 +346,21 @@ pub enum AuthorizedotnetPaymentStatus { #[serde(rename = "4")] #[default] HeldForReview, + #[serde(rename = "5")] + RequiresAction, } -pub type AuthorizedotnetRefundStatus = AuthorizedotnetPaymentStatus; +#[derive(Debug, Clone, serde::Deserialize)] +pub enum AuthorizedotnetRefundStatus { + #[serde(rename = "1")] + Approved, + #[serde(rename = "2")] + Declined, + #[serde(rename = "3")] + Error, + #[serde(rename = "4")] + HeldForReview, +} impl From for enums::AttemptStatus { fn from(item: AuthorizedotnetPaymentStatus) -> Self { @@ -337,6 +369,7 @@ impl From for enums::AttemptStatus { AuthorizedotnetPaymentStatus::Declined | AuthorizedotnetPaymentStatus::Error => { Self::Failure } + AuthorizedotnetPaymentStatus::RequiresAction => Self::AuthenticationPending, AuthorizedotnetPaymentStatus::HeldForReview => Self::Pending, } } @@ -362,26 +395,43 @@ pub struct ResponseMessages { pub message: Vec, } -#[derive(Debug, Clone, Deserialize, PartialEq, Eq)] +#[derive(Debug, Clone, Deserialize)] #[serde(rename_all = "camelCase")] pub struct ErrorMessage { pub error_code: String, pub error_text: String, } -#[derive(Debug, Clone, Deserialize, PartialEq, Eq)] +#[derive(Debug, Clone, Deserialize)] #[serde(rename_all = "camelCase")] pub struct TransactionResponse { response_code: AuthorizedotnetPaymentStatus, - auth_code: String, #[serde(rename = "transId")] transaction_id: String, network_trans_id: Option, pub(super) account_number: Option, pub(super) errors: Option>, + secure_acceptance: Option, } -#[derive(Debug, Clone, Deserialize, PartialEq)] +#[derive(Debug, Clone, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct RefundResponse { + response_code: AuthorizedotnetRefundStatus, + #[serde(rename = "transId")] + transaction_id: String, + network_trans_id: Option, + pub account_number: Option, + pub errors: Option>, +} + +#[derive(Debug, Clone, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct SecureAcceptance { + secure_acceptance_url: Option, +} + +#[derive(Debug, Clone, Deserialize)] #[serde(rename_all = "camelCase")] pub struct AuthorizedotnetPaymentsResponse { pub transaction_response: Option, @@ -471,6 +521,12 @@ impl .change_context(errors::ConnectorError::MissingRequiredField { field_name: "connector_metadata", })?; + let url = transaction_response + .secure_acceptance + .as_ref() + .and_then(|x| x.secure_acceptance_url.to_owned()); + let redirection_data = + url.map(|url| services::RedirectForm::from((url, services::Method::Get))); Ok(Self { status, response: match error { @@ -479,7 +535,7 @@ impl resource_id: types::ResponseId::ConnectorTransactionId( transaction_response.transaction_id.clone(), ), - redirection_data: None, + redirection_data, mandate_reference: None, connector_metadata: metadata, network_txn_id: transaction_response.network_trans_id.clone(), @@ -623,14 +679,14 @@ impl TryFrom<&types::RefundsRouterData> for CreateRefundRequest { } } -impl From for enums::RefundStatus { +impl From for enums::RefundStatus { fn from(item: AuthorizedotnetRefundStatus) -> Self { match item { - AuthorizedotnetPaymentStatus::Approved => Self::Success, - AuthorizedotnetPaymentStatus::Declined | AuthorizedotnetPaymentStatus::Error => { + AuthorizedotnetRefundStatus::Approved => Self::Success, + AuthorizedotnetRefundStatus::Declined | AuthorizedotnetRefundStatus::Error => { Self::Failure } - AuthorizedotnetPaymentStatus::HeldForReview => Self::Pending, + AuthorizedotnetRefundStatus::HeldForReview => Self::Pending, } } } @@ -638,7 +694,7 @@ impl From for enums::RefundStatus { #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] pub struct AuthorizedotnetRefundResponse { - pub transaction_response: TransactionResponse, + pub transaction_response: RefundResponse, pub messages: ResponseMessages, } @@ -847,7 +903,7 @@ impl } } -#[derive(Debug, Default, Eq, PartialEq, Deserialize)] +#[derive(Debug, Default, Deserialize)] pub struct ErrorDetails { pub code: Option, #[serde(rename = "type")] @@ -856,7 +912,7 @@ pub struct ErrorDetails { pub param: Option, } -#[derive(Default, Debug, Deserialize, PartialEq, Eq)] +#[derive(Default, Debug, Deserialize)] pub struct AuthorizedotnetErrorResponse { pub error: ErrorDetails, } @@ -992,3 +1048,115 @@ impl TryFrom for AuthorizedotnetSyncResponse { }) } } + +fn get_wallet_data( + wallet_data: &api_models::payments::WalletData, + return_url: &Option, +) -> CustomResult { + match wallet_data { + api_models::payments::WalletData::GooglePay(_) => { + Ok(PaymentDetails::OpaqueData(WalletDetails { + data_descriptor: WalletMethod::Googlepay, + data_value: wallet_data.get_encoded_wallet_token()?, + })) + } + api_models::payments::WalletData::ApplePay(applepay_token) => { + Ok(PaymentDetails::OpaqueData(WalletDetails { + data_descriptor: WalletMethod::Applepay, + data_value: applepay_token.payment_data.clone(), + })) + } + api_models::payments::WalletData::PaypalRedirect(_) => { + Ok(PaymentDetails::PayPal(PayPalDetails { + success_url: return_url.to_owned(), + cancel_url: return_url.to_owned(), + })) + } + _ => Err(errors::ConnectorError::NotImplemented( + "Payment method".to_string(), + ))?, + } +} + +#[derive(Debug, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct AuthorizedotnetQueryParams { + payer_id: String, +} + +#[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct PaypalConfirmRequest { + create_transaction_request: PaypalConfirmTransactionRequest, +} + +#[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct PaypalConfirmTransactionRequest { + merchant_authentication: MerchantAuthentication, + transaction_request: TransactionConfirmRequest, +} + +#[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct TransactionConfirmRequest { + transaction_type: TransactionType, + payment: PaypalPaymentConfirm, + ref_trans_id: Option, +} + +#[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct PaypalPaymentConfirm { + pay_pal: Paypal, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Paypal { + #[serde(rename = "payerID")] + payer_id: Secret, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct PaypalQueryParams { + #[serde(rename = "PayerID")] + payer_id: String, +} + +impl TryFrom<&types::PaymentsCompleteAuthorizeRouterData> for PaypalConfirmRequest { + type Error = error_stack::Report; + fn try_from(item: &types::PaymentsCompleteAuthorizeRouterData) -> Result { + let params = item + .request + .redirect_response + .as_ref() + .and_then(|redirect_response| redirect_response.params.as_ref()) + .ok_or(errors::ConnectorError::ResponseDeserializationFailed)?; + let payer_id: Secret = Secret::new( + serde_urlencoded::from_str::(params.peek()) + .into_report() + .change_context(errors::ConnectorError::ResponseDeserializationFailed)? + .payer_id, + ); + let transaction_type = match item.request.capture_method { + Some(enums::CaptureMethod::Manual) => TransactionType::ContinueAuthorization, + _ => TransactionType::ContinueCapture, + }; + let transaction_request = TransactionConfirmRequest { + transaction_type, + payment: PaypalPaymentConfirm { + pay_pal: Paypal { payer_id }, + }, + ref_trans_id: item.request.connector_transaction_id.clone(), + }; + + let merchant_authentication = MerchantAuthentication::try_from(&item.connector_auth_type)?; + + Ok(Self { + create_transaction_request: PaypalConfirmTransactionRequest { + merchant_authentication, + transaction_request, + }, + }) + } +} diff --git a/crates/router/src/connector/utils.rs b/crates/router/src/connector/utils.rs index 49a29b78e9..4093984a8d 100644 --- a/crates/router/src/connector/utils.rs +++ b/crates/router/src/connector/utils.rs @@ -581,6 +581,7 @@ pub trait WalletData { fn get_wallet_token_as_json(&self) -> Result where T: serde::de::DeserializeOwned; + fn get_encoded_wallet_token(&self) -> Result; } impl WalletData for api::WalletData { @@ -600,6 +601,20 @@ impl WalletData for api::WalletData { .into_report() .change_context(errors::ConnectorError::InvalidWalletToken) } + + fn get_encoded_wallet_token(&self) -> Result { + match self { + Self::GooglePay(_) => { + let json_token: serde_json::Value = self.get_wallet_token_as_json()?; + let token_as_vec = serde_json::to_vec(&json_token) + .into_report() + .change_context(errors::ConnectorError::InvalidWalletToken)?; + let encoded_token = consts::BASE64_ENGINE.encode(token_as_vec); + Ok(encoded_token) + } + _ => Err(errors::ConnectorError::InvalidWalletToken.into()), + } + } } pub trait ApplePay { diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs index 3c6b295b41..1082c85ad3 100644 --- a/crates/router/src/core/payments.rs +++ b/crates/router/src/core/payments.rs @@ -442,7 +442,7 @@ impl PaymentRedirectFlow for PaymentRedirectCompleteAuthorize { // If the status is terminal status, then redirect to merchant return url to provide status api_models::enums::IntentStatus::Succeeded | api_models::enums::IntentStatus::Failed - | api_models::enums::IntentStatus::Cancelled | api_models::enums::IntentStatus::RequiresCapture=> helpers::get_handle_response_url( + | api_models::enums::IntentStatus::Cancelled | api_models::enums::IntentStatus::RequiresCapture| api_models::enums::IntentStatus::Processing=> helpers::get_handle_response_url( payment_id, &merchant_account, payments_response, diff --git a/crates/router/src/core/payments/flows.rs b/crates/router/src/core/payments/flows.rs index cc04b0d5ac..cd7ef467ef 100644 --- a/crates/router/src/core/payments/flows.rs +++ b/crates/router/src/core/payments/flows.rs @@ -139,7 +139,6 @@ impl default_imp_for_complete_authorize!( connector::Aci, connector::Adyen, - connector::Authorizedotnet, connector::Bitpay, connector::Braintree, connector::Cashtocode, @@ -273,7 +272,6 @@ impl services::ConnectorRedirectResponse for connector::DummyConnec default_imp_for_connector_redirect_response!( connector::Aci, connector::Adyen, - connector::Authorizedotnet, connector::Bitpay, connector::Braintree, connector::Cashtocode,