mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-28 04:04:55 +08:00
refactor(core): add recurring customer support for nomupay payouts. (#6687)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@ -243,7 +243,8 @@ pub struct PaymentMethodMigrate {
|
||||
pub billing: Option<payments::Address>,
|
||||
|
||||
/// The connector mandate details of the payment method
|
||||
pub connector_mandate_details: Option<PaymentsMandateReference>,
|
||||
#[serde(deserialize_with = "deserialize_connector_mandate_details")]
|
||||
pub connector_mandate_details: Option<CommonMandateReference>,
|
||||
|
||||
// The CIT (customer initiated transaction) transaction id associated with the payment method
|
||||
pub network_transaction_id: Option<String>,
|
||||
@ -267,12 +268,22 @@ pub struct PaymentMethodMigrateResponse {
|
||||
pub network_transaction_id_migrated: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct PaymentsMandateReference(
|
||||
pub HashMap<id_type::MerchantConnectorAccountId, PaymentsMandateReferenceRecord>,
|
||||
);
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub struct PayoutsMandateReference(
|
||||
pub HashMap<id_type::MerchantConnectorAccountId, PayoutsMandateReferenceRecord>,
|
||||
);
|
||||
|
||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub struct PayoutsMandateReferenceRecord {
|
||||
pub transfer_method_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub struct PaymentsMandateReferenceRecord {
|
||||
pub connector_mandate_id: String,
|
||||
pub payment_method_type: Option<common_enums::PaymentMethodType>,
|
||||
@ -280,6 +291,80 @@ pub struct PaymentsMandateReferenceRecord {
|
||||
pub original_payment_authorized_currency: Option<common_enums::Currency>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
||||
pub struct CommonMandateReference {
|
||||
pub payments: Option<PaymentsMandateReference>,
|
||||
pub payouts: Option<PayoutsMandateReference>,
|
||||
}
|
||||
|
||||
impl From<CommonMandateReference> for PaymentsMandateReference {
|
||||
fn from(common_mandate: CommonMandateReference) -> Self {
|
||||
common_mandate.payments.unwrap_or_default()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PaymentsMandateReference> for CommonMandateReference {
|
||||
fn from(payments_reference: PaymentsMandateReference) -> Self {
|
||||
Self {
|
||||
payments: Some(payments_reference),
|
||||
payouts: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_connector_mandate_details<'de, D>(
|
||||
deserializer: D,
|
||||
) -> Result<Option<CommonMandateReference>, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let value: Option<serde_json::Value> =
|
||||
<Option<serde_json::Value> as de::Deserialize>::deserialize(deserializer)?;
|
||||
|
||||
let payments_data = value
|
||||
.clone()
|
||||
.map(|mut mandate_details| {
|
||||
mandate_details
|
||||
.as_object_mut()
|
||||
.map(|obj| obj.remove("payouts"));
|
||||
|
||||
serde_json::from_value::<PaymentsMandateReference>(mandate_details)
|
||||
})
|
||||
.transpose()
|
||||
.map_err(|err| {
|
||||
let err_msg = format!("{err:?}");
|
||||
de::Error::custom(format_args!(
|
||||
"Failed to deserialize PaymentsMandateReference `{}`",
|
||||
err_msg
|
||||
))
|
||||
})?;
|
||||
|
||||
let payouts_data = value
|
||||
.clone()
|
||||
.map(|mandate_details| {
|
||||
serde_json::from_value::<Option<CommonMandateReference>>(mandate_details).map(
|
||||
|optional_common_mandate_details| {
|
||||
optional_common_mandate_details
|
||||
.and_then(|common_mandate_details| common_mandate_details.payouts)
|
||||
},
|
||||
)
|
||||
})
|
||||
.transpose()
|
||||
.map_err(|err| {
|
||||
let err_msg = format!("{err:?}");
|
||||
de::Error::custom(format_args!(
|
||||
"Failed to deserialize CommonMandateReference `{}`",
|
||||
err_msg
|
||||
))
|
||||
})?
|
||||
.flatten();
|
||||
|
||||
Ok(Some(CommonMandateReference {
|
||||
payments: payments_data,
|
||||
payouts: payouts_data,
|
||||
}))
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
any(feature = "v1", feature = "v2"),
|
||||
not(feature = "payment_methods_v2")
|
||||
@ -313,7 +398,12 @@ impl PaymentMethodCreate {
|
||||
payment_method_issuer_code: payment_method_migrate.payment_method_issuer_code,
|
||||
metadata: payment_method_migrate.metadata.clone(),
|
||||
payment_method_data: payment_method_migrate.payment_method_data.clone(),
|
||||
connector_mandate_details: payment_method_migrate.connector_mandate_details.clone(),
|
||||
connector_mandate_details: payment_method_migrate
|
||||
.connector_mandate_details
|
||||
.clone()
|
||||
.map(|common_mandate_reference| {
|
||||
PaymentsMandateReference::from(common_mandate_reference)
|
||||
}),
|
||||
client_secret: None,
|
||||
billing: payment_method_migrate.billing.clone(),
|
||||
card: card_details,
|
||||
@ -2328,7 +2418,11 @@ impl
|
||||
}),
|
||||
email: record.email,
|
||||
}),
|
||||
connector_mandate_details,
|
||||
connector_mandate_details: connector_mandate_details.map(
|
||||
|payments_mandate_reference| {
|
||||
CommonMandateReference::from(payments_mandate_reference)
|
||||
},
|
||||
),
|
||||
metadata: None,
|
||||
payment_method_issuer_code: None,
|
||||
card_network: None,
|
||||
|
||||
@ -184,6 +184,9 @@ pub struct PayoutCreateRequest {
|
||||
/// Customer's phone country code. _Deprecated: Use customer object instead._
|
||||
#[schema(deprecated, max_length = 255, example = "+1")]
|
||||
pub phone_country_code: Option<String>,
|
||||
|
||||
/// Identifier for payout method
|
||||
pub payout_method_id: Option<String>,
|
||||
}
|
||||
|
||||
impl PayoutCreateRequest {
|
||||
@ -568,6 +571,9 @@ pub struct PayoutCreateResponse {
|
||||
#[remove_in(PayoutCreateResponse)]
|
||||
#[schema(value_type = Option<String>, max_length = 1024, example = "Invalid card details")]
|
||||
pub unified_message: Option<UnifiedMessage>,
|
||||
|
||||
/// Identifier for payout method
|
||||
pub payout_method_id: Option<String>,
|
||||
}
|
||||
|
||||
/// The payout method information for response
|
||||
|
||||
Reference in New Issue
Block a user