mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-02 21:07:58 +08:00
feat: api contract change for wallet (#628)
This commit is contained in:
committed by
GitHub
parent
060c54193e
commit
ff86417eee
@ -78,7 +78,7 @@ impl TryFrom<refunds::RefundResponse> for StripeCreateRefundResponse {
|
||||
payment_intent: res.payment_id,
|
||||
status: res.status.into(),
|
||||
created: res.created_at.map(|t| t.assume_utc().unix_timestamp()),
|
||||
metadata: res.metadata.unwrap_or(serde_json::json!({})),
|
||||
metadata: res.metadata.unwrap_or_else(|| serde_json::json!({})),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,18 +1,16 @@
|
||||
use base64::Engine;
|
||||
use error_stack::ResultExt;
|
||||
use masking::PeekInterface;
|
||||
use reqwest::Url;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
connector::utils::{self, PaymentsRequestData},
|
||||
connector::utils::PaymentsRequestData,
|
||||
consts,
|
||||
core::errors,
|
||||
pii::{self, Email, Secret},
|
||||
services,
|
||||
types::{
|
||||
self,
|
||||
api::{self, enums as api_enums},
|
||||
storage::enums as storage_enums,
|
||||
},
|
||||
types::{self, api, storage::enums as storage_enums},
|
||||
};
|
||||
|
||||
// Adyen Types Definition
|
||||
@ -339,7 +337,6 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for AdyenPaymentRequest {
|
||||
get_paylater_specific_payment_data(item)
|
||||
}
|
||||
storage_models::enums::PaymentMethod::Wallet => get_wallet_specific_payment_data(item),
|
||||
_ => Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -480,29 +477,34 @@ fn get_payment_method_data(
|
||||
};
|
||||
Ok(AdyenPaymentMethod::AdyenCard(adyen_card))
|
||||
}
|
||||
api::PaymentMethodData::Wallet(ref wallet_data) => match wallet_data.issuer_name {
|
||||
api_enums::WalletIssuer::GooglePay => {
|
||||
api::PaymentMethodData::Wallet(ref wallet_data) => match wallet_data {
|
||||
api_models::payments::WalletData::GooglePay(data) => {
|
||||
let gpay_data = AdyenGPay {
|
||||
payment_type: PaymentType::Googlepay,
|
||||
google_pay_token: wallet_data
|
||||
.token
|
||||
.clone()
|
||||
.ok_or_else(utils::missing_field_err("token"))?,
|
||||
google_pay_token: data.tokenization_data.token.to_owned(),
|
||||
};
|
||||
Ok(AdyenPaymentMethod::Gpay(gpay_data))
|
||||
}
|
||||
|
||||
api_enums::WalletIssuer::ApplePay => {
|
||||
api_models::payments::WalletData::ApplePay(data) => {
|
||||
let apple_pay_data = AdyenApplePay {
|
||||
payment_type: PaymentType::Applepay,
|
||||
apple_pay_token: wallet_data
|
||||
.token
|
||||
.clone()
|
||||
.ok_or_else(utils::missing_field_err("token"))?,
|
||||
apple_pay_token:
|
||||
consts::BASE64_ENGINE.encode(
|
||||
common_utils::ext_traits::Encode::<
|
||||
api_models::payments::ApplepayPaymentData,
|
||||
>::encode_to_string_of_json(
|
||||
&data.payment_data
|
||||
)
|
||||
.change_context(errors::ConnectorError::RequestEncodingFailed)?,
|
||||
),
|
||||
};
|
||||
|
||||
Ok(AdyenPaymentMethod::ApplePay(apple_pay_data))
|
||||
}
|
||||
api_enums::WalletIssuer::Paypal => {
|
||||
api_models::payments::WalletData::PaypalSdk(_) => {
|
||||
Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into())
|
||||
}
|
||||
api_models::payments::WalletData::PaypalRedirect(_) => {
|
||||
let wallet = AdyenPaypal {
|
||||
payment_type: PaymentType::Paypal,
|
||||
};
|
||||
|
||||
@ -171,7 +171,7 @@ impl<F>
|
||||
Ok(Self {
|
||||
response: Ok(types::PaymentsResponseData::SessionResponse {
|
||||
session_token: {
|
||||
api_models::payments::SessionToken::Applepay(Box::new(
|
||||
api_models::payments::SessionToken::ApplePay(Box::new(
|
||||
payments::ApplepaySessionTokenResponse {
|
||||
session_token_data: applepay_session.into(),
|
||||
payment_request_data: payment_request.into(),
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
use api_models::payments;
|
||||
use base64::Engine;
|
||||
use error_stack::ResultExt;
|
||||
use masking::Secret;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@ -8,7 +7,6 @@ use crate::{
|
||||
consts,
|
||||
core::errors,
|
||||
types::{self, api, storage::enums},
|
||||
utils::OptionExt,
|
||||
};
|
||||
|
||||
#[derive(Default, Debug, Serialize, Eq, PartialEq)]
|
||||
@ -111,12 +109,12 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for BraintreePaymentsRequest {
|
||||
})),
|
||||
api::PaymentMethodData::Wallet(ref wallet_data) => {
|
||||
Ok(PaymentMethodType::PaymentMethodNonce(Nonce {
|
||||
payment_method_nonce: wallet_data
|
||||
.token
|
||||
.to_owned()
|
||||
.get_required_value("token")
|
||||
.change_context(errors::ConnectorError::RequestEncodingFailed)
|
||||
.attach_printable("No token passed")?,
|
||||
payment_method_nonce: match wallet_data {
|
||||
api_models::payments::WalletData::PaypalSdk(wallet_data) => {
|
||||
Ok(wallet_data.token.to_owned())
|
||||
}
|
||||
_ => Err(errors::ConnectorError::InvalidWallet),
|
||||
}?,
|
||||
}))
|
||||
}
|
||||
_ => Err(errors::ConnectorError::NotImplemented(format!(
|
||||
|
||||
@ -8,7 +8,6 @@ use crate::{
|
||||
core::errors,
|
||||
pii::{self, Secret},
|
||||
types::{self, api, storage::enums},
|
||||
utils::OptionExt,
|
||||
};
|
||||
|
||||
const WALLET_IDENTIFIER: &str = "PBL";
|
||||
@ -78,33 +77,29 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PayuPaymentsRequest {
|
||||
cvv: ccard.card_cvc,
|
||||
}),
|
||||
}),
|
||||
api::PaymentMethodData::Wallet(wallet_data) => match wallet_data.issuer_name {
|
||||
api_models::enums::WalletIssuer::GooglePay => Ok(PayuPaymentMethod {
|
||||
api::PaymentMethodData::Wallet(wallet_data) => match wallet_data {
|
||||
api_models::payments::WalletData::GooglePay(data) => Ok(PayuPaymentMethod {
|
||||
pay_method: PayuPaymentMethodData::Wallet({
|
||||
PayuWallet {
|
||||
value: PayuWalletCode::Ap,
|
||||
wallet_type: WALLET_IDENTIFIER.to_string(),
|
||||
authorization_code: consts::BASE64_ENGINE.encode(
|
||||
wallet_data
|
||||
.token
|
||||
.get_required_value("token")
|
||||
.change_context(errors::ConnectorError::RequestEncodingFailed)
|
||||
.attach_printable("No token passed")?,
|
||||
),
|
||||
authorization_code: consts::BASE64_ENGINE
|
||||
.encode(data.tokenization_data.token),
|
||||
}
|
||||
}),
|
||||
}),
|
||||
api_models::enums::WalletIssuer::ApplePay => Ok(PayuPaymentMethod {
|
||||
api_models::payments::WalletData::ApplePay(data) => Ok(PayuPaymentMethod {
|
||||
pay_method: PayuPaymentMethodData::Wallet({
|
||||
PayuWallet {
|
||||
value: PayuWalletCode::Jp,
|
||||
wallet_type: WALLET_IDENTIFIER.to_string(),
|
||||
authorization_code: consts::BASE64_ENGINE.encode(
|
||||
wallet_data
|
||||
.token
|
||||
.get_required_value("token")
|
||||
.change_context(errors::ConnectorError::RequestEncodingFailed)
|
||||
.attach_printable("No token passed")?,
|
||||
common_utils::ext_traits::Encode::<
|
||||
api_models::payments::ApplepayPaymentData,
|
||||
>::encode_to_string_of_json(
|
||||
&data.payment_data
|
||||
)
|
||||
.change_context(errors::ConnectorError::RequestEncodingFailed)?,
|
||||
),
|
||||
}
|
||||
}),
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
use base64::Engine;
|
||||
use error_stack::{IntoReport, ResultExt};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
@ -66,7 +67,7 @@ pub struct RapydWallet {
|
||||
#[serde(rename = "type")]
|
||||
payment_type: String,
|
||||
#[serde(rename = "details")]
|
||||
apple_pay_token: Option<String>,
|
||||
token: Option<String>,
|
||||
}
|
||||
|
||||
impl TryFrom<&types::PaymentsAuthorizeRouterData> for RapydPaymentsRequest {
|
||||
@ -104,14 +105,23 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for RapydPaymentsRequest {
|
||||
})
|
||||
}
|
||||
api_models::payments::PaymentMethodData::Wallet(ref wallet_data) => {
|
||||
let digital_wallet = match wallet_data.issuer_name {
|
||||
api_models::enums::WalletIssuer::GooglePay => Some(RapydWallet {
|
||||
let digital_wallet = match wallet_data {
|
||||
api_models::payments::WalletData::GooglePay(data) => Some(RapydWallet {
|
||||
payment_type: "google_pay".to_string(),
|
||||
apple_pay_token: wallet_data.token.to_owned(),
|
||||
token: Some(data.tokenization_data.token.to_owned()),
|
||||
}),
|
||||
api_models::enums::WalletIssuer::ApplePay => Some(RapydWallet {
|
||||
api_models::payments::WalletData::ApplePay(data) => Some(RapydWallet {
|
||||
payment_type: "apple_pay".to_string(),
|
||||
apple_pay_token: wallet_data.token.to_owned(),
|
||||
token: Some(
|
||||
consts::BASE64_ENGINE.encode(
|
||||
common_utils::ext_traits::Encode::<
|
||||
api_models::payments::ApplepayPaymentData,
|
||||
>::encode_to_string_of_json(
|
||||
&data.payment_data
|
||||
)
|
||||
.change_context(errors::ConnectorError::RequestEncodingFailed)?,
|
||||
),
|
||||
),
|
||||
}),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
use base64::Engine;
|
||||
use common_utils::errors::CustomResult;
|
||||
use error_stack::ResultExt;
|
||||
use storage_models::enums;
|
||||
|
||||
use super::{requests::*, response::*};
|
||||
use crate::{
|
||||
consts,
|
||||
core::errors,
|
||||
types::{self, api},
|
||||
utils::OptionExt,
|
||||
};
|
||||
|
||||
fn fetch_payment_instrument(
|
||||
@ -21,26 +22,27 @@ fn fetch_payment_instrument(
|
||||
card_number: card.card_number,
|
||||
..CardPayment::default()
|
||||
})),
|
||||
api::PaymentMethodData::Wallet(wallet) => match wallet.issuer_name {
|
||||
api_models::enums::WalletIssuer::ApplePay => {
|
||||
Ok(PaymentInstrument::Applepay(WalletPayment {
|
||||
payment_type: PaymentType::Applepay,
|
||||
wallet_token: wallet
|
||||
.token
|
||||
.get_required_value("token")
|
||||
.change_context(errors::ConnectorError::RequestEncodingFailed)
|
||||
.attach_printable("No token passed")?,
|
||||
api::PaymentMethodData::Wallet(wallet) => match wallet {
|
||||
api_models::payments::WalletData::GooglePay(data) => {
|
||||
Ok(PaymentInstrument::Googlepay(WalletPayment {
|
||||
payment_type: PaymentType::Googlepay,
|
||||
wallet_token: data.tokenization_data.token,
|
||||
..WalletPayment::default()
|
||||
}))
|
||||
}
|
||||
api_models::enums::WalletIssuer::GooglePay => {
|
||||
Ok(PaymentInstrument::Googlepay(WalletPayment {
|
||||
payment_type: PaymentType::Googlepay,
|
||||
wallet_token: wallet
|
||||
.token
|
||||
.get_required_value("token")
|
||||
.change_context(errors::ConnectorError::RequestEncodingFailed)
|
||||
.attach_printable("No token passed")?,
|
||||
api_models::payments::WalletData::ApplePay(data) => {
|
||||
Ok(PaymentInstrument::Applepay(WalletPayment {
|
||||
payment_type: PaymentType::Applepay,
|
||||
|
||||
wallet_token:
|
||||
consts::BASE64_ENGINE.encode(
|
||||
common_utils::ext_traits::Encode::<
|
||||
api_models::payments::ApplepayPaymentData,
|
||||
>::encode_to_string_of_json(
|
||||
&data.payment_data
|
||||
)
|
||||
.change_context(errors::ConnectorError::RequestEncodingFailed)?,
|
||||
),
|
||||
..WalletPayment::default()
|
||||
}))
|
||||
}
|
||||
|
||||
@ -234,6 +234,8 @@ pub enum ConnectorError {
|
||||
FailedToObtainPreferredConnector,
|
||||
#[error("An invalid connector name was provided")]
|
||||
InvalidConnectorName,
|
||||
#[error("An invalid Wallet was used")]
|
||||
InvalidWallet,
|
||||
#[error("Failed to handle connector response")]
|
||||
ResponseHandlingFailed,
|
||||
#[error("Missing required field: {field_name}")]
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use common_utils::generate_id_with_default_len;
|
||||
use error_stack::{IntoReport, ResultExt};
|
||||
use masking::PeekInterface;
|
||||
@ -103,8 +101,7 @@ impl Vaultable for api::Card {
|
||||
impl Vaultable for api::WalletData {
|
||||
fn get_value1(&self, _customer_id: Option<String>) -> CustomResult<String, errors::VaultError> {
|
||||
let value1 = api::TokenizedWalletValue1 {
|
||||
issuer: self.issuer_name.to_string(),
|
||||
token: self.token.clone(),
|
||||
data: self.to_owned(),
|
||||
};
|
||||
|
||||
utils::Encode::<api::TokenizedWalletValue1>::encode_to_string_of_json(&value1)
|
||||
@ -134,13 +131,7 @@ impl Vaultable for api::WalletData {
|
||||
.change_context(errors::VaultError::ResponseDeserializationFailed)
|
||||
.attach_printable("Could not deserialize into wallet data value2")?;
|
||||
|
||||
let wallet = Self {
|
||||
issuer_name: api::enums::WalletIssuer::from_str(&value1.issuer)
|
||||
.into_report()
|
||||
.change_context(errors::VaultError::ResponseDeserializationFailed)
|
||||
.attach_printable("Invalid issuer name when deserializing wallet data")?,
|
||||
token: value1.token,
|
||||
};
|
||||
let wallet = value1.data;
|
||||
|
||||
let supp_data = SupplementaryVaultData {
|
||||
customer_id: value2.customer_id,
|
||||
|
||||
@ -91,7 +91,7 @@ fn create_gpay_session_token(
|
||||
|
||||
let response_router_data = types::PaymentsSessionRouterData {
|
||||
response: Ok(types::PaymentsResponseData::SessionResponse {
|
||||
session_token: payment_types::SessionToken::Gpay(Box::new(
|
||||
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,
|
||||
|
||||
@ -721,18 +721,19 @@ pub async fn make_pm_data<'a, F: Clone, R>(
|
||||
payment_data.payment_attempt.payment_method =
|
||||
Some(storage_enums::PaymentMethod::Wallet);
|
||||
// TODO: Remove redundant update from wallets.
|
||||
if wallet_data.token.is_some() {
|
||||
let updated_pm = api::PaymentMethodData::Wallet(wallet_data);
|
||||
vault::Vault::store_payment_method_data_in_locker(
|
||||
state,
|
||||
Some(token),
|
||||
&updated_pm,
|
||||
payment_data.payment_intent.customer_id.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
Some(updated_pm)
|
||||
} else {
|
||||
pm
|
||||
match wallet_data {
|
||||
api_models::payments::WalletData::PaypalRedirect(_) => pm,
|
||||
_ => {
|
||||
let updated_pm = api::PaymentMethodData::Wallet(wallet_data);
|
||||
vault::Vault::store_payment_method_data_in_locker(
|
||||
state,
|
||||
Some(token),
|
||||
&updated_pm,
|
||||
payment_data.payment_intent.customer_id.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
Some(updated_pm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -124,6 +124,8 @@ Never share your secret api keys. Keep them guarded and secure.
|
||||
crate::types::api::payment_methods::CardDetailFromLocker,
|
||||
crate::types::api::payment_methods::CardDetail,
|
||||
api_models::customers::CustomerResponse,
|
||||
api_models::admin::AcceptedCountries,
|
||||
api_models::admin::AcceptedCurrencies,
|
||||
api_models::enums::RoutingAlgorithm,
|
||||
api_models::enums::PaymentMethod,
|
||||
api_models::enums::PaymentMethodType,
|
||||
@ -133,17 +135,19 @@ Never share your secret api keys. Keep them guarded and secure.
|
||||
api_models::enums::CaptureMethod,
|
||||
api_models::enums::FutureUsage,
|
||||
api_models::enums::AuthenticationType,
|
||||
api_models::enums::WalletIssuer,
|
||||
api_models::enums::Connector,
|
||||
api_models::enums::PaymentMethod,
|
||||
api_models::enums::SupportedWallets,
|
||||
api_models::enums::PaymentMethodIssuerCode,
|
||||
api_models::enums::MandateStatus,
|
||||
api_models::enums::PaymentExperience,
|
||||
api_models::enums::BankNames,
|
||||
api_models::admin::PaymentConnectorCreate,
|
||||
api_models::admin::PaymentMethodsEnabled,
|
||||
api_models::payments::AddressDetails,
|
||||
api_models::payments::Address,
|
||||
api_models::payments::BankRedirectData,
|
||||
api_models::payments::BankRedirectBilling,
|
||||
api_models::payments::OrderDetails,
|
||||
api_models::payments::NextActionType,
|
||||
api_models::payments::Metadata,
|
||||
@ -172,6 +176,9 @@ Never share your secret api keys. Keep them guarded and secure.
|
||||
api_models::payments::ApplePaySessionResponse,
|
||||
api_models::payments::ApplePayPaymentRequest,
|
||||
api_models::payments::AmountInfo,
|
||||
api_models::payments::GpayWalletData,
|
||||
api_models::payments::PayPalWalletData,
|
||||
api_models::payments::PaypalRedirection,
|
||||
api_models::payments::GpayMerchantInfo,
|
||||
api_models::payments::GpayAllowedPaymentMethods,
|
||||
api_models::payments::GpayAllowedMethodsParameters,
|
||||
@ -182,6 +189,12 @@ Never share your secret api keys. Keep them guarded and secure.
|
||||
api_models::payments::KlarnaSessionTokenResponse,
|
||||
api_models::payments::PaypalSessionTokenResponse,
|
||||
api_models::payments::ApplepaySessionTokenResponse,
|
||||
api_models::payments::GpayTokenizationData,
|
||||
api_models::payments::GpayPaymentMethodInfo,
|
||||
api_models::payments::ApplePayWalletData,
|
||||
api_models::payments::ApplepayPaymentData,
|
||||
api_models::payments::ApplepayHeader,
|
||||
api_models::payments::ApplepayPaymentMethod,
|
||||
api_models::payments::PaymentsCancelRequest,
|
||||
api_models::payments::PaymentListConstraints,
|
||||
api_models::payments::PaymentListResponse,
|
||||
|
||||
Reference in New Issue
Block a user