mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 00:49:42 +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
@ -852,6 +852,8 @@ pub enum WalletData {
|
||||
GooglePay(GooglePayWalletData),
|
||||
/// Wallet data for google pay redirect flow
|
||||
GooglePayRedirect(Box<GooglePayRedirectData>),
|
||||
/// Wallet data for Google pay third party sdk flow
|
||||
GooglePayThirdPartySdk(Box<GooglePayThirdPartySdkData>),
|
||||
MbWayRedirect(Box<MbWayRedirection>),
|
||||
/// The wallet data for MobilePay redirect
|
||||
MobilePayRedirect(Box<MobilePayRedirection>),
|
||||
@ -893,6 +895,9 @@ pub struct ApplePayRedirectData {}
|
||||
#[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)]
|
||||
pub struct GooglePayRedirectData {}
|
||||
|
||||
#[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)]
|
||||
pub struct GooglePayThirdPartySdkData {}
|
||||
|
||||
#[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)]
|
||||
pub struct ApplePayThirdPartySdkData {}
|
||||
|
||||
@ -1781,7 +1786,8 @@ pub struct GpayTransactionInfo {
|
||||
#[schema(value_type = CountryAlpha2, example = "US")]
|
||||
pub country_code: api_enums::CountryAlpha2,
|
||||
/// The currency code
|
||||
pub currency_code: String,
|
||||
#[schema(value_type = Currency, example = "USD")]
|
||||
pub currency_code: api_enums::Currency,
|
||||
/// The total price status (ex: 'FINAL')
|
||||
pub total_price_status: String,
|
||||
/// The total price
|
||||
@ -1870,16 +1876,43 @@ pub enum SessionToken {
|
||||
NoSessionTokenReceived,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq, serde::Serialize, ToSchema)]
|
||||
#[serde(untagged)]
|
||||
pub enum GpaySessionTokenResponse {
|
||||
/// Google pay response involving third party sdk
|
||||
ThirdPartyResponse(GooglePayThirdPartySdk),
|
||||
/// Google pay session response for non third party sdk
|
||||
GooglePaySession(GooglePaySessionResponse),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq, serde::Serialize, ToSchema)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub struct GpaySessionTokenResponse {
|
||||
pub struct GooglePayThirdPartySdk {
|
||||
/// Identifier for the delayed session response
|
||||
pub delayed_session_token: bool,
|
||||
/// The name of the connector
|
||||
pub connector: String,
|
||||
/// The next action for the sdk (ex: calling confirm or sync call)
|
||||
pub sdk_next_action: SdkNextAction,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq, serde::Serialize, ToSchema)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub struct GooglePaySessionResponse {
|
||||
/// The merchant info
|
||||
pub merchant_info: GpayMerchantInfo,
|
||||
/// List of the allowed payment meythods
|
||||
pub allowed_payment_methods: Vec<GpayAllowedPaymentMethods>,
|
||||
/// The transaction info Google Pay requires
|
||||
pub transaction_info: GpayTransactionInfo,
|
||||
/// Identifier for the delayed session response
|
||||
pub delayed_session_token: bool,
|
||||
/// The name of the connector
|
||||
pub connector: String,
|
||||
/// The next action for the sdk (ex: calling confirm or sync call)
|
||||
pub sdk_next_action: SdkNextAction,
|
||||
/// Secrets for sdk display and payment
|
||||
pub secrets: Option<SecretInfoToInitiateSdk>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq, serde::Serialize, ToSchema)]
|
||||
@ -1988,7 +2021,8 @@ pub struct ApplePayPaymentRequest {
|
||||
#[schema(value_type = CountryAlpha2, example = "US")]
|
||||
pub country_code: api_enums::CountryAlpha2,
|
||||
/// The code for currency
|
||||
pub currency_code: String,
|
||||
#[schema(value_type = Currency, example = "USD")]
|
||||
pub currency_code: api_enums::Currency,
|
||||
/// Represents the total for the payment.
|
||||
pub total: AmountInfo,
|
||||
/// The list of merchant capabilities(ex: whether capable of 3ds or no-3ds)
|
||||
|
||||
@ -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)]
|
||||
|
||||
@ -1785,8 +1785,7 @@
|
||||
"$ref": "#/components/schemas/CountryAlpha2"
|
||||
},
|
||||
"currency_code": {
|
||||
"type": "string",
|
||||
"description": "The code for currency"
|
||||
"$ref": "#/components/schemas/Currency"
|
||||
},
|
||||
"total": {
|
||||
"$ref": "#/components/schemas/AmountInfo"
|
||||
@ -3941,6 +3940,75 @@
|
||||
"GooglePayRedirectData": {
|
||||
"type": "object"
|
||||
},
|
||||
"GooglePaySessionResponse": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"merchant_info",
|
||||
"allowed_payment_methods",
|
||||
"transaction_info",
|
||||
"delayed_session_token",
|
||||
"connector",
|
||||
"sdk_next_action"
|
||||
],
|
||||
"properties": {
|
||||
"merchant_info": {
|
||||
"$ref": "#/components/schemas/GpayMerchantInfo"
|
||||
},
|
||||
"allowed_payment_methods": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/GpayAllowedPaymentMethods"
|
||||
},
|
||||
"description": "List of the allowed payment meythods"
|
||||
},
|
||||
"transaction_info": {
|
||||
"$ref": "#/components/schemas/GpayTransactionInfo"
|
||||
},
|
||||
"delayed_session_token": {
|
||||
"type": "boolean",
|
||||
"description": "Identifier for the delayed session response"
|
||||
},
|
||||
"connector": {
|
||||
"type": "string",
|
||||
"description": "The name of the connector"
|
||||
},
|
||||
"sdk_next_action": {
|
||||
"$ref": "#/components/schemas/SdkNextAction"
|
||||
},
|
||||
"secrets": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/SecretInfoToInitiateSdk"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"GooglePayThirdPartySdk": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"delayed_session_token",
|
||||
"connector",
|
||||
"sdk_next_action"
|
||||
],
|
||||
"properties": {
|
||||
"delayed_session_token": {
|
||||
"type": "boolean",
|
||||
"description": "Identifier for the delayed session response"
|
||||
},
|
||||
"connector": {
|
||||
"type": "string",
|
||||
"description": "The name of the connector"
|
||||
},
|
||||
"sdk_next_action": {
|
||||
"$ref": "#/components/schemas/SdkNextAction"
|
||||
}
|
||||
}
|
||||
},
|
||||
"GooglePayThirdPartySdkData": {
|
||||
"type": "object"
|
||||
},
|
||||
"GooglePayWalletData": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@ -4022,31 +4090,14 @@
|
||||
}
|
||||
},
|
||||
"GpaySessionTokenResponse": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"merchant_info",
|
||||
"allowed_payment_methods",
|
||||
"transaction_info",
|
||||
"connector"
|
||||
],
|
||||
"properties": {
|
||||
"merchant_info": {
|
||||
"$ref": "#/components/schemas/GpayMerchantInfo"
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/GooglePayThirdPartySdk"
|
||||
},
|
||||
"allowed_payment_methods": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/GpayAllowedPaymentMethods"
|
||||
},
|
||||
"description": "List of the allowed payment meythods"
|
||||
},
|
||||
"transaction_info": {
|
||||
"$ref": "#/components/schemas/GpayTransactionInfo"
|
||||
},
|
||||
"connector": {
|
||||
"type": "string"
|
||||
{
|
||||
"$ref": "#/components/schemas/GooglePaySessionResponse"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"GpayTokenParameters": {
|
||||
"type": "object",
|
||||
@ -4119,8 +4170,7 @@
|
||||
"$ref": "#/components/schemas/CountryAlpha2"
|
||||
},
|
||||
"currency_code": {
|
||||
"type": "string",
|
||||
"description": "The currency code"
|
||||
"$ref": "#/components/schemas/Currency"
|
||||
},
|
||||
"total_price_status": {
|
||||
"type": "string",
|
||||
@ -6289,17 +6339,17 @@
|
||||
"PaymentsCreateRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"manual_retry",
|
||||
"amount",
|
||||
"currency"
|
||||
"currency",
|
||||
"manual_retry"
|
||||
],
|
||||
"properties": {
|
||||
"allowed_payment_method_types": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/PaymentMethodType"
|
||||
},
|
||||
"description": "Allowed Payment Method Types for a given PaymentIntent",
|
||||
"capture_method": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/CaptureMethod"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"payment_experience": {
|
||||
@ -6310,6 +6360,173 @@
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"amount": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "The payment amount. Amount for the payment in lowest denomination of the currency. (i.e) in cents for USD denomination, in paisa for INR denomination etc.,",
|
||||
"example": 6540,
|
||||
"nullable": true,
|
||||
"minimum": 0.0
|
||||
},
|
||||
"statement_descriptor_name": {
|
||||
"type": "string",
|
||||
"description": "For non-card charges, you can use this value as the complete description that appears on your customers’ statements. Must contain at least one letter, maximum 22 characters.",
|
||||
"example": "Hyperswitch Router",
|
||||
"nullable": true,
|
||||
"maxLength": 255
|
||||
},
|
||||
"order_details": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/OrderDetailsWithAmount"
|
||||
},
|
||||
"description": "Information about the product , quantity and amount for connectors. (e.g. Klarna)",
|
||||
"example": "[{\n \"product_name\": \"gillete creme\",\n \"quantity\": 15,\n \"amount\" : 900\n }]",
|
||||
"nullable": true
|
||||
},
|
||||
"connector": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/Connector"
|
||||
},
|
||||
"description": "This allows the merchant to manually select a connector with which the payment can go through",
|
||||
"example": [
|
||||
"stripe",
|
||||
"adyen"
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"currency": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/Currency"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"customer": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/CustomerDetails"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"mandate_data": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/MandateData"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"browser_info": {
|
||||
"type": "object",
|
||||
"description": "Additional details required by 3DS 2.0",
|
||||
"nullable": true
|
||||
},
|
||||
"business_label": {
|
||||
"type": "string",
|
||||
"description": "Business label of the merchant for this payment",
|
||||
"example": "food",
|
||||
"nullable": true
|
||||
},
|
||||
"payment_method": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/PaymentMethod"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"card_cvc": {
|
||||
"type": "string",
|
||||
"description": "This is used when payment is to be confirmed and the card is not saved",
|
||||
"nullable": true
|
||||
},
|
||||
"phone": {
|
||||
"type": "string",
|
||||
"description": "The customer's phone number\nThis field will be deprecated soon, use the customer object instead",
|
||||
"example": "3141592653",
|
||||
"nullable": true,
|
||||
"maxLength": 255
|
||||
},
|
||||
"authentication_type": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/AuthenticationType"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"manual_retry": {
|
||||
"type": "boolean",
|
||||
"description": "If enabled payment can be retried from the client side until the payment is successful or payment expires or the attempts(configured by the merchant) for payment are exhausted."
|
||||
},
|
||||
"capture_on": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "A timestamp (ISO 8601 code) that determines when the payment should be captured.\nProviding this field will automatically set `capture` to true",
|
||||
"example": "2022-09-10T10:11:12Z",
|
||||
"nullable": true
|
||||
},
|
||||
"return_url": {
|
||||
"type": "string",
|
||||
"description": "The URL to redirect after the completion of the operation",
|
||||
"example": "https://hyperswitch.io",
|
||||
"nullable": true
|
||||
},
|
||||
"setup_future_usage": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/FutureUsage"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"shipping": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/Address"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"business_sub_label": {
|
||||
"type": "string",
|
||||
"description": "Business sub label for the payment",
|
||||
"nullable": true
|
||||
},
|
||||
"confirm": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to confirm the payment (if applicable)",
|
||||
"default": false,
|
||||
"example": true,
|
||||
"nullable": true
|
||||
},
|
||||
"billing": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/Address"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"routing": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/RoutingAlgorithm"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"amount_to_capture": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "The Amount to be captured/ debited from the users payment method. It shall be in lowest denomination of the currency. (i.e) in cents for USD denomination, in paisa for INR denomination etc.,\nIf not provided, the default amount_to_capture will be the payment amount.",
|
||||
"example": 6540,
|
||||
"nullable": true
|
||||
},
|
||||
"off_session": {
|
||||
"type": "boolean",
|
||||
"description": "Set to true to indicate that the customer is not in your checkout flow during this payment, and therefore is unable to authenticate. This parameter is intended for scenarios where you collect card details and charge them later. This parameter can only be used with `confirm: true`.",
|
||||
@ -6323,108 +6540,6 @@
|
||||
"nullable": true,
|
||||
"maxLength": 255
|
||||
},
|
||||
"phone_country_code": {
|
||||
"type": "string",
|
||||
"description": "The country code for the customer phone number\nThis field will be deprecated soon, use the customer object instead",
|
||||
"example": "+1",
|
||||
"nullable": true,
|
||||
"maxLength": 255
|
||||
},
|
||||
"amount_to_capture": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "The Amount to be captured/ debited from the users payment method. It shall be in lowest denomination of the currency. (i.e) in cents for USD denomination, in paisa for INR denomination etc.,\nIf not provided, the default amount_to_capture will be the payment amount.",
|
||||
"example": 6540,
|
||||
"nullable": true
|
||||
},
|
||||
"udf": {
|
||||
"type": "object",
|
||||
"description": "Any user defined fields can be passed here.",
|
||||
"nullable": true
|
||||
},
|
||||
"setup_future_usage": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/FutureUsage"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"connector": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/Connector"
|
||||
},
|
||||
"description": "This allows the merchant to manually select a connector with which the payment can go through",
|
||||
"example": [
|
||||
"stripe",
|
||||
"adyen"
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"shipping": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/Address"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"phone": {
|
||||
"type": "string",
|
||||
"description": "The customer's phone number\nThis field will be deprecated soon, use the customer object instead",
|
||||
"example": "3141592653",
|
||||
"nullable": true,
|
||||
"maxLength": 255
|
||||
},
|
||||
"confirm": {
|
||||
"type": "boolean",
|
||||
"description": "Whether to confirm the payment (if applicable)",
|
||||
"default": false,
|
||||
"example": true,
|
||||
"nullable": true
|
||||
},
|
||||
"mandate_data": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/MandateData"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"statement_descriptor_name": {
|
||||
"type": "string",
|
||||
"description": "For non-card charges, you can use this value as the complete description that appears on your customers’ statements. Must contain at least one letter, maximum 22 characters.",
|
||||
"example": "Hyperswitch Router",
|
||||
"nullable": true,
|
||||
"maxLength": 255
|
||||
},
|
||||
"business_country": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/CountryAlpha2"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"business_label": {
|
||||
"type": "string",
|
||||
"description": "Business label of the merchant for this payment",
|
||||
"example": "food",
|
||||
"nullable": true
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "A description of the payment",
|
||||
"example": "It's my first payment request",
|
||||
"nullable": true
|
||||
},
|
||||
"client_secret": {
|
||||
"type": "string",
|
||||
"description": "It's a token used for client side verification.",
|
||||
"example": "pay_U42c409qyHwOkWo3vK60_secret_el9ksDkiB8hi6j9N78yo",
|
||||
"nullable": true
|
||||
},
|
||||
"payment_method_type": {
|
||||
"allOf": [
|
||||
{
|
||||
@ -6433,60 +6548,6 @@
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"customer": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/CustomerDetails"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"browser_info": {
|
||||
"type": "object",
|
||||
"description": "Additional details required by 3DS 2.0",
|
||||
"nullable": true
|
||||
},
|
||||
"manual_retry": {
|
||||
"type": "boolean",
|
||||
"description": "If enabled payment can be retried from the client side until the payment is successful or payment expires or the attempts(configured by the merchant) for payment are exhausted."
|
||||
},
|
||||
"return_url": {
|
||||
"type": "string",
|
||||
"description": "The URL to redirect after the completion of the operation",
|
||||
"example": "https://hyperswitch.io",
|
||||
"nullable": true
|
||||
},
|
||||
"mandate_id": {
|
||||
"type": "string",
|
||||
"description": "A unique identifier to link the payment to a mandate, can be use instead of payment_method_data",
|
||||
"example": "mandate_iwer89rnjef349dni3",
|
||||
"nullable": true,
|
||||
"maxLength": 255
|
||||
},
|
||||
"payment_id": {
|
||||
"type": "string",
|
||||
"description": "Unique identifier for the payment. This ensures idempotency for multiple payments\nthat have been done by a single merchant. This field is auto generated and is returned in the API response.",
|
||||
"example": "pay_mbabizu24mvu3mela5njyhpit4",
|
||||
"nullable": true,
|
||||
"maxLength": 30,
|
||||
"minLength": 30
|
||||
},
|
||||
"metadata": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/Metadata"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"capture_method": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/CaptureMethod"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "description: The customer's name\nThis field will be deprecated soon, use the customer object instead",
|
||||
@ -6494,23 +6555,46 @@
|
||||
"nullable": true,
|
||||
"maxLength": 255
|
||||
},
|
||||
"amount": {
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"description": "The payment amount. Amount for the payment in lowest denomination of the currency. (i.e) in cents for USD denomination, in paisa for INR denomination etc.,",
|
||||
"example": 6540,
|
||||
"nullable": true,
|
||||
"minimum": 0.0
|
||||
},
|
||||
"card_cvc": {
|
||||
"payment_id": {
|
||||
"type": "string",
|
||||
"description": "This is used when payment is to be confirmed and the card is not saved",
|
||||
"nullable": true
|
||||
"description": "Unique identifier for the payment. This ensures idempotency for multiple payments\nthat have been done by a single merchant. This field is auto generated and is returned in the API response.",
|
||||
"example": "pay_mbabizu24mvu3mela5njyhpit4",
|
||||
"nullable": true,
|
||||
"maxLength": 30,
|
||||
"minLength": 30
|
||||
},
|
||||
"merchant_connector_details": {
|
||||
"payment_method_data": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/MerchantConnectorDetailsWrap"
|
||||
"$ref": "#/components/schemas/PaymentMethodData"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"client_secret": {
|
||||
"type": "string",
|
||||
"description": "It's a token used for client side verification.",
|
||||
"example": "pay_U42c409qyHwOkWo3vK60_secret_el9ksDkiB8hi6j9N78yo",
|
||||
"nullable": true
|
||||
},
|
||||
"email": {
|
||||
"type": "string",
|
||||
"description": "The customer's email address\nThis field will be deprecated soon, use the customer object instead",
|
||||
"example": "johntest@test.com",
|
||||
"nullable": true,
|
||||
"maxLength": 255
|
||||
},
|
||||
"mandate_id": {
|
||||
"type": "string",
|
||||
"description": "A unique identifier to link the payment to a mandate, can be use instead of payment_method_data",
|
||||
"example": "mandate_iwer89rnjef349dni3",
|
||||
"nullable": true,
|
||||
"maxLength": 255
|
||||
},
|
||||
"business_country": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/CountryAlpha2"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
@ -6522,35 +6606,46 @@
|
||||
"nullable": true,
|
||||
"maxLength": 255
|
||||
},
|
||||
"currency": {
|
||||
"metadata": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/Currency"
|
||||
"$ref": "#/components/schemas/Metadata"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"description": {
|
||||
"type": "string",
|
||||
"description": "A description of the payment",
|
||||
"example": "It's my first payment request",
|
||||
"nullable": true
|
||||
},
|
||||
"payment_token": {
|
||||
"type": "string",
|
||||
"description": "Provide a reference to a stored payment method",
|
||||
"example": "187282ab-40ef-47a9-9206-5099ba31e432",
|
||||
"nullable": true
|
||||
},
|
||||
"capture_on": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "A timestamp (ISO 8601 code) that determines when the payment should be captured.\nProviding this field will automatically set `capture` to true",
|
||||
"example": "2022-09-10T10:11:12Z",
|
||||
"nullable": true
|
||||
},
|
||||
"authentication_type": {
|
||||
"merchant_connector_details": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/AuthenticationType"
|
||||
"$ref": "#/components/schemas/MerchantConnectorDetailsWrap"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"udf": {
|
||||
"type": "object",
|
||||
"description": "Any user defined fields can be passed here.",
|
||||
"nullable": true
|
||||
},
|
||||
"phone_country_code": {
|
||||
"type": "string",
|
||||
"description": "The country code for the customer phone number\nThis field will be deprecated soon, use the customer object instead",
|
||||
"example": "+1",
|
||||
"nullable": true,
|
||||
"maxLength": 255
|
||||
},
|
||||
"statement_descriptor_suffix": {
|
||||
"type": "string",
|
||||
"description": "Provides information about a card payment that customers see on their statements. Concatenated with the prefix (shortened descriptor) or statement descriptor that’s set on the account to form the complete statement descriptor. Maximum 22 characters for the concatenated descriptor.",
|
||||
@ -6558,57 +6653,12 @@
|
||||
"nullable": true,
|
||||
"maxLength": 255
|
||||
},
|
||||
"order_details": {
|
||||
"allowed_payment_method_types": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/OrderDetailsWithAmount"
|
||||
"$ref": "#/components/schemas/PaymentMethodType"
|
||||
},
|
||||
"description": "Information about the product , quantity and amount for connectors. (e.g. Klarna)",
|
||||
"example": "[{\n \"product_name\": \"gillete creme\",\n \"quantity\": 15,\n \"amount\" : 900\n }]",
|
||||
"nullable": true
|
||||
},
|
||||
"business_sub_label": {
|
||||
"type": "string",
|
||||
"description": "Business sub label for the payment",
|
||||
"nullable": true
|
||||
},
|
||||
"email": {
|
||||
"type": "string",
|
||||
"description": "The customer's email address\nThis field will be deprecated soon, use the customer object instead",
|
||||
"example": "johntest@test.com",
|
||||
"nullable": true,
|
||||
"maxLength": 255
|
||||
},
|
||||
"payment_method": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/PaymentMethod"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"routing": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/RoutingAlgorithm"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"billing": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/Address"
|
||||
}
|
||||
],
|
||||
"nullable": true
|
||||
},
|
||||
"payment_method_data": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/PaymentMethodData"
|
||||
}
|
||||
],
|
||||
"description": "Allowed Payment Method Types for a given PaymentIntent",
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
@ -8154,6 +8204,17 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"google_pay_third_party_sdk"
|
||||
],
|
||||
"properties": {
|
||||
"google_pay_third_party_sdk": {
|
||||
"$ref": "#/components/schemas/GooglePayThirdPartySdkData"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
||||
Reference in New Issue
Block a user