mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-03 05:17:02 +08:00
feat: stripe connect integration for payouts (#2041)
Co-authored-by: Rachit Naithani <81706961+racnan@users.noreply.github.com> Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com> Co-authored-by: Apoorv Dixit <64925866+apoorvdixit88@users.noreply.github.com> Co-authored-by: Swangi Kumari <85639103+swangi-kumari@users.noreply.github.com> Co-authored-by: Narayan Bhat <narayan.bhat@juspay.in> Co-authored-by: Shankar Singh C <83439957+ShankarSinghC@users.noreply.github.com> Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Sakil Mostak <73734619+Sakilmostak@users.noreply.github.com> Co-authored-by: AkshayaFoiger <131388445+AkshayaFoiger@users.noreply.github.com>
This commit is contained in:
@ -1,11 +1,15 @@
|
||||
use std::{marker::PhantomData, str::FromStr};
|
||||
|
||||
use api_models::enums::{DisputeStage, DisputeStatus};
|
||||
#[cfg(feature = "payouts")]
|
||||
use api_models::payouts::PayoutVendorAccountDetails;
|
||||
use common_enums::{IntentStatus, RequestIncrementalAuthorization};
|
||||
#[cfg(feature = "payouts")]
|
||||
use common_utils::{crypto::Encryptable, pii::Email};
|
||||
use common_utils::{errors::CustomResult, ext_traits::AsyncExt};
|
||||
use error_stack::{report, ResultExt};
|
||||
#[cfg(feature = "payouts")]
|
||||
use masking::PeekInterface;
|
||||
use maud::{html, PreEscaped};
|
||||
use router_env::{instrument, tracing};
|
||||
use uuid::Uuid;
|
||||
@ -31,6 +35,9 @@ use crate::{
|
||||
|
||||
pub const IRRELEVANT_CONNECTOR_REQUEST_REFERENCE_ID_IN_DISPUTE_FLOW: &str =
|
||||
"irrelevant_connector_request_reference_id_in_dispute_flow";
|
||||
#[cfg(feature = "payouts")]
|
||||
pub const IRRELEVANT_CONNECTOR_REQUEST_REFERENCE_ID_IN_PAYOUTS_FLOW: &str =
|
||||
"irrelevant_connector_request_reference_id_in_payouts_flow";
|
||||
const IRRELEVANT_PAYMENT_ID_IN_DISPUTE_FLOW: &str = "irrelevant_payment_id_in_dispute_flow";
|
||||
const IRRELEVANT_ATTEMPT_ID_IN_DISPUTE_FLOW: &str = "irrelevant_attempt_id_in_dispute_flow";
|
||||
|
||||
@ -65,15 +72,14 @@ pub async fn get_mca_for_payout<'a>(
|
||||
#[instrument(skip_all)]
|
||||
pub async fn construct_payout_router_data<'a, F>(
|
||||
state: &'a AppState,
|
||||
connector_id: &str,
|
||||
connector_name: &api_models::enums::Connector,
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
key_store: &domain::MerchantKeyStore,
|
||||
_request: &api_models::payouts::PayoutRequest,
|
||||
payout_data: &mut PayoutData,
|
||||
) -> RouterResult<types::PayoutsRouterData<F>> {
|
||||
let merchant_connector_account = get_mca_for_payout(
|
||||
state,
|
||||
connector_id,
|
||||
&connector_name.to_string(),
|
||||
merchant_account,
|
||||
key_store,
|
||||
payout_data,
|
||||
@ -117,25 +123,36 @@ 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_name = payout_attempt
|
||||
.connector
|
||||
.clone()
|
||||
.get_required_value("connector")
|
||||
.change_context(errors::ApiErrorResponse::InvalidRequestData {
|
||||
message: "Could not decide to route the connector".to_string(),
|
||||
})?;
|
||||
let connector_label = format!("{}_{}", payout_data.profile_id, connector_name);
|
||||
let connector_customer_id = customer_details
|
||||
.as_ref()
|
||||
.and_then(|c| c.connector_customer.as_ref())
|
||||
.and_then(|cc| cc.get(connector_label))
|
||||
.and_then(|id| serde_json::from_value::<String>(id.to_owned()).ok());
|
||||
|
||||
let vendor_details: Option<PayoutVendorAccountDetails> =
|
||||
match api_models::enums::PayoutConnectors::try_from(connector_name.to_owned()).map_err(
|
||||
|err| report!(errors::ApiErrorResponse::InternalServerError).attach_printable(err),
|
||||
)? {
|
||||
api_models::enums::PayoutConnectors::Stripe => {
|
||||
payout_data.payouts.metadata.to_owned().and_then(|meta| {
|
||||
let val = meta
|
||||
.peek()
|
||||
.to_owned()
|
||||
.parse_value("PayoutVendorAccountDetails")
|
||||
.ok();
|
||||
val
|
||||
})
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let router_data = types::RouterData {
|
||||
flow: PhantomData,
|
||||
merchant_id: merchant_account.merchant_id.to_owned(),
|
||||
customer_id: None,
|
||||
connector_customer: connector_customer_id,
|
||||
connector: connector_id.to_string(),
|
||||
connector: connector_name.to_string(),
|
||||
payment_id: "".to_string(),
|
||||
attempt_id: "".to_string(),
|
||||
status: enums::AttemptStatus::Failure,
|
||||
@ -157,6 +174,7 @@ 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,
|
||||
vendor_details,
|
||||
customer_details: customer_details
|
||||
.to_owned()
|
||||
.map(|c| payments::CustomerDetails {
|
||||
@ -174,7 +192,7 @@ pub async fn construct_payout_router_data<'a, F>(
|
||||
payment_method_token: None,
|
||||
recurring_mandate_payment_data: None,
|
||||
preprocessing_id: None,
|
||||
connector_request_reference_id: IRRELEVANT_CONNECTOR_REQUEST_REFERENCE_ID_IN_DISPUTE_FLOW
|
||||
connector_request_reference_id: IRRELEVANT_CONNECTOR_REQUEST_REFERENCE_ID_IN_PAYOUTS_FLOW
|
||||
.to_string(),
|
||||
payout_method_data: payout_data.payout_method_data.to_owned(),
|
||||
quote_id: None,
|
||||
|
||||
Reference in New Issue
Block a user