Skip to content
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions api-reference-v2/openapi_spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -4828,7 +4828,8 @@
"failure",
"payment_method_awaited",
"confirmation_awaited",
"device_data_collection_pending"
"device_data_collection_pending",
"integrity_failure"
]
},
"AuthenticationConnectorDetails": {
Expand Down Expand Up @@ -12375,7 +12376,8 @@
"requires_confirmation",
"requires_capture",
"partially_captured",
"partially_captured_and_capturable"
"partially_captured_and_capturable",
"conflicted"
]
},
"JCSVoucherData": {
Expand Down
6 changes: 4 additions & 2 deletions api-reference/openapi_spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -6808,7 +6808,8 @@
"failure",
"payment_method_awaited",
"confirmation_awaited",
"device_data_collection_pending"
"device_data_collection_pending",
"integrity_failure"
]
},
"AuthenticationConnectorDetails": {
Expand Down Expand Up @@ -14609,7 +14610,8 @@
"requires_confirmation",
"requires_capture",
"partially_captured",
"partially_captured_and_capturable"
"partially_captured_and_capturable",
"conflicted"
]
},
"IssuerData": {
Expand Down
14 changes: 10 additions & 4 deletions crates/common_enums/src/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ pub enum AttemptStatus {
PaymentMethodAwaited,
ConfirmationAwaited,
DeviceDataCollectionPending,
IntegrityFailure,
}

impl AttemptStatus {
Expand Down Expand Up @@ -183,7 +184,8 @@ impl AttemptStatus {
| Self::Pending
| Self::PaymentMethodAwaited
| Self::ConfirmationAwaited
| Self::DeviceDataCollectionPending => false,
| Self::DeviceDataCollectionPending
| Self::IntegrityFailure => false,
}
}
}
Expand Down Expand Up @@ -1599,6 +1601,8 @@ pub enum IntentStatus {
PartiallyCaptured,
/// The payment has been captured partially and the remaining amount is capturable
PartiallyCapturedAndCapturable,
/// There has been a discrepancy between the amount/currency sent in the request and the amount/currency received by the processor
Conflicted,
}

impl IntentStatus {
Expand All @@ -1612,7 +1616,8 @@ impl IntentStatus {
| Self::RequiresPaymentMethod
| Self::RequiresConfirmation
| Self::RequiresCapture
| Self::PartiallyCapturedAndCapturable => false,
| Self::PartiallyCapturedAndCapturable
| Self::Conflicted => false,
}
}

