Skip to content

Commit

Permalink
feat(connector): [Iatapay] add upi qr support (#4728)
Browse files Browse the repository at this point in the history
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
Co-authored-by: SamraatBansal <[email protected]>
  • Loading branch information
3 people authored May 28, 2024
1 parent d15cb31 commit c9fa94f
Show file tree
Hide file tree
Showing 22 changed files with 257 additions and 65 deletions.
27 changes: 25 additions & 2 deletions crates/api_models/src/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1664,7 +1664,10 @@ impl GetPaymentMethodType for CryptoData {

impl GetPaymentMethodType for UpiData {
fn get_payment_method_type(&self) -> api_enums::PaymentMethodType {
api_enums::PaymentMethodType::UpiCollect
match self {
Self::UpiCollect(_) => api_enums::PaymentMethodType::UpiCollect,
Self::UpiIntent(_) => api_enums::PaymentMethodType::UpiIntent,
}
}
}
impl GetPaymentMethodType for VoucherData {
Expand Down Expand Up @@ -2119,11 +2122,21 @@ pub struct CryptoData {

#[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub struct UpiData {
pub enum UpiData {
UpiCollect(UpiCollectData),
UpiIntent(UpiIntentData),
}

#[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub struct UpiCollectData {
#[schema(value_type = Option<String>, example = "successtest@iata")]
pub vpa_id: Option<Secret<String, pii::UpiVpaMaskingStrategy>>,
}

#[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize, ToSchema)]
pub struct UpiIntentData {}

#[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize, ToSchema)]
pub struct SofortBilling {
/// The country associated with the billing
Expand Down Expand Up @@ -2960,6 +2973,11 @@ pub enum NextActionData {
/// The url for Qr code given by the connector
qr_code_url: Option<Url>,
},
/// Contains url to fetch Qr code data
FetchQrCodeInformation {
#[schema(value_type = String)]
qr_code_fetch_url: Url,
},
/// Contains the download url and the reference number for transaction
DisplayVoucherInformation {
#[schema(value_type = String)]
Expand Down Expand Up @@ -3045,6 +3063,11 @@ pub struct SdkNextActionData {
pub next_action: NextActionCall,
}

#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)]
pub struct FetchQrCodeInformation {
pub qr_code_fetch_url: Url,
}

#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)]
pub struct BankTransferNextStepsData {
/// The instructions for performing a bank transfer
Expand Down
1 change: 1 addition & 0 deletions crates/common_enums/src/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1430,6 +1430,7 @@ pub enum PaymentMethodType {
Trustly,
Twint,
UpiCollect,
UpiIntent,
Vipps,
Venmo,
Walley,
Expand Down
1 change: 1 addition & 0 deletions crates/common_enums/src/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1854,6 +1854,7 @@ impl From<PaymentMethodType> for PaymentMethod {
PaymentMethodType::Trustly => Self::BankRedirect,
PaymentMethodType::Twint => Self::Wallet,
PaymentMethodType::UpiCollect => Self::Upi,
PaymentMethodType::UpiIntent => Self::Upi,
PaymentMethodType::Vipps => Self::Wallet,
PaymentMethodType::Venmo => Self::Wallet,
PaymentMethodType::Walley => Self::PayLater,
Expand Down
1 change: 1 addition & 0 deletions crates/euclid/src/frontend/dir/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ pub enum CryptoType {
#[strum(serialize_all = "snake_case")]
pub enum UpiType {
UpiCollect,
UpiIntent,
}

#[derive(
Expand Down
1 change: 1 addition & 0 deletions crates/euclid/src/frontend/dir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ impl From<enums::UpiType> for global_enums::PaymentMethodType {
fn from(value: enums::UpiType) -> Self {
match value {
enums::UpiType::UpiCollect => Self::UpiCollect,
enums::UpiType::UpiIntent => Self::UpiIntent,
}
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/euclid/src/frontend/dir/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ impl IntoDirValue for (global_enums::PaymentMethodType, global_enums::PaymentMet
}
global_enums::PaymentMethodType::Evoucher => Ok(dirval!(RewardType = Evoucher)),
global_enums::PaymentMethodType::UpiCollect => Ok(dirval!(UpiType = UpiCollect)),
global_enums::PaymentMethodType::UpiIntent => Ok(dirval!(UpiType = UpiIntent)),
global_enums::PaymentMethodType::SamsungPay => Ok(dirval!(WalletType = SamsungPay)),
global_enums::PaymentMethodType::GoPay => Ok(dirval!(WalletType = GoPay)),
global_enums::PaymentMethodType::KakaoPay => Ok(dirval!(WalletType = KakaoPay)),
Expand Down
20 changes: 17 additions & 3 deletions crates/hyperswitch_domain_models/src/payment_method_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,10 +289,20 @@ pub struct CryptoData {

#[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "snake_case")]
pub struct UpiData {
pub enum UpiData {
UpiCollect(UpiCollectData),
UpiIntent(UpiIntentData),
}

#[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "snake_case")]
pub struct UpiCollectData {
pub vpa_id: Option<Secret<String, pii::UpiVpaMaskingStrategy>>,
}

#[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct UpiIntentData {}

#[derive(Debug, Clone, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum VoucherData {
Expand Down Expand Up @@ -690,8 +700,12 @@ impl From<api_models::payments::CryptoData> for CryptoData {

impl From<api_models::payments::UpiData> for UpiData {
fn from(value: api_models::payments::UpiData) -> Self {
let api_models::payments::UpiData { vpa_id } = value;
Self { vpa_id }
match value {
api_models::payments::UpiData::UpiCollect(upi) => {
Self::UpiCollect(UpiCollectData { vpa_id: upi.vpa_id })
}
api_models::payments::UpiData::UpiIntent(_) => Self::UpiIntent(UpiIntentData {}),
}
}
}

Expand Down
3 changes: 2 additions & 1 deletion crates/kgraph_utils/src/mca.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ fn get_dir_value_payment_method(

api_enums::PaymentMethodType::ClassicReward => Ok(dirval!(RewardType = ClassicReward)),
api_enums::PaymentMethodType::Evoucher => Ok(dirval!(RewardType = Evoucher)),
api_enums::PaymentMethodType::UpiCollect => Ok(dirval!(UpiType = UpiCollect)),
api_enums::PaymentMethodType::SamsungPay => Ok(dirval!(WalletType = SamsungPay)),
api_enums::PaymentMethodType::GoPay => Ok(dirval!(WalletType = GoPay)),
api_enums::PaymentMethodType::KakaoPay => Ok(dirval!(WalletType = KakaoPay)),
Expand Down Expand Up @@ -133,6 +132,8 @@ fn get_dir_value_payment_method(
api_enums::PaymentMethodType::Oxxo => Ok(dirval!(VoucherType = Oxxo)),
api_enums::PaymentMethodType::CardRedirect => Ok(dirval!(CardRedirectType = CardRedirect)),
api_enums::PaymentMethodType::Venmo => Ok(dirval!(WalletType = Venmo)),
api_enums::PaymentMethodType::UpiIntent => Ok(dirval!(UpiType = UpiIntent)),
api_enums::PaymentMethodType::UpiCollect => Ok(dirval!(UpiType = UpiCollect)),
}
}

Expand Down
1 change: 1 addition & 0 deletions crates/kgraph_utils/src/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ impl IntoDirValue for (api_enums::PaymentMethodType, api_enums::PaymentMethod) {
api_enums::PaymentMethodType::ClassicReward => Ok(dirval!(RewardType = ClassicReward)),
api_enums::PaymentMethodType::Evoucher => Ok(dirval!(RewardType = Evoucher)),
api_enums::PaymentMethodType::UpiCollect => Ok(dirval!(UpiType = UpiCollect)),
api_enums::PaymentMethodType::UpiIntent => Ok(dirval!(UpiType = UpiIntent)),
api_enums::PaymentMethodType::SamsungPay => Ok(dirval!(WalletType = SamsungPay)),
api_enums::PaymentMethodType::GoPay => Ok(dirval!(WalletType = GoPay)),
api_enums::PaymentMethodType::KakaoPay => Ok(dirval!(WalletType = KakaoPay)),
Expand Down
2 changes: 2 additions & 0 deletions crates/openapi/src/openapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,8 @@ Never share your secret api keys. Keep them guarded and secure.
api_models::payments::CryptoData,
api_models::payments::RewardData,
api_models::payments::UpiData,
api_models::payments::UpiCollectData,
api_models::payments::UpiIntentData,
api_models::payments::VoucherData,
api_models::payments::BoletoVoucherData,
api_models::payments::AlfamartVoucherData,
Expand Down
49 changes: 35 additions & 14 deletions crates/router/src/compatibility/stripe/payment_intents/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,10 @@ impl From<StripeWallet> for payments::WalletData {
}

impl From<StripeUpi> for payments::UpiData {
fn from(upi: StripeUpi) -> Self {
Self {
vpa_id: Some(upi.vpa_id),
}
fn from(upi_data: StripeUpi) -> Self {
Self::UpiCollect(payments::UpiCollectData {
vpa_id: Some(upi_data.vpa_id),
})
}
}

Expand Down Expand Up @@ -315,6 +315,18 @@ impl TryFrom<StripePaymentIntentRequest> for payments::PaymentsRequest {

let amount = item.amount.map(|amount| MinorUnit::new(amount).into());

let payment_method_data = item.payment_method_data.as_ref().map(|pmd| {
let payment_method_data = match pmd.payment_method_details.as_ref() {
Some(spmd) => Some(payments::PaymentMethodData::from(spmd.to_owned())),
None => get_pmd_based_on_payment_method_type(item.payment_method_types),
};

payments::PaymentMethodDataRequest {
payment_method_data,
billing: pmd.billing_details.clone().map(payments::Address::from),
}
});

let request = Ok(Self {
payment_id: item.id.map(payments::PaymentIdType::PaymentIntentId),
amount,
Expand All @@ -334,16 +346,7 @@ impl TryFrom<StripePaymentIntentRequest> for payments::PaymentsRequest {
phone: item.shipping.as_ref().and_then(|s| s.phone.clone()),
description: item.description,
return_url: item.return_url,
payment_method_data: item.payment_method_data.as_ref().and_then(|pmd| {
pmd.payment_method_details
.as_ref()
.map(|spmd| payments::PaymentMethodDataRequest {
payment_method_data: Some(payments::PaymentMethodData::from(
spmd.to_owned(),
)),
billing: pmd.billing_details.clone().map(payments::Address::from),
})
}),
payment_method_data,
payment_method: item
.payment_method_data
.as_ref()
Expand Down Expand Up @@ -816,6 +819,9 @@ pub enum StripeNextAction {
display_to_timestamp: Option<i64>,
qr_code_url: Option<url::Url>,
},
FetchQrCodeInformation {
qr_code_fetch_url: url::Url,
},
DisplayVoucherInformation {
voucher_details: payments::VoucherNextStepData,
},
Expand Down Expand Up @@ -858,6 +864,9 @@ pub(crate) fn into_stripe_next_action(
display_to_timestamp,
qr_code_url,
},
payments::NextActionData::FetchQrCodeInformation { qr_code_fetch_url } => {
StripeNextAction::FetchQrCodeInformation { qr_code_fetch_url }
}
payments::NextActionData::DisplayVoucherInformation { voucher_details } => {
StripeNextAction::DisplayVoucherInformation { voucher_details }
}
Expand All @@ -884,3 +893,15 @@ pub(crate) fn into_stripe_next_action(
pub struct StripePaymentRetrieveBody {
pub client_secret: Option<String>,
}

//To handle payment types that have empty payment method data
fn get_pmd_based_on_payment_method_type(
payment_method_type: Option<api_enums::PaymentMethodType>,
) -> Option<payments::PaymentMethodData> {
match payment_method_type {
Some(api_enums::PaymentMethodType::UpiIntent) => Some(payments::PaymentMethodData::Upi(
payments::UpiData::UpiIntent(payments::UpiIntentData {}),
)),
_ => None,
}
}
6 changes: 6 additions & 0 deletions crates/router/src/compatibility/stripe/setup_intents/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,9 @@ pub enum StripeNextAction {
display_to_timestamp: Option<i64>,
qr_code_url: Option<url::Url>,
},
FetchQrCodeInformation {
qr_code_fetch_url: url::Url,
},
DisplayVoucherInformation {
voucher_details: payments::VoucherNextStepData,
},
Expand Down Expand Up @@ -424,6 +427,9 @@ pub(crate) fn into_stripe_next_action(
display_to_timestamp,
qr_code_url,
},
payments::NextActionData::FetchQrCodeInformation { qr_code_fetch_url } => {
StripeNextAction::FetchQrCodeInformation { qr_code_fetch_url }
}
payments::NextActionData::DisplayVoucherInformation { voucher_details } => {
StripeNextAction::DisplayVoucherInformation { voucher_details }
}
Expand Down
3 changes: 2 additions & 1 deletion crates/router/src/connector/adyen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,8 @@ impl ConnectorValidation for Adyen {
| PaymentMethodType::SamsungPay
| PaymentMethodType::Evoucher
| PaymentMethodType::Cashapp
| PaymentMethodType::UpiCollect => {
| PaymentMethodType::UpiCollect
| PaymentMethodType::UpiIntent => {
capture_method_not_supported!(connector, capture_method, payment_method_type)
}
},
Expand Down
Loading

0 comments on commit c9fa94f

Please sign in to comment.