mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-11-04 14:07:18 +08:00 
			
		
		
		
	fix: fixes to surface level mandate issues (#180)
This commit is contained in:
		@ -93,6 +93,7 @@ where
 | 
			
		||||
{
 | 
			
		||||
    match resp.request.get_mandate_id() {
 | 
			
		||||
        Some(mandate_id) => {
 | 
			
		||||
            let mandate_id = &mandate_id.mandate_id;
 | 
			
		||||
            let mandate = state
 | 
			
		||||
                .store
 | 
			
		||||
                .find_mandate_by_merchant_id_mandate_id(resp.merchant_id.as_ref(), mandate_id)
 | 
			
		||||
@ -157,7 +158,10 @@ where
 | 
			
		||||
                    mandate_reference,
 | 
			
		||||
                ) {
 | 
			
		||||
                    resp.request
 | 
			
		||||
                        .set_mandate_id(new_mandate_data.mandate_id.clone());
 | 
			
		||||
                        .set_mandate_id(api_models::payments::MandateIds {
 | 
			
		||||
                            mandate_id: new_mandate_data.mandate_id.clone(),
 | 
			
		||||
                            connector_mandate_id: new_mandate_data.connector_mandate_id.clone(),
 | 
			
		||||
                        });
 | 
			
		||||
                    state
 | 
			
		||||
                        .store
 | 
			
		||||
                        .insert_mandate(new_mandate_data)
 | 
			
		||||
@ -178,7 +182,7 @@ where
 | 
			
		||||
pub trait MandateBehaviour {
 | 
			
		||||
    fn get_amount(&self) -> i64;
 | 
			
		||||
    fn get_setup_future_usage(&self) -> Option<storage_models::enums::FutureUsage>;
 | 
			
		||||
    fn get_mandate_id(&self) -> Option<&String>;
 | 
			
		||||
    fn set_mandate_id(&mut self, new_mandate_id: String);
 | 
			
		||||
    fn get_mandate_id(&self) -> Option<&api_models::payments::MandateIds>;
 | 
			
		||||
    fn set_mandate_id(&mut self, new_mandate_id: api_models::payments::MandateIds);
 | 
			
		||||
    fn get_payment_method_data(&self) -> api_models::payments::PaymentMethod;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,7 @@ pub mod transformers;
 | 
			
		||||
 | 
			
		||||
use std::{fmt::Debug, marker::PhantomData, time::Instant};
 | 
			
		||||
 | 
			
		||||
use common_utils::ext_traits::AsyncExt;
 | 
			
		||||
use error_stack::{IntoReport, ResultExt};
 | 
			
		||||
use futures::future::join_all;
 | 
			
		||||
use router_env::{tracing, tracing::instrument};
 | 
			
		||||
@ -61,6 +62,7 @@ where
 | 
			
		||||
 | 
			
		||||
    // To perform router related operation for PaymentResponse
 | 
			
		||||
    PaymentResponse: Operation<F, FData>,
 | 
			
		||||
    FData: std::marker::Send,
 | 
			
		||||
{
 | 
			
		||||
    let operation: BoxedOperation<F, Req> = Box::new(operation);
 | 
			
		||||
 | 
			
		||||
@ -181,6 +183,7 @@ pub async fn payments_core<F, Res, Req, Op, FData>(
 | 
			
		||||
) -> RouterResponse<Res>
 | 
			
		||||
where
 | 
			
		||||
    F: Send + Clone,
 | 
			
		||||
    FData: std::marker::Send,
 | 
			
		||||
    Op: Operation<F, Req> + Send + Sync + Clone,
 | 
			
		||||
    Req: Debug,
 | 
			
		||||
    Res: transformers::ToResponse<Req, PaymentData<F>, Op> + From<Req>,
 | 
			
		||||
@ -194,7 +197,6 @@ where
 | 
			
		||||
 | 
			
		||||
    // To perform router related operation for PaymentResponse
 | 
			
		||||
    PaymentResponse: Operation<F, FData>,
 | 
			
		||||
    // To create merchant response
 | 
			
		||||
{
 | 
			
		||||
    let (payment_data, req, customer) = payments_operation_core(
 | 
			
		||||
        state,
 | 
			
		||||
@ -313,7 +315,7 @@ where
 | 
			
		||||
 | 
			
		||||
    // To create connector flow specific interface data
 | 
			
		||||
    PaymentData<F>: ConstructFlowSpecificData<F, Req, types::PaymentsResponseData>,
 | 
			
		||||
    types::RouterData<F, Req, types::PaymentsResponseData>: Feature<F, Req>,
 | 
			
		||||
    types::RouterData<F, Req, types::PaymentsResponseData>: Feature<F, Req> + Send,
 | 
			
		||||
 | 
			
		||||
    // To construct connector flow specific api
 | 
			
		||||
    dyn api::Connector: services::api::ConnectorIntegration<F, Req, types::PaymentsResponseData>,
 | 
			
		||||
@ -339,21 +341,22 @@ where
 | 
			
		||||
        )
 | 
			
		||||
        .await;
 | 
			
		||||
 | 
			
		||||
    let response = helpers::amap(res, |response| async {
 | 
			
		||||
        let operation = helpers::response_operation::<F, Req>();
 | 
			
		||||
        let payment_data = operation
 | 
			
		||||
            .to_post_update_tracker()?
 | 
			
		||||
            .update_tracker(
 | 
			
		||||
                db,
 | 
			
		||||
                payment_id,
 | 
			
		||||
                payment_data,
 | 
			
		||||
                Some(response),
 | 
			
		||||
                merchant_account.storage_scheme,
 | 
			
		||||
            )
 | 
			
		||||
            .await?;
 | 
			
		||||
        Ok(payment_data)
 | 
			
		||||
    })
 | 
			
		||||
    .await?;
 | 
			
		||||
    let response = res
 | 
			
		||||
        .async_and_then(|response| async {
 | 
			
		||||
            let operation = helpers::response_operation::<F, Req>();
 | 
			
		||||
            let payment_data = operation
 | 
			
		||||
                .to_post_update_tracker()?
 | 
			
		||||
                .update_tracker(
 | 
			
		||||
                    db,
 | 
			
		||||
                    payment_id,
 | 
			
		||||
                    payment_data,
 | 
			
		||||
                    response,
 | 
			
		||||
                    merchant_account.storage_scheme,
 | 
			
		||||
                )
 | 
			
		||||
                .await?;
 | 
			
		||||
            Ok(payment_data)
 | 
			
		||||
        })
 | 
			
		||||
        .await?;
 | 
			
		||||
 | 
			
		||||
    let etime_connector = Instant::now();
 | 
			
		||||
    let duration_connector = etime_connector.saturating_duration_since(stime_connector);
 | 
			
		||||
@ -457,8 +460,8 @@ where
 | 
			
		||||
    pub payment_attempt: storage::PaymentAttempt,
 | 
			
		||||
    pub connector_response: storage::ConnectorResponse,
 | 
			
		||||
    pub amount: api::Amount,
 | 
			
		||||
    pub mandate_id: Option<api_models::payments::MandateIds>,
 | 
			
		||||
    pub currency: storage_enums::Currency,
 | 
			
		||||
    pub mandate_id: Option<String>,
 | 
			
		||||
    pub setup_mandate: Option<api::MandateData>,
 | 
			
		||||
    pub address: PaymentAddress,
 | 
			
		||||
    pub token: Option<String>,
 | 
			
		||||
 | 
			
		||||
@ -111,7 +111,7 @@ impl mandate::MandateBehaviour for types::PaymentsAuthorizeData {
 | 
			
		||||
    fn get_amount(&self) -> i64 {
 | 
			
		||||
        self.amount
 | 
			
		||||
    }
 | 
			
		||||
    fn get_mandate_id(&self) -> Option<&String> {
 | 
			
		||||
    fn get_mandate_id(&self) -> Option<&api_models::payments::MandateIds> {
 | 
			
		||||
        self.mandate_id.as_ref()
 | 
			
		||||
    }
 | 
			
		||||
    fn get_payment_method_data(&self) -> api_models::payments::PaymentMethod {
 | 
			
		||||
@ -120,7 +120,7 @@ impl mandate::MandateBehaviour for types::PaymentsAuthorizeData {
 | 
			
		||||
    fn get_setup_future_usage(&self) -> Option<storage_models::enums::FutureUsage> {
 | 
			
		||||
        self.setup_future_usage
 | 
			
		||||
    }
 | 
			
		||||
    fn set_mandate_id(&mut self, new_mandate_id: String) {
 | 
			
		||||
    fn set_mandate_id(&mut self, new_mandate_id: api_models::payments::MandateIds) {
 | 
			
		||||
        self.mandate_id = Some(new_mandate_id);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -98,11 +98,11 @@ impl mandate::MandateBehaviour for types::VerifyRequestData {
 | 
			
		||||
        self.setup_future_usage
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn get_mandate_id(&self) -> Option<&String> {
 | 
			
		||||
    fn get_mandate_id(&self) -> Option<&api_models::payments::MandateIds> {
 | 
			
		||||
        self.mandate_id.as_ref()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn set_mandate_id(&mut self, new_mandate_id: String) {
 | 
			
		||||
    fn set_mandate_id(&mut self, new_mandate_id: api_models::payments::MandateIds) {
 | 
			
		||||
        self.mandate_id = Some(new_mandate_id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -390,7 +390,7 @@ pub fn verify_mandate_details(
 | 
			
		||||
        mandate
 | 
			
		||||
            .mandate_currency
 | 
			
		||||
            .map(|mandate_currency| mandate_currency.to_string() != request_currency)
 | 
			
		||||
            .unwrap_or(true),
 | 
			
		||||
            .unwrap_or(false),
 | 
			
		||||
        Err(report!(errors::ApiErrorResponse::MandateValidationFailed {
 | 
			
		||||
            reason: "cross currency mandates not supported".to_string()
 | 
			
		||||
        })),
 | 
			
		||||
@ -471,17 +471,6 @@ where
 | 
			
		||||
    Box::new(PaymentResponse)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub async fn amap<A, B, E, F, Fut>(value: Result<A, E>, func: F) -> Result<B, E>
 | 
			
		||||
where
 | 
			
		||||
    F: FnOnce(A) -> Fut,
 | 
			
		||||
    Fut: futures::Future<Output = Result<B, E>>,
 | 
			
		||||
{
 | 
			
		||||
    match value {
 | 
			
		||||
        Ok(a) => func(a).await,
 | 
			
		||||
        Err(err) => Err(err),
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[instrument(skip_all)]
 | 
			
		||||
pub(crate) async fn call_payment_method(
 | 
			
		||||
    state: &AppState,
 | 
			
		||||
 | 
			
		||||
@ -164,7 +164,7 @@ pub trait PostUpdateTracker<F, D, R>: Send {
 | 
			
		||||
        db: &dyn StorageInterface,
 | 
			
		||||
        payment_id: &api::PaymentIdType,
 | 
			
		||||
        payment_data: D,
 | 
			
		||||
        response: Option<types::RouterData<F, R, PaymentsResponseData>>,
 | 
			
		||||
        response: types::RouterData<F, R, PaymentsResponseData>,
 | 
			
		||||
        storage_scheme: enums::MerchantStorageScheme,
 | 
			
		||||
    ) -> RouterResult<D>
 | 
			
		||||
    where
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
use std::marker::PhantomData;
 | 
			
		||||
 | 
			
		||||
use async_trait::async_trait;
 | 
			
		||||
use common_utils::ext_traits::AsyncExt;
 | 
			
		||||
use error_stack::ResultExt;
 | 
			
		||||
use masking::Secret;
 | 
			
		||||
use router_derive::PaymentOperation;
 | 
			
		||||
@ -182,6 +183,22 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
 | 
			
		||||
            }
 | 
			
		||||
        }?;
 | 
			
		||||
 | 
			
		||||
        let mandate_id = request
 | 
			
		||||
            .mandate_id
 | 
			
		||||
            .as_ref()
 | 
			
		||||
            .async_and_then(|mandate_id| async {
 | 
			
		||||
                let mandate = db
 | 
			
		||||
                    .find_mandate_by_merchant_id_mandate_id(merchant_id, mandate_id)
 | 
			
		||||
                    .await
 | 
			
		||||
                    .change_context(errors::ApiErrorResponse::MandateNotFound);
 | 
			
		||||
                Some(mandate.map(|mandate_obj| api_models::payments::MandateIds {
 | 
			
		||||
                    mandate_id: mandate_obj.mandate_id,
 | 
			
		||||
                    connector_mandate_id: mandate_obj.connector_mandate_id,
 | 
			
		||||
                }))
 | 
			
		||||
            })
 | 
			
		||||
            .await
 | 
			
		||||
            .transpose()?;
 | 
			
		||||
 | 
			
		||||
        let operation = payments::if_not_create_change_operation::<_, F>(
 | 
			
		||||
            is_update,
 | 
			
		||||
            payment_intent.status,
 | 
			
		||||
@ -197,7 +214,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
 | 
			
		||||
                payment_attempt,
 | 
			
		||||
                currency,
 | 
			
		||||
                amount,
 | 
			
		||||
                mandate_id: request.mandate_id.clone(),
 | 
			
		||||
                mandate_id,
 | 
			
		||||
                setup_mandate,
 | 
			
		||||
                token,
 | 
			
		||||
                address: PaymentAddress {
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
use async_trait::async_trait;
 | 
			
		||||
use error_stack::{report, ResultExt};
 | 
			
		||||
use error_stack::ResultExt;
 | 
			
		||||
use router_derive;
 | 
			
		||||
 | 
			
		||||
use super::{Operation, PostUpdateTracker};
 | 
			
		||||
@ -34,27 +34,22 @@ impl<F: Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsAuthorizeData
 | 
			
		||||
        db: &dyn StorageInterface,
 | 
			
		||||
        payment_id: &api::PaymentIdType,
 | 
			
		||||
        mut payment_data: PaymentData<F>,
 | 
			
		||||
        response: Option<
 | 
			
		||||
            types::RouterData<F, types::PaymentsAuthorizeData, types::PaymentsResponseData>,
 | 
			
		||||
        router_data: types::RouterData<
 | 
			
		||||
            F,
 | 
			
		||||
            types::PaymentsAuthorizeData,
 | 
			
		||||
            types::PaymentsResponseData,
 | 
			
		||||
        >,
 | 
			
		||||
        storage_scheme: enums::MerchantStorageScheme,
 | 
			
		||||
    ) -> RouterResult<PaymentData<F>>
 | 
			
		||||
    where
 | 
			
		||||
        F: 'b + Send,
 | 
			
		||||
    {
 | 
			
		||||
        let router_data = response.ok_or(report!(errors::ApiErrorResponse::InternalServerError))?;
 | 
			
		||||
        payment_data.mandate_id = payment_data
 | 
			
		||||
            .mandate_id
 | 
			
		||||
            .or_else(|| router_data.request.mandate_id.clone());
 | 
			
		||||
 | 
			
		||||
        payment_response_update_tracker(
 | 
			
		||||
            db,
 | 
			
		||||
            payment_id,
 | 
			
		||||
            payment_data,
 | 
			
		||||
            Some(router_data),
 | 
			
		||||
            storage_scheme,
 | 
			
		||||
        )
 | 
			
		||||
        .await
 | 
			
		||||
        payment_response_update_tracker(db, payment_id, payment_data, router_data, storage_scheme)
 | 
			
		||||
            .await
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -65,9 +60,7 @@ impl<F: Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsSyncData> for
 | 
			
		||||
        db: &dyn StorageInterface,
 | 
			
		||||
        payment_id: &api::PaymentIdType,
 | 
			
		||||
        payment_data: PaymentData<F>,
 | 
			
		||||
        response: Option<
 | 
			
		||||
            types::RouterData<F, types::PaymentsSyncData, types::PaymentsResponseData>,
 | 
			
		||||
        >,
 | 
			
		||||
        response: types::RouterData<F, types::PaymentsSyncData, types::PaymentsResponseData>,
 | 
			
		||||
        storage_scheme: enums::MerchantStorageScheme,
 | 
			
		||||
    ) -> RouterResult<PaymentData<F>>
 | 
			
		||||
    where
 | 
			
		||||
@ -87,9 +80,7 @@ impl<F: Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsSessionData>
 | 
			
		||||
        db: &dyn StorageInterface,
 | 
			
		||||
        payment_id: &api::PaymentIdType,
 | 
			
		||||
        payment_data: PaymentData<F>,
 | 
			
		||||
        response: Option<
 | 
			
		||||
            types::RouterData<F, types::PaymentsSessionData, types::PaymentsResponseData>,
 | 
			
		||||
        >,
 | 
			
		||||
        response: types::RouterData<F, types::PaymentsSessionData, types::PaymentsResponseData>,
 | 
			
		||||
        storage_scheme: enums::MerchantStorageScheme,
 | 
			
		||||
    ) -> RouterResult<PaymentData<F>>
 | 
			
		||||
    where
 | 
			
		||||
@ -109,9 +100,7 @@ impl<F: Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsCaptureData>
 | 
			
		||||
        db: &dyn StorageInterface,
 | 
			
		||||
        payment_id: &api::PaymentIdType,
 | 
			
		||||
        payment_data: PaymentData<F>,
 | 
			
		||||
        response: Option<
 | 
			
		||||
            types::RouterData<F, types::PaymentsCaptureData, types::PaymentsResponseData>,
 | 
			
		||||
        >,
 | 
			
		||||
        response: types::RouterData<F, types::PaymentsCaptureData, types::PaymentsResponseData>,
 | 
			
		||||
        storage_scheme: enums::MerchantStorageScheme,
 | 
			
		||||
    ) -> RouterResult<PaymentData<F>>
 | 
			
		||||
    where
 | 
			
		||||
@ -129,9 +118,8 @@ impl<F: Clone> PostUpdateTracker<F, PaymentData<F>, types::PaymentsCancelData> f
 | 
			
		||||
        db: &dyn StorageInterface,
 | 
			
		||||
        payment_id: &api::PaymentIdType,
 | 
			
		||||
        payment_data: PaymentData<F>,
 | 
			
		||||
        response: Option<
 | 
			
		||||
            types::RouterData<F, types::PaymentsCancelData, types::PaymentsResponseData>,
 | 
			
		||||
        >,
 | 
			
		||||
        response: types::RouterData<F, types::PaymentsCancelData, types::PaymentsResponseData>,
 | 
			
		||||
 | 
			
		||||
        storage_scheme: enums::MerchantStorageScheme,
 | 
			
		||||
    ) -> RouterResult<PaymentData<F>>
 | 
			
		||||
    where
 | 
			
		||||
@ -148,16 +136,20 @@ impl<F: Clone> PostUpdateTracker<F, PaymentData<F>, types::VerifyRequestData> fo
 | 
			
		||||
        &'b self,
 | 
			
		||||
        db: &dyn StorageInterface,
 | 
			
		||||
        payment_id: &api::PaymentIdType,
 | 
			
		||||
        payment_data: PaymentData<F>,
 | 
			
		||||
        response: Option<
 | 
			
		||||
            types::RouterData<F, types::VerifyRequestData, types::PaymentsResponseData>,
 | 
			
		||||
        >,
 | 
			
		||||
        mut payment_data: PaymentData<F>,
 | 
			
		||||
        router_data: types::RouterData<F, types::VerifyRequestData, types::PaymentsResponseData>,
 | 
			
		||||
 | 
			
		||||
        storage_scheme: enums::MerchantStorageScheme,
 | 
			
		||||
    ) -> RouterResult<PaymentData<F>>
 | 
			
		||||
    where
 | 
			
		||||
        F: 'b + Send,
 | 
			
		||||
    {
 | 
			
		||||
        payment_response_update_tracker(db, payment_id, payment_data, response, storage_scheme)
 | 
			
		||||
        payment_data.mandate_id = payment_data.mandate_id.or_else(|| {
 | 
			
		||||
            router_data.request.mandate_id.clone()
 | 
			
		||||
            // .map(api_models::payments::MandateIds::new)
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        payment_response_update_tracker(db, payment_id, payment_data, router_data, storage_scheme)
 | 
			
		||||
            .await
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -166,11 +158,9 @@ async fn payment_response_update_tracker<F: Clone, T>(
 | 
			
		||||
    db: &dyn StorageInterface,
 | 
			
		||||
    _payment_id: &api::PaymentIdType,
 | 
			
		||||
    mut payment_data: PaymentData<F>,
 | 
			
		||||
    response: Option<types::RouterData<F, T, types::PaymentsResponseData>>,
 | 
			
		||||
    router_data: types::RouterData<F, T, types::PaymentsResponseData>,
 | 
			
		||||
    storage_scheme: enums::MerchantStorageScheme,
 | 
			
		||||
) -> RouterResult<PaymentData<F>> {
 | 
			
		||||
    let router_data = response.ok_or(report!(errors::ApiErrorResponse::InternalServerError))?;
 | 
			
		||||
 | 
			
		||||
    let (payment_attempt_update, connector_response_update) = match router_data.response.clone() {
 | 
			
		||||
        Err(err) => (
 | 
			
		||||
            Some(storage::PaymentAttemptUpdate::ErrorUpdate {
 | 
			
		||||
@ -212,7 +202,10 @@ async fn payment_response_update_tracker<F: Clone, T>(
 | 
			
		||||
                    authentication_type: None,
 | 
			
		||||
                    payment_method_id: Some(router_data.payment_method_id),
 | 
			
		||||
                    redirect: Some(redirect),
 | 
			
		||||
                    mandate_id: payment_data.mandate_id.clone(),
 | 
			
		||||
                    mandate_id: payment_data
 | 
			
		||||
                        .mandate_id
 | 
			
		||||
                        .clone()
 | 
			
		||||
                        .map(|mandate| mandate.mandate_id),
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                let connector_response_update = storage::ConnectorResponseUpdate::ResponseUpdate {
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
use std::marker::PhantomData;
 | 
			
		||||
 | 
			
		||||
use async_trait::async_trait;
 | 
			
		||||
use common_utils::ext_traits::AsyncExt;
 | 
			
		||||
use error_stack::{report, ResultExt};
 | 
			
		||||
use masking::Secret;
 | 
			
		||||
use router_derive::PaymentOperation;
 | 
			
		||||
@ -126,6 +127,21 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
 | 
			
		||||
                    .attach_printable("Database error when finding connector response")
 | 
			
		||||
            })?;
 | 
			
		||||
 | 
			
		||||
        let mandate_id = request
 | 
			
		||||
            .mandate_id
 | 
			
		||||
            .as_ref()
 | 
			
		||||
            .async_and_then(|mandate_id| async {
 | 
			
		||||
                let mandate = db
 | 
			
		||||
                    .find_mandate_by_merchant_id_mandate_id(merchant_id, mandate_id)
 | 
			
		||||
                    .await
 | 
			
		||||
                    .change_context(errors::ApiErrorResponse::MandateNotFound);
 | 
			
		||||
                Some(mandate.map(|mandate_obj| api_models::payments::MandateIds {
 | 
			
		||||
                    mandate_id: mandate_obj.mandate_id,
 | 
			
		||||
                    connector_mandate_id: mandate_obj.connector_mandate_id,
 | 
			
		||||
                }))
 | 
			
		||||
            })
 | 
			
		||||
            .await
 | 
			
		||||
            .transpose()?;
 | 
			
		||||
        let next_operation: BoxedOperation<'a, F, api::PaymentsRequest> =
 | 
			
		||||
            if request.confirm.unwrap_or(false) {
 | 
			
		||||
                Box::new(operations::PaymentConfirm)
 | 
			
		||||
@ -149,7 +165,7 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
 | 
			
		||||
                    payment_attempt,
 | 
			
		||||
                    currency,
 | 
			
		||||
                    amount,
 | 
			
		||||
                    mandate_id: request.mandate_id.clone(),
 | 
			
		||||
                    mandate_id,
 | 
			
		||||
                    token,
 | 
			
		||||
                    setup_mandate,
 | 
			
		||||
                    address: PaymentAddress {
 | 
			
		||||
 | 
			
		||||
@ -197,7 +197,7 @@ where
 | 
			
		||||
            phone: customer
 | 
			
		||||
                .as_ref()
 | 
			
		||||
                .and_then(|cus| cus.phone.as_ref().map(|s| s.to_owned())),
 | 
			
		||||
            mandate_id: data.mandate_id,
 | 
			
		||||
            mandate_id: data.mandate_id.map(|mandate_ids| mandate_ids.mandate_id),
 | 
			
		||||
            payment_method: data
 | 
			
		||||
                .payment_attempt
 | 
			
		||||
                .payment_method
 | 
			
		||||
@ -499,8 +499,8 @@ impl<F: Clone> TryFrom<PaymentData<F>> for types::VerifyRequestData {
 | 
			
		||||
            },
 | 
			
		||||
            statement_descriptor_suffix: payment_data.payment_intent.statement_descriptor_suffix,
 | 
			
		||||
            setup_future_usage: payment_data.payment_intent.setup_future_usage,
 | 
			
		||||
            mandate_id: payment_data.mandate_id.clone(),
 | 
			
		||||
            off_session: payment_data.mandate_id.as_ref().map(|_| true),
 | 
			
		||||
            mandate_id: payment_data.mandate_id.clone(),
 | 
			
		||||
            setup_mandate_details: payment_data.setup_mandate,
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user