Expand All @@ -1627,7 +1632,7 @@ impl IntentStatus {
| Self::Failed
| Self::Cancelled
| Self::PartiallyCaptured
| Self::RequiresCapture => false,
| Self::RequiresCapture | Self::Conflicted => false,
Self::Processing
| Self::RequiresCustomerAction
| Self::RequiresMerchantAction
Expand Down Expand Up @@ -1747,7 +1752,8 @@ impl From<AttemptStatus> for PaymentMethodStatus {
| AttemptStatus::PartialCharged
| AttemptStatus::PartialChargedAndChargeable
| AttemptStatus::ConfirmationAwaited
| AttemptStatus::DeviceDataCollectionPending => Self::Inactive,
| AttemptStatus::DeviceDataCollectionPending
| AttemptStatus::IntegrityFailure => Self::Inactive,
AttemptStatus::Charged | AttemptStatus::Authorized => Self::Active,
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/common_enums/src/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2095,7 +2095,7 @@ impl From<AttemptStatus> for IntentStatus {
Self::RequiresCustomerAction
}
AttemptStatus::Unresolved => Self::RequiresMerchantAction,

AttemptStatus::IntegrityFailure => Self::Conflicted,
AttemptStatus::PartialCharged => Self::PartiallyCaptured,
AttemptStatus::PartialChargedAndChargeable => Self::PartiallyCapturedAndCapturable,
AttemptStatus::Started
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -685,13 +685,12 @@ impl TryFrom<enums::AttemptStatus> for ChargebeeRecordStatus {
| enums::AttemptStatus::Pending
| enums::AttemptStatus::PaymentMethodAwaited
| enums::AttemptStatus::ConfirmationAwaited
| enums::AttemptStatus::DeviceDataCollectionPending => {
Err(errors::ConnectorError::NotSupported {
message: "Record back flow is only supported for terminal status".to_string(),
connector: "chargebee",
}
.into())
| enums::AttemptStatus::DeviceDataCollectionPending
| enums::AttemptStatus::IntegrityFailure => Err(errors::ConnectorError::NotSupported {
message: "Record back flow is only supported for terminal status".to_string(),
connector: "chargebee",
}
.into()),
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2530,9 +2530,8 @@ impl TryFrom<PaymentsCaptureResponseRouterData<PaypalCaptureResponse>>
| storage_enums::AttemptStatus::Voided => 0,
storage_enums::AttemptStatus::Charged
| storage_enums::AttemptStatus::PartialCharged
| storage_enums::AttemptStatus::PartialChargedAndChargeable => {
item.data.request.amount_to_capture
}
| storage_enums::AttemptStatus::PartialChargedAndChargeable
| storage_enums::AttemptStatus::IntegrityFailure => item.data.request.amount_to_capture,
};
let connector_payment_id: PaypalMeta =
to_connector_meta(item.data.request.connector_meta.clone())?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,13 +273,12 @@ impl TryFrom<enums::AttemptStatus> for RecurlyRecordStatus {
| enums::AttemptStatus::Pending
| enums::AttemptStatus::PaymentMethodAwaited
| enums::AttemptStatus::ConfirmationAwaited
| enums::AttemptStatus::DeviceDataCollectionPending => {
Err(errors::ConnectorError::NotSupported {
message: "Record back flow is only supported for terminal status".to_string(),
connector: "recurly",
}
.into())
| enums::AttemptStatus::DeviceDataCollectionPending
| enums::AttemptStatus::IntegrityFailure => Err(errors::ConnectorError::NotSupported {
message: "Record back flow is only supported for terminal status".to_string(),
connector: "recurly",
}
.into()),
}
}
}
Expand Down
51 changes: 49 additions & 2 deletions crates/hyperswitch_connectors/src/connectors/trustpay.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
pub mod transformers;

use base64::Engine;
use common_enums::{enums, PaymentAction};
use common_utils::{
Expand Down Expand Up @@ -54,7 +53,7 @@ use transformers as trustpay;
use crate::{
constants::headers,
types::ResponseRouterData,
utils::{self, ConnectorErrorType, PaymentsPreProcessingRequestData},
utils::{self, self as connector_utils, ConnectorErrorType, PaymentsPreProcessingRequestData},
};

#[derive(Clone)]
Expand Down Expand Up @@ -424,6 +423,31 @@ impl ConnectorIntegration<PSync, PaymentsSyncData, PaymentsResponseData> for Tru
.parse_struct("trustpay PaymentsResponse")
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;

if let trustpay::TrustpayPaymentsResponse::WebhookResponse(ref webhook_response) = response
{
let response_integrity_object = connector_utils::get_sync_integrity_object(
self.amount_converter_to_float_major_unit,
webhook_response.amount.amount,
webhook_response.amount.currency.to_string(),
)?;

event_builder.map(|i| i.set_response_body(&response));
router_env::logger::info!(connector_response=?response);

let new_router_data = RouterData::try_from(ResponseRouterData {
response,
data: data.clone(),
http_code: res.status_code,
});

return new_router_data
.map(|mut router_data| {
router_data.request.integrity_object = Some(response_integrity_object);
router_data
})
.change_context(errors::ConnectorError::ResponseHandlingFailed);
}

event_builder.map(|i| i.set_response_body(&response));
router_env::logger::info!(connector_response=?response);

Expand Down Expand Up @@ -810,6 +834,29 @@ impl ConnectorIntegration<RSync, RefundsData, RefundsResponseData> for Trustpay
.parse_struct("trustpay RefundResponse")
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;

if let trustpay::RefundResponse::WebhookRefund(ref webhook_response) = response {
let response_integrity_object = connector_utils::get_refund_integrity_object(
self.amount_converter_to_float_major_unit,
webhook_response.amount.amount,
webhook_response.amount.currency.to_string(),
)?;

event_builder.map(|i| i.set_response_body(&response));
router_env::logger::info!(connector_response=?response);

let new_router_data = RouterData::try_from(ResponseRouterData {
response,
data: data.clone(),
http_code: res.status_code,
});

return new_router_data
.map(|mut router_data| {
router_data.request.integrity_object = Some(response_integrity_object);
router_data
})
.change_context(errors::ConnectorError::ResponseHandlingFailed);
}
event_builder.map(|i| i.set_response_body(&response));
router_env::logger::info!(connector_response=?response);

Expand Down
6 changes: 4 additions & 2 deletions crates/hyperswitch_connectors/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,8 @@ pub(crate) fn is_payment_failure(status: AttemptStatus) -> bool {
| AttemptStatus::Pending
| AttemptStatus::PaymentMethodAwaited
| AttemptStatus::ConfirmationAwaited
| AttemptStatus::DeviceDataCollectionPending => false,
| AttemptStatus::DeviceDataCollectionPending
| AttemptStatus::IntegrityFailure => false,
}
}

Expand Down Expand Up @@ -6172,7 +6173,8 @@ impl FrmTransactionRouterDataRequest for FrmTransactionRouterData {
AttemptStatus::AuthenticationSuccessful
| AttemptStatus::PartialChargedAndChargeable
| AttemptStatus::Authorized
| AttemptStatus::Charged => Some(true),
| AttemptStatus::Charged
| AttemptStatus::IntegrityFailure => Some(true),

AttemptStatus::Started
| AttemptStatus::AuthenticationPending
Expand Down
20 changes: 12 additions & 8 deletions crates/hyperswitch_domain_models/src/router_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,8 @@ impl
// So set the amount capturable to zero
common_enums::IntentStatus::Succeeded
| common_enums::IntentStatus::Failed
| common_enums::IntentStatus::Cancelled => Some(MinorUnit::zero()),
| common_enums::IntentStatus::Cancelled
| common_enums::IntentStatus::Conflicted => Some(MinorUnit::zero()),
// For these statuses, update the capturable amount when it reaches terminal / capturable state
common_enums::IntentStatus::RequiresCustomerAction
| common_enums::IntentStatus::RequiresMerchantAction
Expand Down Expand Up @@ -726,7 +727,7 @@ impl
match intent_status {
// If the status is succeeded then we have captured the whole amount
// we need not check for `amount_to_capture` here because passing `amount_to_capture` when authorizing is not supported
common_enums::IntentStatus::Succeeded => {
common_enums::IntentStatus::Succeeded | common_enums::IntentStatus::Conflicted => {
let total_amount = payment_data.payment_attempt.amount_details.get_net_amount();
Some(total_amount)
}
Expand Down Expand Up @@ -912,7 +913,8 @@ impl
// If the status is already succeeded / failed we cannot capture any more amount
common_enums::IntentStatus::Succeeded
| common_enums::IntentStatus::Failed
| common_enums::IntentStatus::Cancelled => Some(MinorUnit::zero()),
| common_enums::IntentStatus::Cancelled
| common_enums::IntentStatus::Conflicted => Some(MinorUnit::zero()),
// For these statuses, update the capturable amount when it reaches terminal / capturable state
common_enums::IntentStatus::RequiresCustomerAction
| common_enums::IntentStatus::RequiresMerchantAction
Expand All @@ -938,7 +940,7 @@ impl
let intent_status = common_enums::IntentStatus::from(self.status);
match intent_status {
// If the status is succeeded then we have captured the whole amount
common_enums::IntentStatus::Succeeded => {
common_enums::IntentStatus::Succeeded | common_enums::IntentStatus::Conflicted => {
let amount_to_capture = payment_data
.payment_attempt
.amount_details
Expand Down Expand Up @@ -1153,7 +1155,8 @@ impl
// If the status is already succeeded / failed we cannot capture any more amount
common_enums::IntentStatus::Succeeded
| common_enums::IntentStatus::Failed
| common_enums::IntentStatus::Cancelled => Some(MinorUnit::zero()),
| common_enums::IntentStatus::Cancelled
| common_enums::IntentStatus::Conflicted => Some(MinorUnit::zero()),
// For these statuses, update the capturable amount when it reaches terminal / capturable state
common_enums::IntentStatus::RequiresCustomerAction
| common_enums::IntentStatus::RequiresMerchantAction
Expand Down Expand Up @@ -1181,7 +1184,7 @@ impl
let intent_status = common_enums::IntentStatus::from(self.status);
match intent_status {
// If the status is succeeded then we have captured the whole amount or amount_to_capture
common_enums::IntentStatus::Succeeded => {
common_enums::IntentStatus::Succeeded | common_enums::IntentStatus::Conflicted => {
let amount_to_capture = payment_attempt.amount_details.get_amount_to_capture();

let amount_captured =
Expand Down Expand Up @@ -1385,7 +1388,8 @@ impl
// So set the amount capturable to zero
common_enums::IntentStatus::Succeeded
| common_enums::IntentStatus::Failed
| common_enums::IntentStatus::Cancelled => Some(MinorUnit::zero()),
| common_enums::IntentStatus::Cancelled
| common_enums::IntentStatus::Conflicted => Some(MinorUnit::zero()),
// For these statuses, update the capturable amount when it reaches terminal / capturable state
common_enums::IntentStatus::RequiresCustomerAction
| common_enums::IntentStatus::RequiresMerchantAction
Expand Down Expand Up @@ -1415,7 +1419,7 @@ impl
match intent_status {
// If the status is succeeded then we have captured the whole amount
// we need not check for `amount_to_capture` here because passing `amount_to_capture` when authorizing is not supported
common_enums::IntentStatus::Succeeded => {
common_enums::IntentStatus::Succeeded | common_enums::IntentStatus::Conflicted => {
let total_amount = payment_data.payment_attempt.amount_details.get_net_amount();
Some(total_amount)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,8 @@ impl From<api_enums::IntentStatus> for StripePaymentStatus {
api_enums::IntentStatus::Failed => Self::Canceled,
api_enums::IntentStatus::Processing => Self::Processing,
api_enums::IntentStatus::RequiresCustomerAction
| api_enums::IntentStatus::RequiresMerchantAction => Self::RequiresAction,
| api_enums::IntentStatus::RequiresMerchantAction
| api_enums::IntentStatus::Conflicted => Self::RequiresAction,
api_enums::IntentStatus::RequiresPaymentMethod => Self::RequiresPaymentMethod,
api_enums::IntentStatus::RequiresConfirmation => Self::RequiresConfirmation,
api_enums::IntentStatus::RequiresCapture
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,8 @@ impl From<api_enums::IntentStatus> for StripeSetupStatus {
api_enums::IntentStatus::Failed => Self::Canceled,
api_enums::IntentStatus::Processing => Self::Processing,
api_enums::IntentStatus::RequiresCustomerAction => Self::RequiresAction,
api_enums::IntentStatus::RequiresMerchantAction => Self::RequiresAction,
api_enums::IntentStatus::RequiresMerchantAction
| api_enums::IntentStatus::Conflicted => Self::RequiresAction,
api_enums::IntentStatus::RequiresPaymentMethod => Self::RequiresPaymentMethod,
api_enums::IntentStatus::RequiresConfirmation => Self::RequiresConfirmation,
api_enums::IntentStatus::RequiresCapture
Expand Down
6 changes: 4 additions & 2 deletions crates/router/src/connector/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2225,7 +2225,8 @@ impl FrmTransactionRouterDataRequest for fraud_check::FrmTransactionRouterData {
| storage_enums::AttemptStatus::Pending
| storage_enums::AttemptStatus::PaymentMethodAwaited
| storage_enums::AttemptStatus::ConfirmationAwaited
| storage_enums::AttemptStatus::DeviceDataCollectionPending => None,
| storage_enums::AttemptStatus::DeviceDataCollectionPending
| storage_enums::AttemptStatus::IntegrityFailure => None,
}
}
}
Expand Down Expand Up @@ -2255,7 +2256,8 @@ pub fn is_payment_failure(status: enums::AttemptStatus) -> bool {
| common_enums::AttemptStatus::Pending
| common_enums::AttemptStatus::PaymentMethodAwaited
| common_enums::AttemptStatus::ConfirmationAwaited
| common_enums::AttemptStatus::DeviceDataCollectionPending => false,
| common_enums::AttemptStatus::DeviceDataCollectionPending
| common_enums::AttemptStatus::IntegrityFailure => false,
}
}

Expand Down
1 change: 1 addition & 0 deletions crates/router/src/core/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2735,6 +2735,7 @@ impl ValidateStatusForOperation for &PaymentRedirectSync {
match intent_status {
common_enums::IntentStatus::RequiresCustomerAction => Ok(()),
common_enums::IntentStatus::Succeeded
| common_enums::IntentStatus::Conflicted
| common_enums::IntentStatus::Failed
| common_enums::IntentStatus::Cancelled
| common_enums::IntentStatus::Processing
Expand Down
Loading
Loading