fix: consume profile_id throughout payouts flow (#2501)

Co-authored-by: Kashif <mohammed.kashif@juspay.in>
This commit is contained in:
Kashif
2023-10-12 13:14:23 +05:30
committed by GitHub
parent 1ee11849d4
commit 7eabd24a4d
6 changed files with 38 additions and 29 deletions

View File

@ -146,6 +146,10 @@ pub struct PayoutCreateRequest {
/// Provide a reference to a stored payment method
#[schema(example = "187282ab-40ef-47a9-9206-5099ba31e432")]
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)]
@ -376,6 +380,9 @@ pub struct PayoutCreateResponse {
/// If there was an error while calling the connectors the code is received here
#[schema(value_type = String, example = "E0001")]
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)]

View File

@ -618,7 +618,7 @@ pub async fn create_recipient(
let merchant_id = merchant_account.merchant_id.to_owned();
let updated_customer = storage::CustomerUpdate::ConnectorCustomer {
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(
@ -1116,6 +1116,7 @@ pub async fn response_handler(
status: payout_attempt.status.to_owned(),
error_message: payout_attempt.error_message.to_owned(),
error_code: payout_attempt.error_code,
profile_id: payout_attempt.profile_id,
};
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_created_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();
let payout_attempt = db
.insert_payout_attempt(payout_attempt_req)

View File

@ -40,31 +40,32 @@ pub async fn get_mca_for_payout<'a>(
merchant_account: &domain::MerchantAccount,
key_store: &domain::MerchantKeyStore,
payout_data: &PayoutData,
) -> RouterResult<helpers::MerchantConnectorAccountType> {
) -> RouterResult<(helpers::MerchantConnectorAccountType, String)> {
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() {
Some(mca) => Ok(mca),
Some(mca) => Ok((mca, profile_id)),
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(
state,
merchant_account.merchant_id.as_str(),
None,
key_store,
profile_id,
&profile_id,
connector_id,
)
.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,
payout_data: &mut PayoutData,
) -> RouterResult<types::PayoutsRouterData<F>> {
let (business_country, _) = helpers::get_business_details(
payout_data.payout_attempt.business_country,
payout_data.payout_attempt.business_label.as_ref(),
merchant_account,
)?;
let merchant_connector_account = get_mca_for_payout(
let (merchant_connector_account, profile_id) = get_mca_for_payout(
state,
connector_id,
merchant_account,
@ -130,10 +126,11 @@ pub async fn construct_payout_router_data<'a, F>(
let payouts = &payout_data.payouts;
let payout_attempt = &payout_data.payout_attempt;
let customer_details = &payout_data.customer_details;
let connector_label = format!("{profile_id}_{}", payout_attempt.connector);
let connector_customer_id = customer_details
.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());
let router_data = types::RouterData {
flow: PhantomData,
@ -161,7 +158,6 @@ pub async fn construct_payout_router_data<'a, F>(
source_currency: payouts.source_currency,
entity_type: payouts.entity_type.to_owned(),
payout_type: payouts.payout_type,
country_code: business_country,
customer_details: customer_details
.to_owned()
.map(|c| payments::CustomerDetails {

View File

@ -335,7 +335,6 @@ pub struct PayoutsData {
pub source_currency: storage_enums::Currency,
pub payout_type: storage_enums::PayoutType,
pub entity_type: storage_enums::PayoutEntityType,
pub country_code: storage_enums::CountryAlpha2,
pub customer_details: Option<CustomerDetails>,
}

View File

@ -442,11 +442,6 @@ pub trait ConnectorActions: Connector {
}),
entity_type: enums::PayoutEntityType::Individual,
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_id: core_utils::get_or_generate_id("customer_id", &None, "cust_").ok(),
name: Some(Secret::new("John Doe".to_string())),

View File

@ -9847,6 +9847,11 @@
"description": "Provide a reference to a stored payment method",
"example": "187282ab-40ef-47a9-9206-5099ba31e432",
"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",
"description": "If there was an error while calling the connectors the code is received here",
"example": "E0001"
},
"profile_id": {
"type": "string",
"description": "The business profile that is associated with this payment",
"nullable": true
}
}
},