mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-02 21:07:58 +08:00
feat(connector): [TrustPay] Add Google Pay support (#1515)
Co-authored-by: Sanchith Hegde <sanchith.hegde@juspay.in>
This commit is contained in:
committed by
GitHub
parent
dd4ba63cc4
commit
47cd08a0b0
@ -17,7 +17,11 @@ use crate::{
|
||||
consts,
|
||||
core::errors,
|
||||
pii::Secret,
|
||||
types::{self, api, storage::enums, transformers::ForeignTryFrom},
|
||||
types::{
|
||||
self, api,
|
||||
storage::enums,
|
||||
transformers::{ForeignInto, ForeignTryFrom},
|
||||
},
|
||||
utils::{Encode, OptionExt},
|
||||
};
|
||||
|
||||
@ -349,7 +353,7 @@ impl TryFrom<types::PaymentsSessionResponseRouterData<BluesnapWalletTokenRespons
|
||||
),
|
||||
payment_request_data: Some(api_models::payments::ApplePayPaymentRequest {
|
||||
country_code: item.data.get_billing_country()?,
|
||||
currency_code: item.data.request.currency.to_string(),
|
||||
currency_code: item.data.request.currency.foreign_into(),
|
||||
total: api_models::payments::AmountInfo {
|
||||
label: applepay_metadata.data.payment_request_data.label,
|
||||
total_type: Some("final".to_string()),
|
||||
|
||||
@ -2,7 +2,7 @@ use std::collections::HashMap;
|
||||
|
||||
use api_models::payments::BankRedirectData;
|
||||
use common_utils::{errors::CustomResult, pii};
|
||||
use error_stack::{IntoReport, ResultExt};
|
||||
use error_stack::{report, IntoReport, ResultExt};
|
||||
use masking::Secret;
|
||||
use reqwest::Url;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@ -823,22 +823,25 @@ pub struct TrustpayCreateIntentRequest {
|
||||
pub currency: String,
|
||||
// If true, Apple Pay will be initialized
|
||||
pub init_apple_pay: Option<bool>,
|
||||
}
|
||||
|
||||
impl TryFrom<&types::PaymentsSessionRouterData> for TrustpayCreateIntentRequest {
|
||||
type Error = Error;
|
||||
fn try_from(item: &types::PaymentsSessionRouterData) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
amount: item.request.amount.to_string(),
|
||||
currency: item.request.currency.to_string(),
|
||||
init_apple_pay: Some(true),
|
||||
})
|
||||
}
|
||||
// If true, Google pay will be initialized
|
||||
pub init_google_pay: Option<bool>,
|
||||
}
|
||||
|
||||
impl TryFrom<&types::PaymentsPreProcessingRouterData> for TrustpayCreateIntentRequest {
|
||||
type Error = Error;
|
||||
fn try_from(item: &types::PaymentsPreProcessingRouterData) -> Result<Self, Self::Error> {
|
||||
let is_apple_pay = item
|
||||
.request
|
||||
.payment_method_type
|
||||
.as_ref()
|
||||
.map(|pmt| matches!(pmt, storage_models::enums::PaymentMethodType::ApplePay));
|
||||
|
||||
let is_google_pay = item
|
||||
.request
|
||||
.payment_method_type
|
||||
.as_ref()
|
||||
.map(|pmt| matches!(pmt, storage_models::enums::PaymentMethodType::GooglePay));
|
||||
|
||||
Ok(Self {
|
||||
amount: item
|
||||
.request
|
||||
@ -856,90 +859,218 @@ impl TryFrom<&types::PaymentsPreProcessingRouterData> for TrustpayCreateIntentRe
|
||||
field_name: "currency",
|
||||
})?
|
||||
.to_string(),
|
||||
init_apple_pay: Some(true),
|
||||
init_apple_pay: is_apple_pay,
|
||||
init_google_pay: is_google_pay,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Deserialize)]
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct TrustpayCreateIntentResponse {
|
||||
// TrustPay's authorization secrets used by client
|
||||
pub secrets: SdkSecretInfo,
|
||||
// Data object to be used for Apple Pay
|
||||
pub apple_init_result_data: TrustpayApplePayResponse,
|
||||
// Data object to be used for Apple Pay or Google Pay
|
||||
#[serde(flatten)]
|
||||
pub init_result_data: InitResultData,
|
||||
// Unique operation/transaction identifier
|
||||
pub instance_id: String,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Deserialize)]
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum InitResultData {
|
||||
AppleInitResultData(TrustpayApplePayResponse),
|
||||
GoogleInitResultData(TrustpayGooglePayResponse),
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GooglePayTransactionInfo {
|
||||
pub country_code: api_models::enums::CountryAlpha2,
|
||||
pub currency_code: api_models::enums::Currency,
|
||||
pub total_price_status: String,
|
||||
pub total_price: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GooglePayMerchantInfo {
|
||||
pub merchant_name: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GooglePayAllowedPaymentMethods {
|
||||
#[serde(rename = "type")]
|
||||
pub payment_method_type: String,
|
||||
pub parameters: GpayAllowedMethodsParameters,
|
||||
pub tokenization_specification: GpayTokenizationSpecification,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GpayTokenParameters {
|
||||
pub gateway: String,
|
||||
pub gateway_merchant_id: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GpayTokenizationSpecification {
|
||||
#[serde(rename = "type")]
|
||||
pub token_specification_type: String,
|
||||
pub parameters: GpayTokenParameters,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GpayAllowedMethodsParameters {
|
||||
pub allowed_auth_methods: Vec<String>,
|
||||
pub allowed_card_networks: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct TrustpayGooglePayResponse {
|
||||
pub merchant_info: GooglePayMerchantInfo,
|
||||
pub allowed_payment_methods: Vec<GooglePayAllowedPaymentMethods>,
|
||||
pub transaction_info: GooglePayTransactionInfo,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct SdkSecretInfo {
|
||||
pub display: Secret<String>,
|
||||
pub payment: Secret<String>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Deserialize)]
|
||||
#[derive(Clone, Default, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct TrustpayApplePayResponse {
|
||||
pub country_code: api_models::enums::CountryAlpha2,
|
||||
pub currency_code: String,
|
||||
pub currency_code: api_models::enums::Currency,
|
||||
pub supported_networks: Vec<String>,
|
||||
pub merchant_capabilities: Vec<String>,
|
||||
pub total: ApplePayTotalInfo,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Deserialize)]
|
||||
#[derive(Clone, Default, Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ApplePayTotalInfo {
|
||||
pub label: String,
|
||||
pub amount: String,
|
||||
}
|
||||
|
||||
impl<F, T>
|
||||
impl<F>
|
||||
TryFrom<
|
||||
types::ResponseRouterData<F, TrustpayCreateIntentResponse, T, types::PaymentsResponseData>,
|
||||
> for types::RouterData<F, T, types::PaymentsResponseData>
|
||||
types::ResponseRouterData<
|
||||
F,
|
||||
TrustpayCreateIntentResponse,
|
||||
types::PaymentsPreProcessingData,
|
||||
types::PaymentsResponseData,
|
||||
>,
|
||||
> for types::RouterData<F, types::PaymentsPreProcessingData, types::PaymentsResponseData>
|
||||
{
|
||||
type Error = Error;
|
||||
fn try_from(
|
||||
item: types::ResponseRouterData<
|
||||
F,
|
||||
TrustpayCreateIntentResponse,
|
||||
T,
|
||||
types::PaymentsPreProcessingData,
|
||||
types::PaymentsResponseData,
|
||||
>,
|
||||
) -> Result<Self, Self::Error> {
|
||||
let response = item.response;
|
||||
let create_intent_response = item.response.init_result_data.to_owned();
|
||||
let secrets = item.response.secrets.to_owned();
|
||||
let instance_id = item.response.instance_id.to_owned();
|
||||
let pmt = utils::PaymentsPreProcessingData::get_payment_method_type(&item.data.request)?;
|
||||
|
||||
Ok(Self {
|
||||
response: Ok(types::PaymentsResponseData::PreProcessingResponse {
|
||||
connector_metadata: None,
|
||||
pre_processing_id: types::PreprocessingResponseId::ConnectorTransactionId(
|
||||
response.instance_id,
|
||||
),
|
||||
session_token: Some(types::api::SessionToken::ApplePay(Box::new(
|
||||
api_models::payments::ApplepaySessionTokenResponse {
|
||||
session_token_data:
|
||||
api_models::payments::ApplePaySessionResponse::ThirdPartySdk(
|
||||
api_models::payments::ThirdPartySdkSessionResponse {
|
||||
secrets: response.secrets.into(),
|
||||
},
|
||||
),
|
||||
payment_request_data: Some(api_models::payments::ApplePayPaymentRequest {
|
||||
country_code: response.apple_init_result_data.country_code,
|
||||
currency_code: response.apple_init_result_data.currency_code.clone(),
|
||||
supported_networks: response
|
||||
.apple_init_result_data
|
||||
.supported_networks
|
||||
.clone(),
|
||||
merchant_capabilities: response
|
||||
.apple_init_result_data
|
||||
.merchant_capabilities
|
||||
.clone(),
|
||||
total: response.apple_init_result_data.total.into(),
|
||||
merchant_identifier: None,
|
||||
}),
|
||||
match (pmt, create_intent_response) {
|
||||
(
|
||||
storage_models::enums::PaymentMethodType::ApplePay,
|
||||
InitResultData::AppleInitResultData(apple_pay_response),
|
||||
) => get_apple_pay_session(instance_id, &secrets, apple_pay_response, item),
|
||||
(
|
||||
storage_models::enums::PaymentMethodType::GooglePay,
|
||||
InitResultData::GoogleInitResultData(google_pay_response),
|
||||
) => get_google_pay_session(instance_id, &secrets, google_pay_response, item),
|
||||
_ => Err(report!(errors::ConnectorError::InvalidWallet)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_apple_pay_session<F, T>(
|
||||
instance_id: String,
|
||||
secrets: &SdkSecretInfo,
|
||||
apple_pay_init_result: TrustpayApplePayResponse,
|
||||
item: types::ResponseRouterData<
|
||||
F,
|
||||
TrustpayCreateIntentResponse,
|
||||
T,
|
||||
types::PaymentsResponseData,
|
||||
>,
|
||||
) -> Result<
|
||||
types::RouterData<F, T, types::PaymentsResponseData>,
|
||||
error_stack::Report<errors::ConnectorError>,
|
||||
> {
|
||||
Ok(types::RouterData {
|
||||
response: Ok(types::PaymentsResponseData::PreProcessingResponse {
|
||||
connector_metadata: None,
|
||||
pre_processing_id: types::PreprocessingResponseId::ConnectorTransactionId(instance_id),
|
||||
session_token: Some(types::api::SessionToken::ApplePay(Box::new(
|
||||
api_models::payments::ApplepaySessionTokenResponse {
|
||||
session_token_data:
|
||||
api_models::payments::ApplePaySessionResponse::ThirdPartySdk(
|
||||
api_models::payments::ThirdPartySdkSessionResponse {
|
||||
secrets: secrets.to_owned().into(),
|
||||
},
|
||||
),
|
||||
payment_request_data: Some(api_models::payments::ApplePayPaymentRequest {
|
||||
country_code: apple_pay_init_result.country_code,
|
||||
currency_code: apple_pay_init_result.currency_code,
|
||||
supported_networks: apple_pay_init_result.supported_networks.clone(),
|
||||
merchant_capabilities: apple_pay_init_result.merchant_capabilities.clone(),
|
||||
total: apple_pay_init_result.total.into(),
|
||||
merchant_identifier: None,
|
||||
}),
|
||||
connector: "trustpay".to_string(),
|
||||
delayed_session_token: true,
|
||||
sdk_next_action: {
|
||||
api_models::payments::SdkNextAction {
|
||||
next_action: api_models::payments::NextActionCall::Sync,
|
||||
}
|
||||
},
|
||||
},
|
||||
))),
|
||||
}),
|
||||
// We don't get status from TrustPay but status should be pending by default for session response
|
||||
status: storage_models::enums::AttemptStatus::Pending,
|
||||
..item.data
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_google_pay_session<F, T>(
|
||||
instance_id: String,
|
||||
secrets: &SdkSecretInfo,
|
||||
google_pay_init_result: TrustpayGooglePayResponse,
|
||||
item: types::ResponseRouterData<
|
||||
F,
|
||||
TrustpayCreateIntentResponse,
|
||||
T,
|
||||
types::PaymentsResponseData,
|
||||
>,
|
||||
) -> Result<
|
||||
types::RouterData<F, T, types::PaymentsResponseData>,
|
||||
error_stack::Report<errors::ConnectorError>,
|
||||
> {
|
||||
Ok(types::RouterData {
|
||||
response: Ok(types::PaymentsResponseData::PreProcessingResponse {
|
||||
connector_metadata: None,
|
||||
pre_processing_id: types::PreprocessingResponseId::ConnectorTransactionId(instance_id),
|
||||
session_token: Some(types::api::SessionToken::GooglePay(Box::new(
|
||||
api_models::payments::GpaySessionTokenResponse::GooglePaySession(
|
||||
api_models::payments::GooglePaySessionResponse {
|
||||
connector: "trustpay".to_string(),
|
||||
delayed_session_token: true,
|
||||
sdk_next_action: {
|
||||
@ -947,12 +1078,79 @@ impl<F, T>
|
||||
next_action: api_models::payments::NextActionCall::Sync,
|
||||
}
|
||||
},
|
||||
merchant_info: google_pay_init_result.merchant_info.into(),
|
||||
allowed_payment_methods: google_pay_init_result
|
||||
.allowed_payment_methods
|
||||
.into_iter()
|
||||
.map(Into::into)
|
||||
.collect(),
|
||||
transaction_info: google_pay_init_result.transaction_info.into(),
|
||||
secrets: Some((*secrets).clone().into()),
|
||||
},
|
||||
))),
|
||||
}),
|
||||
status: storage_models::enums::AttemptStatus::Pending,
|
||||
..item.data
|
||||
})
|
||||
),
|
||||
))),
|
||||
}),
|
||||
// We don't get status from TrustPay but status should be pending by default for session response
|
||||
status: storage_models::enums::AttemptStatus::Pending,
|
||||
..item.data
|
||||
})
|
||||
}
|
||||
|
||||
impl From<GooglePayTransactionInfo> for api_models::payments::GpayTransactionInfo {
|
||||
fn from(value: GooglePayTransactionInfo) -> Self {
|
||||
Self {
|
||||
country_code: value.country_code,
|
||||
currency_code: value.currency_code,
|
||||
total_price_status: value.total_price_status,
|
||||
total_price: value.total_price,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<GooglePayMerchantInfo> for api_models::payments::GpayMerchantInfo {
|
||||
fn from(value: GooglePayMerchantInfo) -> Self {
|
||||
Self {
|
||||
merchant_name: value.merchant_name,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<GooglePayAllowedPaymentMethods> for api_models::payments::GpayAllowedPaymentMethods {
|
||||
fn from(value: GooglePayAllowedPaymentMethods) -> Self {
|
||||
Self {
|
||||
payment_method_type: value.payment_method_type,
|
||||
parameters: value.parameters.into(),
|
||||
tokenization_specification: value.tokenization_specification.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<GpayAllowedMethodsParameters> for api_models::payments::GpayAllowedMethodsParameters {
|
||||
fn from(value: GpayAllowedMethodsParameters) -> Self {
|
||||
Self {
|
||||
allowed_auth_methods: value.allowed_auth_methods,
|
||||
allowed_card_networks: value.allowed_card_networks,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<GpayTokenizationSpecification> for api_models::payments::GpayTokenizationSpecification {
|
||||
fn from(value: GpayTokenizationSpecification) -> Self {
|
||||
Self {
|
||||
token_specification_type: value.token_specification_type,
|
||||
parameters: value.parameters.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<GpayTokenParameters> for api_models::payments::GpayTokenParameters {
|
||||
fn from(value: GpayTokenParameters) -> Self {
|
||||
Self {
|
||||
gateway: value.gateway,
|
||||
gateway_merchant_id: Some(value.gateway_merchant_id),
|
||||
stripe_version: None,
|
||||
stripe_publishable_key: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -170,12 +170,18 @@ impl<Flow, Request, Response> RouterData for types::RouterData<Flow, Request, Re
|
||||
|
||||
pub trait PaymentsPreProcessingData {
|
||||
fn get_email(&self) -> Result<Email, Error>;
|
||||
fn get_payment_method_type(&self) -> Result<storage_models::enums::PaymentMethodType, Error>;
|
||||
}
|
||||
|
||||
impl PaymentsPreProcessingData for types::PaymentsPreProcessingData {
|
||||
fn get_email(&self) -> Result<Email, Error> {
|
||||
self.email.clone().ok_or_else(missing_field_err("email"))
|
||||
}
|
||||
fn get_payment_method_type(&self) -> Result<storage_models::enums::PaymentMethodType, Error> {
|
||||
self.payment_method_type
|
||||
.to_owned()
|
||||
.ok_or_else(missing_field_err("payment_method_type"))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait PaymentsAuthorizeRequestData {
|
||||
|
||||
@ -345,6 +345,7 @@ impl TryFrom<types::PaymentsAuthorizeData> for types::PaymentsPreProcessingData
|
||||
email: data.email,
|
||||
currency: Some(data.currency),
|
||||
amount: Some(data.amount),
|
||||
payment_method_type: data.payment_method_type,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,7 +13,7 @@ use crate::{
|
||||
headers, logger,
|
||||
routes::{self, metrics},
|
||||
services,
|
||||
types::{self, api, domain},
|
||||
types::{self, api, domain, transformers::ForeignInto},
|
||||
utils::{self, OptionExt},
|
||||
};
|
||||
|
||||
@ -154,14 +154,7 @@ async fn create_applepay_session_token(
|
||||
router_data: &types::PaymentsSessionRouterData,
|
||||
connector: &api::ConnectorData,
|
||||
) -> RouterResult<types::PaymentsSessionRouterData> {
|
||||
let connectors_with_delayed_response = &state
|
||||
.conf
|
||||
.delayed_session_response
|
||||
.connectors_with_delayed_session_response;
|
||||
|
||||
let connector_name = connector.connector_name;
|
||||
let delayed_response = connectors_with_delayed_response.contains(&connector_name);
|
||||
|
||||
let delayed_response = is_session_response_delayed(state, connector);
|
||||
if delayed_response {
|
||||
let delayed_response_apple_pay_session =
|
||||
Some(payment_types::ApplePaySessionResponse::NoSessionResponse);
|
||||
@ -169,7 +162,7 @@ async fn create_applepay_session_token(
|
||||
router_data,
|
||||
delayed_response_apple_pay_session,
|
||||
None, // Apple pay payment request will be none for delayed session response
|
||||
connector_name.to_string(),
|
||||
connector.connector_name.to_string(),
|
||||
delayed_response,
|
||||
payment_types::NextActionCall::Confirm,
|
||||
)
|
||||
@ -197,7 +190,7 @@ async fn create_applepay_session_token(
|
||||
.change_context(errors::ApiErrorResponse::MissingRequiredField {
|
||||
field_name: "country_code",
|
||||
})?,
|
||||
currency_code: router_data.request.currency.to_string(),
|
||||
currency_code: router_data.request.currency.foreign_into(),
|
||||
total: amount_info,
|
||||
merchant_capabilities: applepay_metadata
|
||||
.data
|
||||
@ -249,7 +242,7 @@ async fn create_applepay_session_token(
|
||||
router_data,
|
||||
session_response,
|
||||
Some(applepay_payment_request),
|
||||
connector_name.to_string(),
|
||||
connector.connector_name.to_string(),
|
||||
delayed_response,
|
||||
payment_types::NextActionCall::Confirm,
|
||||
)
|
||||
@ -289,53 +282,90 @@ fn create_apple_pay_session_response(
|
||||
}
|
||||
|
||||
fn create_gpay_session_token(
|
||||
state: &routes::AppState,
|
||||
router_data: &types::PaymentsSessionRouterData,
|
||||
connector: &api::ConnectorData,
|
||||
) -> RouterResult<types::PaymentsSessionRouterData> {
|
||||
let connector_metadata = router_data.connector_meta_data.clone();
|
||||
let delayed_response = is_session_response_delayed(state, connector);
|
||||
|
||||
let gpay_data = connector_metadata
|
||||
.clone()
|
||||
.parse_value::<payment_types::GpaySessionTokenData>("GpaySessionTokenData")
|
||||
.change_context(errors::ConnectorError::NoConnectorMetaData)
|
||||
.attach_printable(format!(
|
||||
"cannot parse gpay metadata from the given value {connector_metadata:?}"
|
||||
))
|
||||
.change_context(errors::ApiErrorResponse::InvalidDataFormat {
|
||||
field_name: "connector_metadata".to_string(),
|
||||
expected_format: "gpay_metadata_format".to_string(),
|
||||
})?;
|
||||
if delayed_response {
|
||||
Ok(types::PaymentsSessionRouterData {
|
||||
response: Ok(types::PaymentsResponseData::SessionResponse {
|
||||
session_token: payment_types::SessionToken::GooglePay(Box::new(
|
||||
payment_types::GpaySessionTokenResponse::ThirdPartyResponse(
|
||||
payment_types::GooglePayThirdPartySdk {
|
||||
delayed_session_token: true,
|
||||
connector: connector.connector_name.to_string(),
|
||||
sdk_next_action: payment_types::SdkNextAction {
|
||||
next_action: payment_types::NextActionCall::Confirm,
|
||||
},
|
||||
},
|
||||
),
|
||||
)),
|
||||
}),
|
||||
..router_data.clone()
|
||||
})
|
||||
} else {
|
||||
let gpay_data = connector_metadata
|
||||
.clone()
|
||||
.parse_value::<payment_types::GpaySessionTokenData>("GpaySessionTokenData")
|
||||
.change_context(errors::ConnectorError::NoConnectorMetaData)
|
||||
.attach_printable(format!(
|
||||
"cannot parse gpay metadata from the given value {connector_metadata:?}"
|
||||
))
|
||||
.change_context(errors::ApiErrorResponse::InvalidDataFormat {
|
||||
field_name: "connector_metadata".to_string(),
|
||||
expected_format: "gpay_metadata_format".to_string(),
|
||||
})?;
|
||||
|
||||
let session_data = router_data.request.clone();
|
||||
let transaction_info = payment_types::GpayTransactionInfo {
|
||||
country_code: session_data.country.unwrap_or_default(),
|
||||
currency_code: router_data.request.currency.to_string(),
|
||||
total_price_status: "Final".to_string(),
|
||||
total_price: utils::to_currency_base_unit(
|
||||
router_data.request.amount,
|
||||
router_data.request.currency,
|
||||
)
|
||||
.attach_printable("Cannot convert given amount to base currency denomination".to_string())
|
||||
.change_context(errors::ApiErrorResponse::InvalidDataValue {
|
||||
field_name: "amount",
|
||||
})?,
|
||||
};
|
||||
let session_data = router_data.request.clone();
|
||||
let transaction_info = payment_types::GpayTransactionInfo {
|
||||
country_code: session_data.country.unwrap_or_default(),
|
||||
currency_code: router_data.request.currency.foreign_into(),
|
||||
total_price_status: "Final".to_string(),
|
||||
total_price: utils::to_currency_base_unit(
|
||||
router_data.request.amount,
|
||||
router_data.request.currency,
|
||||
)
|
||||
.attach_printable(
|
||||
"Cannot convert given amount to base currency denomination".to_string(),
|
||||
)
|
||||
.change_context(errors::ApiErrorResponse::InvalidDataValue {
|
||||
field_name: "amount",
|
||||
})?,
|
||||
};
|
||||
|
||||
let response_router_data = types::PaymentsSessionRouterData {
|
||||
response: Ok(types::PaymentsResponseData::SessionResponse {
|
||||
session_token: payment_types::SessionToken::GooglePay(Box::new(
|
||||
payment_types::GpaySessionTokenResponse {
|
||||
merchant_info: gpay_data.data.merchant_info,
|
||||
allowed_payment_methods: gpay_data.data.allowed_payment_methods,
|
||||
transaction_info,
|
||||
connector: connector.connector_name.to_string(),
|
||||
},
|
||||
)),
|
||||
}),
|
||||
..router_data.clone()
|
||||
};
|
||||
Ok(types::PaymentsSessionRouterData {
|
||||
response: Ok(types::PaymentsResponseData::SessionResponse {
|
||||
session_token: payment_types::SessionToken::GooglePay(Box::new(
|
||||
payment_types::GpaySessionTokenResponse::GooglePaySession(
|
||||
payment_types::GooglePaySessionResponse {
|
||||
merchant_info: gpay_data.data.merchant_info,
|
||||
allowed_payment_methods: gpay_data.data.allowed_payment_methods,
|
||||
transaction_info,
|
||||
connector: connector.connector_name.to_string(),
|
||||
sdk_next_action: payment_types::SdkNextAction {
|
||||
next_action: payment_types::NextActionCall::Confirm,
|
||||
},
|
||||
delayed_session_token: false,
|
||||
secrets: None,
|
||||
},
|
||||
),
|
||||
)),
|
||||
}),
|
||||
..router_data.clone()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Ok(response_router_data)
|
||||
fn is_session_response_delayed(state: &routes::AppState, connector: &api::ConnectorData) -> bool {
|
||||
let connectors_with_delayed_response = &state
|
||||
.conf
|
||||
.delayed_session_response
|
||||
.connectors_with_delayed_session_response;
|
||||
|
||||
connectors_with_delayed_response.contains(&connector.connector_name)
|
||||
}
|
||||
|
||||
fn log_session_response_if_error(
|
||||
@ -360,7 +390,7 @@ impl types::PaymentsSessionRouterData {
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
) -> RouterResult<Self> {
|
||||
match connector.get_token {
|
||||
api::GetToken::GpayMetadata => create_gpay_session_token(self, connector),
|
||||
api::GetToken::GpayMetadata => create_gpay_session_token(state, self, connector),
|
||||
api::GetToken::ApplePayMetadata => {
|
||||
create_applepay_session_token(state, self, connector).await
|
||||
}
|
||||
|
||||
@ -945,6 +945,7 @@ impl<F: Clone> TryFrom<PaymentAdditionalData<'_, F>> for types::PaymentsPreProce
|
||||
email: payment_data.email,
|
||||
currency: Some(payment_data.currency),
|
||||
amount: Some(payment_data.amount.into()),
|
||||
payment_method_type: payment_data.payment_attempt.payment_method_type,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -219,6 +219,7 @@ Never share your secret api keys. Keep them guarded and secure.
|
||||
api_models::payments::GpayTokenParameters,
|
||||
api_models::payments::GpayTransactionInfo,
|
||||
api_models::payments::GpaySessionTokenResponse,
|
||||
api_models::payments::GooglePayThirdPartySdkData,
|
||||
api_models::payments::KlarnaSessionTokenResponse,
|
||||
api_models::payments::PaypalSessionTokenResponse,
|
||||
api_models::payments::ApplepaySessionTokenResponse,
|
||||
@ -242,6 +243,8 @@ Never share your secret api keys. Keep them guarded and secure.
|
||||
api_models::payments::ApplePayRedirectData,
|
||||
api_models::payments::ApplePayThirdPartySdkData,
|
||||
api_models::payments::GooglePayRedirectData,
|
||||
api_models::payments::GooglePayThirdPartySdk,
|
||||
api_models::payments::GooglePaySessionResponse,
|
||||
api_models::payments::SepaBankTransferInstructions,
|
||||
api_models::payments::BacsBankTransferInstructions,
|
||||
api_models::payments::RedirectResponse,
|
||||
|
||||
@ -271,6 +271,7 @@ pub struct PaymentsPreProcessingData {
|
||||
pub email: Option<Email>,
|
||||
pub currency: Option<storage_enums::Currency>,
|
||||
pub amount: Option<i64>,
|
||||
pub payment_method_type: Option<storage_enums::PaymentMethodType>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
||||
Reference in New Issue
Block a user