Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(connector): [Iatapay] add upi qr support #4728

Merged
merged 21 commits into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 {
Comment on lines +292 to +299
Copy link
Member

@Narayanbhat166 Narayanbhat166 May 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have changed a struct to enum, is this change backwards compatible? If this breaks existing api contract then this change cannot be made.

Copy link
Contributor Author

@AkshayaFoiger AkshayaFoiger May 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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,
}
}
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
Loading