mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-30 01:27:31 +08:00
fix: consume profile_id throughout payouts flow (#2501)
Co-authored-by: Kashif <mohammed.kashif@juspay.in>
This commit is contained in:
@ -146,6 +146,10 @@ pub struct PayoutCreateRequest {
|
|||||||
/// Provide a reference to a stored payment method
|
/// Provide a reference to a stored payment method
|
||||||
#[schema(example = "187282ab-40ef-47a9-9206-5099ba31e432")]
|
#[schema(example = "187282ab-40ef-47a9-9206-5099ba31e432")]
|
||||||
pub payout_token: Option<String>,
|
pub payout_token: Option<String>,
|
||||||
|
|
||||||
|
/// The business profile to use for this payment, if not passed the default business profile
|
||||||
|
/// associated with the merchant account will be used.
|
||||||
|
pub profile_id: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, ToSchema)]
|
#[derive(Debug, Clone, Deserialize, Serialize, ToSchema)]
|
||||||
@ -376,6 +380,9 @@ pub struct PayoutCreateResponse {
|
|||||||
/// If there was an error while calling the connectors the code is received here
|
/// If there was an error while calling the connectors the code is received here
|
||||||
#[schema(value_type = String, example = "E0001")]
|
#[schema(value_type = String, example = "E0001")]
|
||||||
pub error_code: Option<String>,
|
pub error_code: Option<String>,
|
||||||
|
|
||||||
|
/// The business profile that is associated with this payment
|
||||||
|
pub profile_id: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, Deserialize, ToSchema)]
|
#[derive(Default, Debug, Clone, Deserialize, ToSchema)]
|
||||||
|
|||||||
@ -618,7 +618,7 @@ pub async fn create_recipient(
|
|||||||
let merchant_id = merchant_account.merchant_id.to_owned();
|
let merchant_id = merchant_account.merchant_id.to_owned();
|
||||||
let updated_customer = storage::CustomerUpdate::ConnectorCustomer {
|
let updated_customer = storage::CustomerUpdate::ConnectorCustomer {
|
||||||
connector_customer: Some(
|
connector_customer: Some(
|
||||||
serde_json::json!({"id": recipient_create_data.connector_payout_id}),
|
serde_json::json!({connector_label: recipient_create_data.connector_payout_id}),
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
payout_data.customer_details = Some(
|
payout_data.customer_details = Some(
|
||||||
@ -1116,6 +1116,7 @@ pub async fn response_handler(
|
|||||||
status: payout_attempt.status.to_owned(),
|
status: payout_attempt.status.to_owned(),
|
||||||
error_message: payout_attempt.error_message.to_owned(),
|
error_message: payout_attempt.error_message.to_owned(),
|
||||||
error_code: payout_attempt.error_code,
|
error_code: payout_attempt.error_code,
|
||||||
|
profile_id: payout_attempt.profile_id,
|
||||||
};
|
};
|
||||||
Ok(services::ApplicationResponse::Json(response))
|
Ok(services::ApplicationResponse::Json(response))
|
||||||
}
|
}
|
||||||
@ -1244,6 +1245,7 @@ pub async fn payout_create_db_entries(
|
|||||||
.set_payout_token(req.payout_token.to_owned())
|
.set_payout_token(req.payout_token.to_owned())
|
||||||
.set_created_at(Some(common_utils::date_time::now()))
|
.set_created_at(Some(common_utils::date_time::now()))
|
||||||
.set_last_modified_at(Some(common_utils::date_time::now()))
|
.set_last_modified_at(Some(common_utils::date_time::now()))
|
||||||
|
.set_profile_id(req.profile_id.to_owned())
|
||||||
.to_owned();
|
.to_owned();
|
||||||
let payout_attempt = db
|
let payout_attempt = db
|
||||||
.insert_payout_attempt(payout_attempt_req)
|
.insert_payout_attempt(payout_attempt_req)
|
||||||
|
|||||||
@ -40,31 +40,32 @@ pub async fn get_mca_for_payout<'a>(
|
|||||||
merchant_account: &domain::MerchantAccount,
|
merchant_account: &domain::MerchantAccount,
|
||||||
key_store: &domain::MerchantKeyStore,
|
key_store: &domain::MerchantKeyStore,
|
||||||
payout_data: &PayoutData,
|
payout_data: &PayoutData,
|
||||||
) -> RouterResult<helpers::MerchantConnectorAccountType> {
|
) -> RouterResult<(helpers::MerchantConnectorAccountType, String)> {
|
||||||
let payout_attempt = &payout_data.payout_attempt;
|
let payout_attempt = &payout_data.payout_attempt;
|
||||||
|
let profile_id = get_profile_id_from_business_details(
|
||||||
|
payout_attempt.business_country,
|
||||||
|
payout_attempt.business_label.as_ref(),
|
||||||
|
merchant_account,
|
||||||
|
payout_attempt.profile_id.as_ref(),
|
||||||
|
&*state.store,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||||
|
.attach_printable("profile_id is not set in payout_attempt")?;
|
||||||
match payout_data.merchant_connector_account.to_owned() {
|
match payout_data.merchant_connector_account.to_owned() {
|
||||||
Some(mca) => Ok(mca),
|
Some(mca) => Ok((mca, profile_id)),
|
||||||
None => {
|
None => {
|
||||||
let profile_id = payout_attempt
|
|
||||||
.profile_id
|
|
||||||
.as_ref()
|
|
||||||
.ok_or(errors::ApiErrorResponse::MissingRequiredField {
|
|
||||||
field_name: "business_profile",
|
|
||||||
})
|
|
||||||
.into_report()
|
|
||||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
|
||||||
.attach_printable("profile_id is not set in payment_intent")?;
|
|
||||||
|
|
||||||
let merchant_connector_account = helpers::get_merchant_connector_account(
|
let merchant_connector_account = helpers::get_merchant_connector_account(
|
||||||
state,
|
state,
|
||||||
merchant_account.merchant_id.as_str(),
|
merchant_account.merchant_id.as_str(),
|
||||||
None,
|
None,
|
||||||
key_store,
|
key_store,
|
||||||
profile_id,
|
&profile_id,
|
||||||
connector_id,
|
connector_id,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
Ok(merchant_connector_account)
|
Ok((merchant_connector_account, profile_id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,12 +80,7 @@ pub async fn construct_payout_router_data<'a, F>(
|
|||||||
_request: &api_models::payouts::PayoutRequest,
|
_request: &api_models::payouts::PayoutRequest,
|
||||||
payout_data: &mut PayoutData,
|
payout_data: &mut PayoutData,
|
||||||
) -> RouterResult<types::PayoutsRouterData<F>> {
|
) -> RouterResult<types::PayoutsRouterData<F>> {
|
||||||
let (business_country, _) = helpers::get_business_details(
|
let (merchant_connector_account, profile_id) = get_mca_for_payout(
|
||||||
payout_data.payout_attempt.business_country,
|
|
||||||
payout_data.payout_attempt.business_label.as_ref(),
|
|
||||||
merchant_account,
|
|
||||||
)?;
|
|
||||||
let merchant_connector_account = get_mca_for_payout(
|
|
||||||
state,
|
state,
|
||||||
connector_id,
|
connector_id,
|
||||||
merchant_account,
|
merchant_account,
|
||||||
@ -130,10 +126,11 @@ pub async fn construct_payout_router_data<'a, F>(
|
|||||||
let payouts = &payout_data.payouts;
|
let payouts = &payout_data.payouts;
|
||||||
let payout_attempt = &payout_data.payout_attempt;
|
let payout_attempt = &payout_data.payout_attempt;
|
||||||
let customer_details = &payout_data.customer_details;
|
let customer_details = &payout_data.customer_details;
|
||||||
|
let connector_label = format!("{profile_id}_{}", payout_attempt.connector);
|
||||||
let connector_customer_id = customer_details
|
let connector_customer_id = customer_details
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|c| c.connector_customer.as_ref())
|
.and_then(|c| c.connector_customer.as_ref())
|
||||||
.and_then(|cc| cc.get("id"))
|
.and_then(|cc| cc.get(connector_label))
|
||||||
.and_then(|id| serde_json::from_value::<String>(id.to_owned()).ok());
|
.and_then(|id| serde_json::from_value::<String>(id.to_owned()).ok());
|
||||||
let router_data = types::RouterData {
|
let router_data = types::RouterData {
|
||||||
flow: PhantomData,
|
flow: PhantomData,
|
||||||
@ -161,7 +158,6 @@ pub async fn construct_payout_router_data<'a, F>(
|
|||||||
source_currency: payouts.source_currency,
|
source_currency: payouts.source_currency,
|
||||||
entity_type: payouts.entity_type.to_owned(),
|
entity_type: payouts.entity_type.to_owned(),
|
||||||
payout_type: payouts.payout_type,
|
payout_type: payouts.payout_type,
|
||||||
country_code: business_country,
|
|
||||||
customer_details: customer_details
|
customer_details: customer_details
|
||||||
.to_owned()
|
.to_owned()
|
||||||
.map(|c| payments::CustomerDetails {
|
.map(|c| payments::CustomerDetails {
|
||||||
|
|||||||
@ -335,7 +335,6 @@ pub struct PayoutsData {
|
|||||||
pub source_currency: storage_enums::Currency,
|
pub source_currency: storage_enums::Currency,
|
||||||
pub payout_type: storage_enums::PayoutType,
|
pub payout_type: storage_enums::PayoutType,
|
||||||
pub entity_type: storage_enums::PayoutEntityType,
|
pub entity_type: storage_enums::PayoutEntityType,
|
||||||
pub country_code: storage_enums::CountryAlpha2,
|
|
||||||
pub customer_details: Option<CustomerDetails>,
|
pub customer_details: Option<CustomerDetails>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -442,11 +442,6 @@ pub trait ConnectorActions: Connector {
|
|||||||
}),
|
}),
|
||||||
entity_type: enums::PayoutEntityType::Individual,
|
entity_type: enums::PayoutEntityType::Individual,
|
||||||
payout_type,
|
payout_type,
|
||||||
country_code: payment_info
|
|
||||||
.to_owned()
|
|
||||||
.map_or(enums::CountryAlpha2::NL, |pi| {
|
|
||||||
pi.country.map_or(enums::CountryAlpha2::NL, |c| c)
|
|
||||||
}),
|
|
||||||
customer_details: Some(payments::CustomerDetails {
|
customer_details: Some(payments::CustomerDetails {
|
||||||
customer_id: core_utils::get_or_generate_id("customer_id", &None, "cust_").ok(),
|
customer_id: core_utils::get_or_generate_id("customer_id", &None, "cust_").ok(),
|
||||||
name: Some(Secret::new("John Doe".to_string())),
|
name: Some(Secret::new("John Doe".to_string())),
|
||||||
|
|||||||
@ -9847,6 +9847,11 @@
|
|||||||
"description": "Provide a reference to a stored payment method",
|
"description": "Provide a reference to a stored payment method",
|
||||||
"example": "187282ab-40ef-47a9-9206-5099ba31e432",
|
"example": "187282ab-40ef-47a9-9206-5099ba31e432",
|
||||||
"nullable": true
|
"nullable": true
|
||||||
|
},
|
||||||
|
"profile_id": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The business profile to use for this payment, if not passed the default business profile\nassociated with the merchant account will be used.",
|
||||||
|
"nullable": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -9996,6 +10001,11 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "If there was an error while calling the connectors the code is received here",
|
"description": "If there was an error while calling the connectors the code is received here",
|
||||||
"example": "E0001"
|
"example": "E0001"
|
||||||
|
},
|
||||||
|
"profile_id": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The business profile that is associated with this payment",
|
||||||
|
"nullable": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user