mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 00:49:42 +08:00
refactor(connector): [Paypal] Add support for passing shipping_cost in Payment request (#6423)
This commit is contained in:
@ -71,17 +71,22 @@ pub struct PaymentsAuthorizeData {
|
||||
/// In case the connector supports only one reference id, Hyperswitch's Payment ID will be sent as reference.
|
||||
pub merchant_order_reference_id: Option<String>,
|
||||
pub integrity_object: Option<AuthoriseIntegrityObject>,
|
||||
pub shipping_cost: Option<MinorUnit>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PaymentsPostSessionTokensData {
|
||||
// amount here would include amount, surcharge_amount and shipping_cost
|
||||
pub amount: MinorUnit,
|
||||
/// original amount sent by the merchant
|
||||
pub order_amount: MinorUnit,
|
||||
pub currency: storage_enums::Currency,
|
||||
pub capture_method: Option<storage_enums::CaptureMethod>,
|
||||
/// Merchant's identifier for the payment/invoice. This will be sent to the connector
|
||||
/// if the connector provides support to accept multiple reference ids.
|
||||
/// In case the connector supports only one reference id, Hyperswitch's Payment ID will be sent as reference.
|
||||
pub merchant_order_reference_id: Option<String>,
|
||||
pub shipping_cost: Option<MinorUnit>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
@ -833,10 +838,13 @@ pub struct PaymentsTaxCalculationData {
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct SdkPaymentsSessionUpdateData {
|
||||
pub order_tax_amount: MinorUnit,
|
||||
pub net_amount: MinorUnit,
|
||||
// amount here would include amount, surcharge_amount, order_tax_amount and shipping_cost
|
||||
pub amount: MinorUnit,
|
||||
/// original amount sent by the merchant
|
||||
pub order_amount: MinorUnit,
|
||||
pub currency: storage_enums::Currency,
|
||||
pub session_id: Option<String>,
|
||||
pub shipping_cost: Option<MinorUnit>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -862,4 +870,5 @@ pub struct SetupMandateRequestData {
|
||||
|
||||
// MinorUnit for amount framework
|
||||
pub minor_amount: Option<MinorUnit>,
|
||||
pub shipping_cost: Option<MinorUnit>,
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ use base64::Engine;
|
||||
use common_utils::{
|
||||
ext_traits::ByteSliceExt,
|
||||
request::RequestContent,
|
||||
types::{AmountConvertor, StringMajorUnit, StringMajorUnitForConnector},
|
||||
types::{AmountConvertor, MinorUnit, StringMajorUnit, StringMajorUnitForConnector},
|
||||
};
|
||||
use diesel_models::enums;
|
||||
use error_stack::ResultExt;
|
||||
@ -484,7 +484,8 @@ impl ConnectorIntegration<api::PoFulfill, types::PayoutsData, types::PayoutsResp
|
||||
req.request.minor_amount,
|
||||
req.request.destination_currency,
|
||||
)?;
|
||||
let connector_router_data = paypal::PaypalRouterData::try_from((amount, None, None, req))?;
|
||||
let connector_router_data =
|
||||
paypal::PaypalRouterData::try_from((amount, None, None, None, req))?;
|
||||
let connector_req = paypal::PaypalFulfillRequest::try_from(&connector_router_data)?;
|
||||
Ok(RequestContent::Json(Box::new(connector_req)))
|
||||
}
|
||||
@ -710,7 +711,23 @@ impl
|
||||
req.request.amount,
|
||||
req.request.currency,
|
||||
)?;
|
||||
let connector_router_data = paypal::PaypalRouterData::try_from((amount, None, None, req))?;
|
||||
let shipping_cost = connector_utils::convert_amount(
|
||||
self.amount_converter,
|
||||
req.request.shipping_cost.unwrap_or(MinorUnit::zero()),
|
||||
req.request.currency,
|
||||
)?;
|
||||
let order_amount = connector_utils::convert_amount(
|
||||
self.amount_converter,
|
||||
req.request.order_amount,
|
||||
req.request.currency,
|
||||
)?;
|
||||
let connector_router_data = paypal::PaypalRouterData::try_from((
|
||||
amount,
|
||||
Some(shipping_cost),
|
||||
None,
|
||||
Some(order_amount),
|
||||
req,
|
||||
))?;
|
||||
let connector_req = paypal::PaypalPaymentsRequest::try_from(&connector_router_data)?;
|
||||
Ok(RequestContent::Json(Box::new(connector_req)))
|
||||
}
|
||||
@ -810,12 +827,12 @@ impl
|
||||
) -> CustomResult<RequestContent, errors::ConnectorError> {
|
||||
let order_amount = connector_utils::convert_amount(
|
||||
self.amount_converter,
|
||||
req.request.amount,
|
||||
req.request.order_amount,
|
||||
req.request.currency,
|
||||
)?;
|
||||
let amount = connector_utils::convert_amount(
|
||||
self.amount_converter,
|
||||
req.request.net_amount,
|
||||
req.request.amount,
|
||||
req.request.currency,
|
||||
)?;
|
||||
let order_tax_amount = connector_utils::convert_amount(
|
||||
@ -823,8 +840,14 @@ impl
|
||||
req.request.order_tax_amount,
|
||||
req.request.currency,
|
||||
)?;
|
||||
let shipping_cost = connector_utils::convert_amount(
|
||||
self.amount_converter,
|
||||
req.request.shipping_cost.unwrap_or(MinorUnit::zero()),
|
||||
req.request.currency,
|
||||
)?;
|
||||
let connector_router_data = paypal::PaypalRouterData::try_from((
|
||||
amount,
|
||||
Some(shipping_cost),
|
||||
Some(order_tax_amount),
|
||||
Some(order_amount),
|
||||
req,
|
||||
@ -915,7 +938,13 @@ impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::P
|
||||
req.request.minor_amount,
|
||||
req.request.currency,
|
||||
)?;
|
||||
let connector_router_data = paypal::PaypalRouterData::try_from((amount, None, None, req))?;
|
||||
let shipping_cost = connector_utils::convert_amount(
|
||||
self.amount_converter,
|
||||
req.request.shipping_cost.unwrap_or(MinorUnit::zero()),
|
||||
req.request.currency,
|
||||
)?;
|
||||
let connector_router_data =
|
||||
paypal::PaypalRouterData::try_from((amount, Some(shipping_cost), None, None, req))?;
|
||||
let connector_req = paypal::PaypalPaymentsRequest::try_from(&connector_router_data)?;
|
||||
Ok(RequestContent::Json(Box::new(connector_req)))
|
||||
}
|
||||
@ -1432,7 +1461,7 @@ impl ConnectorIntegration<api::Capture, types::PaymentsCaptureData, types::Payme
|
||||
req.request.currency,
|
||||
)?;
|
||||
let connector_router_data =
|
||||
paypal::PaypalRouterData::try_from((amount_to_capture, None, None, req))?;
|
||||
paypal::PaypalRouterData::try_from((amount_to_capture, None, None, None, req))?;
|
||||
let connector_req = paypal::PaypalPaymentsCaptureRequest::try_from(&connector_router_data)?;
|
||||
Ok(RequestContent::Json(Box::new(connector_req)))
|
||||
}
|
||||
@ -1599,7 +1628,8 @@ impl ConnectorIntegration<api::Execute, types::RefundsData, types::RefundsRespon
|
||||
req.request.minor_refund_amount,
|
||||
req.request.currency,
|
||||
)?;
|
||||
let connector_router_data = paypal::PaypalRouterData::try_from((amount, None, None, req))?;
|
||||
let connector_router_data =
|
||||
paypal::PaypalRouterData::try_from((amount, None, None, None, req))?;
|
||||
let connector_req = paypal::PaypalRefundRequest::try_from(&connector_router_data)?;
|
||||
Ok(RequestContent::Json(Box::new(connector_req)))
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ use crate::{
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct PaypalRouterData<T> {
|
||||
pub amount: StringMajorUnit,
|
||||
pub shipping_cost: Option<StringMajorUnit>,
|
||||
pub order_tax_amount: Option<StringMajorUnit>,
|
||||
pub order_amount: Option<StringMajorUnit>,
|
||||
pub router_data: T,
|
||||
@ -38,20 +39,23 @@ impl<T>
|
||||
StringMajorUnit,
|
||||
Option<StringMajorUnit>,
|
||||
Option<StringMajorUnit>,
|
||||
Option<StringMajorUnit>,
|
||||
T,
|
||||
)> for PaypalRouterData<T>
|
||||
{
|
||||
type Error = error_stack::Report<errors::ConnectorError>;
|
||||
fn try_from(
|
||||
(amount, order_tax_amount, order_amount, item): (
|
||||
(amount, shipping_cost, order_tax_amount, order_amount, item): (
|
||||
StringMajorUnit,
|
||||
Option<StringMajorUnit>,
|
||||
Option<StringMajorUnit>,
|
||||
Option<StringMajorUnit>,
|
||||
T,
|
||||
),
|
||||
) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
amount,
|
||||
shipping_cost,
|
||||
order_tax_amount,
|
||||
order_amount,
|
||||
router_data: item,
|
||||
@ -107,24 +111,47 @@ impl From<&PaypalRouterData<&types::PaymentsAuthorizeRouterData>> for OrderReque
|
||||
value: item.amount.clone(),
|
||||
},
|
||||
tax_total: None,
|
||||
shipping: Some(OrderAmount {
|
||||
currency_code: item.router_data.request.currency,
|
||||
value: item
|
||||
.shipping_cost
|
||||
.clone()
|
||||
.unwrap_or(StringMajorUnit::zero()),
|
||||
}),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&PaypalRouterData<&types::PaymentsPostSessionTokensRouterData>> for OrderRequestAmount {
|
||||
fn from(item: &PaypalRouterData<&types::PaymentsPostSessionTokensRouterData>) -> Self {
|
||||
Self {
|
||||
impl TryFrom<&PaypalRouterData<&types::PaymentsPostSessionTokensRouterData>>
|
||||
for OrderRequestAmount
|
||||
{
|
||||
type Error = error_stack::Report<errors::ConnectorError>;
|
||||
fn try_from(
|
||||
item: &PaypalRouterData<&types::PaymentsPostSessionTokensRouterData>,
|
||||
) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
currency_code: item.router_data.request.currency,
|
||||
value: item.amount.clone(),
|
||||
breakdown: AmountBreakdown {
|
||||
item_total: OrderAmount {
|
||||
currency_code: item.router_data.request.currency,
|
||||
value: item.amount.clone(),
|
||||
value: item.order_amount.clone().ok_or(
|
||||
errors::ConnectorError::MissingRequiredField {
|
||||
field_name: "order_amount",
|
||||
},
|
||||
)?,
|
||||
},
|
||||
tax_total: None,
|
||||
shipping: Some(OrderAmount {
|
||||
currency_code: item.router_data.request.currency,
|
||||
value: item
|
||||
.shipping_cost
|
||||
.clone()
|
||||
.unwrap_or(StringMajorUnit::zero()),
|
||||
}),
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,6 +180,13 @@ impl TryFrom<&PaypalRouterData<&types::SdkSessionUpdateRouterData>> for OrderReq
|
||||
},
|
||||
)?,
|
||||
}),
|
||||
shipping: Some(OrderAmount {
|
||||
currency_code: item.router_data.request.currency,
|
||||
value: item
|
||||
.shipping_cost
|
||||
.clone()
|
||||
.unwrap_or(StringMajorUnit::zero()),
|
||||
}),
|
||||
},
|
||||
})
|
||||
}
|
||||
@ -162,6 +196,7 @@ impl TryFrom<&PaypalRouterData<&types::SdkSessionUpdateRouterData>> for OrderReq
|
||||
pub struct AmountBreakdown {
|
||||
item_total: OrderAmount,
|
||||
tax_total: Option<OrderAmount>,
|
||||
shipping: Option<OrderAmount>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Serialize, Eq, PartialEq)]
|
||||
@ -206,9 +241,12 @@ impl From<&PaypalRouterData<&types::PaymentsAuthorizeRouterData>> for ItemDetail
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&PaypalRouterData<&types::PaymentsPostSessionTokensRouterData>> for ItemDetails {
|
||||
fn from(item: &PaypalRouterData<&types::PaymentsPostSessionTokensRouterData>) -> Self {
|
||||
Self {
|
||||
impl TryFrom<&PaypalRouterData<&types::PaymentsPostSessionTokensRouterData>> for ItemDetails {
|
||||
type Error = error_stack::Report<errors::ConnectorError>;
|
||||
fn try_from(
|
||||
item: &PaypalRouterData<&types::PaymentsPostSessionTokensRouterData>,
|
||||
) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
name: format!(
|
||||
"Payment for invoice {}",
|
||||
item.router_data.connector_request_reference_id
|
||||
@ -216,10 +254,14 @@ impl From<&PaypalRouterData<&types::PaymentsPostSessionTokensRouterData>> for It
|
||||
quantity: ORDER_QUANTITY,
|
||||
unit_amount: OrderAmount {
|
||||
currency_code: item.router_data.request.currency,
|
||||
value: item.amount.clone(),
|
||||
value: item.order_amount.clone().ok_or(
|
||||
errors::ConnectorError::MissingRequiredField {
|
||||
field_name: "order_amount",
|
||||
},
|
||||
)?,
|
||||
},
|
||||
tax: None,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -549,12 +591,12 @@ impl TryFrom<&PaypalRouterData<&types::PaymentsPostSessionTokensRouterData>>
|
||||
PaypalAuthType::try_from(&item.router_data.connector_auth_type)?;
|
||||
let payee = get_payee(&paypal_auth);
|
||||
|
||||
let amount = OrderRequestAmount::from(item);
|
||||
let amount = OrderRequestAmount::try_from(item)?;
|
||||
let connector_request_reference_id =
|
||||
item.router_data.connector_request_reference_id.clone();
|
||||
|
||||
let shipping_address = ShippingAddress::from(item);
|
||||
let item_details = vec![ItemDetails::from(item)];
|
||||
let item_details = vec![ItemDetails::try_from(item)?];
|
||||
|
||||
let purchase_units = vec![PurchaseUnitRequest {
|
||||
reference_id: Some(connector_request_reference_id.clone()),
|
||||
|
||||
@ -278,6 +278,7 @@ pub async fn construct_payment_router_data_for_authorize<'a>(
|
||||
charges: None,
|
||||
merchant_order_reference_id: None,
|
||||
integrity_object: None,
|
||||
shipping_cost: payment_data.payment_intent.amount_details.shipping_cost,
|
||||
};
|
||||
|
||||
// TODO: evaluate the fields in router data, if they are required or not
|
||||
@ -2150,6 +2151,7 @@ impl<F: Clone> TryFrom<PaymentAdditionalData<'_, F>> for types::PaymentsAuthoriz
|
||||
.payment_intent
|
||||
.merchant_order_reference_id
|
||||
.clone();
|
||||
let shipping_cost = payment_data.payment_intent.shipping_cost;
|
||||
|
||||
Ok(Self {
|
||||
payment_method_data: (payment_method_data.get_required_value("payment_method_data")?),
|
||||
@ -2196,6 +2198,7 @@ impl<F: Clone> TryFrom<PaymentAdditionalData<'_, F>> for types::PaymentsAuthoriz
|
||||
charges,
|
||||
merchant_order_reference_id,
|
||||
integrity_object: None,
|
||||
shipping_cost,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -2534,11 +2537,12 @@ impl<F: Clone> TryFrom<PaymentAdditionalData<'_, F>> for types::SdkPaymentsSessi
|
||||
+ shipping_cost
|
||||
+ surcharge_amount;
|
||||
Ok(Self {
|
||||
net_amount,
|
||||
amount: net_amount,
|
||||
order_tax_amount,
|
||||
currency: payment_data.currency,
|
||||
amount: payment_data.payment_intent.amount,
|
||||
order_amount: payment_data.payment_intent.amount,
|
||||
session_id: payment_data.session_id,
|
||||
shipping_cost: payment_data.payment_intent.shipping_cost,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -2575,9 +2579,11 @@ impl<F: Clone> TryFrom<PaymentAdditionalData<'_, F>> for types::PaymentsPostSess
|
||||
.clone();
|
||||
Ok(Self {
|
||||
amount, //need to change after we move to connector module
|
||||
order_amount: payment_data.payment_intent.amount,
|
||||
currency: payment_data.currency,
|
||||
merchant_order_reference_id,
|
||||
capture_method: payment_data.payment_attempt.capture_method,
|
||||
shipping_cost: payment_data.payment_intent.shipping_cost,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -2770,6 +2776,7 @@ impl<F: Clone> TryFrom<PaymentAdditionalData<'_, F>> for types::SetupMandateRequ
|
||||
| Some(RequestIncrementalAuthorization::Default)
|
||||
),
|
||||
metadata: payment_data.payment_intent.metadata.clone().map(Into::into),
|
||||
shipping_cost: payment_data.payment_intent.shipping_cost,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -879,6 +879,7 @@ impl ForeignFrom<&SetupMandateRouterData> for PaymentsAuthorizeData {
|
||||
charges: None, // TODO: allow charges on mandates?
|
||||
merchant_order_reference_id: None,
|
||||
integrity_object: None,
|
||||
shipping_cost: data.request.shipping_cost,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -57,6 +57,7 @@ impl VerifyConnectorData {
|
||||
charges: None,
|
||||
merchant_order_reference_id: None,
|
||||
integrity_object: None,
|
||||
shipping_cost: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -947,6 +947,7 @@ impl Default for PaymentAuthorizeType {
|
||||
charges: None,
|
||||
integrity_object: None,
|
||||
merchant_order_reference_id: None,
|
||||
shipping_cost: None,
|
||||
};
|
||||
Self(data)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user