mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 00:49:42 +08:00
feat(connector): [facilitapay] fix refunds, add webhook and void support (#8778)
This commit is contained in:
@ -6157,8 +6157,8 @@ api_secret="Secret Key"
|
||||
key1="Username"
|
||||
[facilitapay.metadata.destination_account_number]
|
||||
name="destination_account_number"
|
||||
label="Destination Account Number"
|
||||
placeholder="Enter Destination Account Number"
|
||||
label="Merchant Account Number"
|
||||
placeholder="Enter Merchant's (to_bank_account_id) Account Number"
|
||||
required=true
|
||||
type="Text"
|
||||
|
||||
|
||||
@ -4725,8 +4725,8 @@ key1 = "Username"
|
||||
|
||||
[facilitapay.metadata.destination_account_number]
|
||||
name="destination_account_number"
|
||||
label="Destination Account Number"
|
||||
placeholder="Enter Destination Account Number"
|
||||
label="Merchant Account Number"
|
||||
placeholder="Enter Merchant's (to_bank_account_id) Account Number"
|
||||
required=true
|
||||
type="Text"
|
||||
|
||||
|
||||
@ -6139,8 +6139,8 @@ key1 = "Username"
|
||||
|
||||
[facilitapay.metadata.destination_account_number]
|
||||
name="destination_account_number"
|
||||
label="Destination Account Number"
|
||||
placeholder="Enter Destination Account Number"
|
||||
label="Merchant Account Number"
|
||||
placeholder="Enter Merchant's (to_bank_account_id) Account Number"
|
||||
required=true
|
||||
type="Text"
|
||||
|
||||
|
||||
@ -4,12 +4,13 @@ pub mod transformers;
|
||||
|
||||
use common_enums::enums;
|
||||
use common_utils::{
|
||||
crypto,
|
||||
errors::CustomResult,
|
||||
ext_traits::BytesExt,
|
||||
ext_traits::{ByteSliceExt, BytesExt, ValueExt},
|
||||
request::{Method, Request, RequestBuilder, RequestContent},
|
||||
types::{AmountConvertor, StringMajorUnit, StringMajorUnitForConnector},
|
||||
};
|
||||
use error_stack::{report, ResultExt};
|
||||
use error_stack::ResultExt;
|
||||
use hyperswitch_domain_models::{
|
||||
router_data::{AccessToken, ErrorResponse, RouterData},
|
||||
router_flow_types::{
|
||||
@ -30,8 +31,8 @@ use hyperswitch_domain_models::{
|
||||
SupportedPaymentMethods, SupportedPaymentMethodsExt,
|
||||
},
|
||||
types::{
|
||||
ConnectorCustomerRouterData, PaymentsAuthorizeRouterData, PaymentsCaptureRouterData,
|
||||
PaymentsSyncRouterData, RefundSyncRouterData, RefundsRouterData,
|
||||
ConnectorCustomerRouterData, PaymentsAuthorizeRouterData, PaymentsCancelRouterData,
|
||||
PaymentsCaptureRouterData, PaymentsSyncRouterData, RefundSyncRouterData, RefundsRouterData,
|
||||
},
|
||||
};
|
||||
use hyperswitch_interfaces::{
|
||||
@ -46,18 +47,19 @@ use hyperswitch_interfaces::{
|
||||
webhooks,
|
||||
};
|
||||
use lazy_static::lazy_static;
|
||||
use masking::{Mask, PeekInterface};
|
||||
use masking::{ExposeInterface, Mask, PeekInterface};
|
||||
use requests::{
|
||||
FacilitapayAuthRequest, FacilitapayCustomerRequest, FacilitapayPaymentsRequest,
|
||||
FacilitapayRefundRequest, FacilitapayRouterData,
|
||||
FacilitapayRouterData,
|
||||
};
|
||||
use responses::{
|
||||
FacilitapayAuthResponse, FacilitapayCustomerResponse, FacilitapayPaymentsResponse,
|
||||
FacilitapayRefundResponse,
|
||||
FacilitapayRefundResponse, FacilitapayWebhookEventType,
|
||||
};
|
||||
use transformers::parse_facilitapay_error_response;
|
||||
|
||||
use crate::{
|
||||
connectors::facilitapay::responses::FacilitapayVoidResponse,
|
||||
constants::headers,
|
||||
types::{RefreshTokenRouterData, ResponseRouterData},
|
||||
utils::{self, RefundsRequestData},
|
||||
@ -581,7 +583,72 @@ impl ConnectorIntegration<Capture, PaymentsCaptureData, PaymentsResponseData> fo
|
||||
}
|
||||
}
|
||||
|
||||
impl ConnectorIntegration<Void, PaymentsCancelData, PaymentsResponseData> for Facilitapay {}
|
||||
impl ConnectorIntegration<Void, PaymentsCancelData, PaymentsResponseData> for Facilitapay {
|
||||
fn get_headers(
|
||||
&self,
|
||||
req: &PaymentsCancelRouterData,
|
||||
connectors: &Connectors,
|
||||
) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> {
|
||||
self.build_headers(req, connectors)
|
||||
}
|
||||
|
||||
fn get_content_type(&self) -> &'static str {
|
||||
self.common_get_content_type()
|
||||
}
|
||||
|
||||
fn get_url(
|
||||
&self,
|
||||
req: &PaymentsCancelRouterData,
|
||||
connectors: &Connectors,
|
||||
) -> CustomResult<String, errors::ConnectorError> {
|
||||
Ok(format!(
|
||||
"{}/transactions/{}/refund",
|
||||
self.base_url(connectors),
|
||||
req.request.connector_transaction_id
|
||||
))
|
||||
}
|
||||
|
||||
fn build_request(
|
||||
&self,
|
||||
req: &PaymentsCancelRouterData,
|
||||
connectors: &Connectors,
|
||||
) -> CustomResult<Option<Request>, errors::ConnectorError> {
|
||||
let request = RequestBuilder::new()
|
||||
.method(Method::Get)
|
||||
.url(&types::PaymentsVoidType::get_url(self, req, connectors)?)
|
||||
.attach_default_headers()
|
||||
.headers(types::PaymentsVoidType::get_headers(self, req, connectors)?)
|
||||
.build();
|
||||
Ok(Some(request))
|
||||
}
|
||||
|
||||
fn handle_response(
|
||||
&self,
|
||||
data: &PaymentsCancelRouterData,
|
||||
event_builder: Option<&mut ConnectorEvent>,
|
||||
res: Response,
|
||||
) -> CustomResult<PaymentsCancelRouterData, errors::ConnectorError> {
|
||||
let response: FacilitapayVoidResponse = res
|
||||
.response
|
||||
.parse_struct("FacilitapayCancelResponse")
|
||||
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
|
||||
event_builder.map(|i| i.set_response_body(&response));
|
||||
router_env::logger::info!(connector_response=?response);
|
||||
RouterData::try_from(ResponseRouterData {
|
||||
response,
|
||||
data: data.clone(),
|
||||
http_code: res.status_code,
|
||||
})
|
||||
}
|
||||
|
||||
fn get_error_response(
|
||||
&self,
|
||||
res: Response,
|
||||
event_builder: Option<&mut ConnectorEvent>,
|
||||
) -> CustomResult<ErrorResponse, errors::ConnectorError> {
|
||||
self.build_error_response(res, event_builder)
|
||||
}
|
||||
}
|
||||
|
||||
impl ConnectorIntegration<Execute, RefundsData, RefundsResponseData> for Facilitapay {
|
||||
fn get_headers(
|
||||
@ -608,37 +675,27 @@ impl ConnectorIntegration<Execute, RefundsData, RefundsResponseData> for Facilit
|
||||
))
|
||||
}
|
||||
|
||||
fn get_request_body(
|
||||
&self,
|
||||
req: &RefundsRouterData<Execute>,
|
||||
_connectors: &Connectors,
|
||||
) -> CustomResult<RequestContent, errors::ConnectorError> {
|
||||
let refund_amount = utils::convert_amount(
|
||||
self.amount_converter,
|
||||
req.request.minor_refund_amount,
|
||||
req.request.currency,
|
||||
)?;
|
||||
|
||||
let connector_router_data = FacilitapayRouterData::from((refund_amount, req));
|
||||
let connector_req = FacilitapayRefundRequest::try_from(&connector_router_data)?;
|
||||
Ok(RequestContent::Json(Box::new(connector_req)))
|
||||
}
|
||||
|
||||
fn build_request(
|
||||
&self,
|
||||
req: &RefundsRouterData<Execute>,
|
||||
connectors: &Connectors,
|
||||
) -> CustomResult<Option<Request>, errors::ConnectorError> {
|
||||
// Validate that this is a full refund
|
||||
if req.request.payment_amount != req.request.refund_amount {
|
||||
return Err(errors::ConnectorError::NotSupported {
|
||||
message: "Partial refund not supported by Facilitapay".to_string(),
|
||||
connector: "Facilitapay",
|
||||
}
|
||||
.into());
|
||||
}
|
||||
|
||||
let request = RequestBuilder::new()
|
||||
.method(Method::Post)
|
||||
.method(Method::Get)
|
||||
.url(&types::RefundExecuteType::get_url(self, req, connectors)?)
|
||||
.attach_default_headers()
|
||||
.headers(types::RefundExecuteType::get_headers(
|
||||
self, req, connectors,
|
||||
)?)
|
||||
.set_body(types::RefundExecuteType::get_request_body(
|
||||
self, req, connectors,
|
||||
)?)
|
||||
.build();
|
||||
Ok(Some(request))
|
||||
}
|
||||
@ -743,25 +800,117 @@ impl ConnectorIntegration<RSync, RefundsData, RefundsResponseData> for Facilitap
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl webhooks::IncomingWebhook for Facilitapay {
|
||||
async fn verify_webhook_source(
|
||||
&self,
|
||||
request: &webhooks::IncomingWebhookRequestDetails<'_>,
|
||||
_merchant_id: &common_utils::id_type::MerchantId,
|
||||
connector_webhook_details: Option<common_utils::pii::SecretSerdeValue>,
|
||||
_connector_account_details: crypto::Encryptable<masking::Secret<serde_json::Value>>,
|
||||
_connector_name: &str,
|
||||
) -> CustomResult<bool, errors::ConnectorError> {
|
||||
let webhook_body: responses::FacilitapayWebhookNotification = request
|
||||
.body
|
||||
.parse_struct("FacilitapayWebhookNotification")
|
||||
.change_context(errors::ConnectorError::WebhookSourceVerificationFailed)?;
|
||||
|
||||
let connector_webhook_secrets = match connector_webhook_details {
|
||||
Some(secret_value) => {
|
||||
let secret = secret_value
|
||||
.parse_value::<api_models::admin::MerchantConnectorWebhookDetails>(
|
||||
"MerchantConnectorWebhookDetails",
|
||||
)
|
||||
.change_context(errors::ConnectorError::WebhookSourceVerificationFailed)?;
|
||||
secret.merchant_secret.expose()
|
||||
}
|
||||
None => "default_secret".to_string(),
|
||||
};
|
||||
|
||||
// FacilitaPay uses a simple 4-digit secret for verification
|
||||
Ok(webhook_body.notification.secret.peek() == &connector_webhook_secrets)
|
||||
}
|
||||
|
||||
fn get_webhook_object_reference_id(
|
||||
&self,
|
||||
_request: &webhooks::IncomingWebhookRequestDetails<'_>,
|
||||
request: &webhooks::IncomingWebhookRequestDetails<'_>,
|
||||
) -> CustomResult<api_models::webhooks::ObjectReferenceId, errors::ConnectorError> {
|
||||
Err(report!(errors::ConnectorError::WebhooksNotImplemented))
|
||||
let webhook_body: responses::FacilitapayWebhookNotification = request
|
||||
.body
|
||||
.parse_struct("FacilitapayWebhookNotification")
|
||||
.change_context(errors::ConnectorError::WebhookReferenceIdNotFound)?;
|
||||
|
||||
// Extract transaction ID from the webhook data
|
||||
let transaction_id = match &webhook_body.notification.data {
|
||||
responses::FacilitapayWebhookData::Transaction { transaction_id }
|
||||
| responses::FacilitapayWebhookData::CardPayment { transaction_id, .. } => {
|
||||
transaction_id.clone()
|
||||
}
|
||||
responses::FacilitapayWebhookData::Exchange {
|
||||
transaction_ids, ..
|
||||
}
|
||||
| responses::FacilitapayWebhookData::Wire {
|
||||
transaction_ids, ..
|
||||
}
|
||||
| responses::FacilitapayWebhookData::WireError {
|
||||
transaction_ids, ..
|
||||
} => transaction_ids
|
||||
.first()
|
||||
.ok_or(errors::ConnectorError::WebhookReferenceIdNotFound)?
|
||||
.clone(),
|
||||
};
|
||||
|
||||
// For refund webhooks, Facilitapay sends the original payment transaction ID
|
||||
// not the refund transaction ID
|
||||
Ok(api_models::webhooks::ObjectReferenceId::PaymentId(
|
||||
api_models::payments::PaymentIdType::ConnectorTransactionId(transaction_id),
|
||||
))
|
||||
}
|
||||
|
||||
fn get_webhook_event_type(
|
||||
&self,
|
||||
_request: &webhooks::IncomingWebhookRequestDetails<'_>,
|
||||
request: &webhooks::IncomingWebhookRequestDetails<'_>,
|
||||
) -> CustomResult<api_models::webhooks::IncomingWebhookEvent, errors::ConnectorError> {
|
||||
Err(report!(errors::ConnectorError::WebhooksNotImplemented))
|
||||
let webhook_body: responses::FacilitapayWebhookNotification = request
|
||||
.body
|
||||
.parse_struct("FacilitapayWebhookNotification")
|
||||
.change_context(errors::ConnectorError::WebhookEventTypeNotFound)?;
|
||||
|
||||
// Note: For "identified" events, we need additional logic to determine if it's cross-currency
|
||||
// Since we don't have access to the payment data here, we'll default to Success for now
|
||||
// The actual status determination happens in the webhook processing flow
|
||||
let event = match webhook_body.notification.event_type {
|
||||
FacilitapayWebhookEventType::ExchangeCreated => {
|
||||
api_models::webhooks::IncomingWebhookEvent::PaymentIntentProcessing
|
||||
}
|
||||
FacilitapayWebhookEventType::Identified
|
||||
| FacilitapayWebhookEventType::PaymentApproved
|
||||
| FacilitapayWebhookEventType::WireCreated => {
|
||||
api_models::webhooks::IncomingWebhookEvent::PaymentIntentSuccess
|
||||
}
|
||||
FacilitapayWebhookEventType::PaymentExpired
|
||||
| FacilitapayWebhookEventType::PaymentFailed => {
|
||||
api_models::webhooks::IncomingWebhookEvent::PaymentIntentFailure
|
||||
}
|
||||
FacilitapayWebhookEventType::PaymentRefunded => {
|
||||
api_models::webhooks::IncomingWebhookEvent::RefundSuccess
|
||||
}
|
||||
FacilitapayWebhookEventType::WireWaitingCorrection => {
|
||||
api_models::webhooks::IncomingWebhookEvent::PaymentActionRequired
|
||||
}
|
||||
};
|
||||
|
||||
Ok(event)
|
||||
}
|
||||
|
||||
fn get_webhook_resource_object(
|
||||
&self,
|
||||
_request: &webhooks::IncomingWebhookRequestDetails<'_>,
|
||||
request: &webhooks::IncomingWebhookRequestDetails<'_>,
|
||||
) -> CustomResult<Box<dyn masking::ErasedMaskSerialize>, errors::ConnectorError> {
|
||||
Err(report!(errors::ConnectorError::WebhooksNotImplemented))
|
||||
let webhook_body: responses::FacilitapayWebhookNotification = request
|
||||
.body
|
||||
.parse_struct("FacilitapayWebhookNotification")
|
||||
.change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?;
|
||||
|
||||
Ok(Box::new(webhook_body))
|
||||
}
|
||||
}
|
||||
|
||||
@ -794,7 +943,9 @@ lazy_static! {
|
||||
|
||||
facilitapay_supported_payment_methods
|
||||
};
|
||||
static ref FACILITAPAY_SUPPORTED_WEBHOOK_FLOWS: Vec<enums::EventClass> = Vec::new();
|
||||
static ref FACILITAPAY_SUPPORTED_WEBHOOK_FLOWS: Vec<enums::EventClass> = vec![
|
||||
enums::EventClass::Payments,
|
||||
];
|
||||
}
|
||||
|
||||
impl ConnectorSpecifications for Facilitapay {
|
||||
|
||||
@ -69,12 +69,6 @@ pub struct FacilitapayPaymentsRequest {
|
||||
pub transaction: FacilitapayTransactionRequest,
|
||||
}
|
||||
|
||||
// Type definition for RefundRequest
|
||||
#[derive(Default, Debug, Serialize)]
|
||||
pub struct FacilitapayRefundRequest {
|
||||
pub amount: StringMajorUnit,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, PartialEq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct FacilitapayCustomerRequest {
|
||||
|
||||
@ -136,6 +136,7 @@ pub struct BankAccountDetail {
|
||||
pub routing_number: Option<Secret<String>>,
|
||||
pub pix_info: Option<PixInfo>,
|
||||
pub owner_name: Option<Secret<String>>,
|
||||
pub owner_document_type: Option<String>,
|
||||
pub owner_document_number: Option<Secret<String>>,
|
||||
pub owner_company: Option<OwnerCompany>,
|
||||
pub internal: Option<bool>,
|
||||
@ -176,7 +177,7 @@ pub struct TransactionData {
|
||||
pub subject_is_receiver: Option<bool>,
|
||||
|
||||
// Source identification (potentially redundant with subject or card/bank info)
|
||||
pub source_name: Secret<String>,
|
||||
pub source_name: Option<Secret<String>>,
|
||||
pub source_document_type: DocumentType,
|
||||
pub source_document_number: Secret<String>,
|
||||
|
||||
@ -204,14 +205,124 @@ pub struct TransactionData {
|
||||
pub meta: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
// Void response structures (for /refund endpoint)
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct RefundData {
|
||||
pub struct VoidBankTransaction {
|
||||
#[serde(rename = "id")]
|
||||
pub refund_id: String,
|
||||
pub status: FacilitapayPaymentStatus,
|
||||
pub transaction_id: String,
|
||||
pub value: StringMajorUnit,
|
||||
pub currency: api_models::enums::Currency,
|
||||
pub iof_value: Option<StringMajorUnit>,
|
||||
pub fx_value: Option<StringMajorUnit>,
|
||||
pub exchange_rate: Option<StringMajorUnit>,
|
||||
pub exchange_currency: api_models::enums::Currency,
|
||||
pub exchanged_value: StringMajorUnit,
|
||||
pub exchange_approved: bool,
|
||||
pub wire_id: Option<String>,
|
||||
pub exchange_id: Option<String>,
|
||||
pub movement_date: String,
|
||||
pub source_name: Secret<String>,
|
||||
pub source_document_number: Secret<String>,
|
||||
pub source_document_type: String,
|
||||
pub source_id: String,
|
||||
pub source_type: String,
|
||||
pub source_description: String,
|
||||
pub source_bank: Option<String>,
|
||||
pub source_branch: Option<String>,
|
||||
pub source_account: Option<String>,
|
||||
pub source_bank_ispb: Option<String>,
|
||||
pub company_id: String,
|
||||
pub company_name: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct FacilitapayRefundResponse {
|
||||
pub data: RefundData,
|
||||
pub struct VoidData {
|
||||
#[serde(rename = "id")]
|
||||
pub void_id: String,
|
||||
pub reason: Option<String>,
|
||||
pub inserted_at: String,
|
||||
pub status: FacilitapayPaymentStatus,
|
||||
pub transaction_kind: String,
|
||||
pub bank_transaction: VoidBankTransaction,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct FacilitapayVoidResponse {
|
||||
pub data: VoidData,
|
||||
}
|
||||
|
||||
// Refund response uses the same TransactionData structure as payments
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct FacilitapayRefundResponse {
|
||||
pub data: TransactionData,
|
||||
}
|
||||
|
||||
// Webhook structures
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct FacilitapayWebhookNotification {
|
||||
pub notification: FacilitapayWebhookBody,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct FacilitapayWebhookBody {
|
||||
#[serde(rename = "type")]
|
||||
pub event_type: FacilitapayWebhookEventType,
|
||||
pub secret: Secret<String>,
|
||||
#[serde(flatten)]
|
||||
pub data: FacilitapayWebhookData,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum FacilitapayWebhookEventType {
|
||||
ExchangeCreated,
|
||||
Identified,
|
||||
PaymentApproved,
|
||||
PaymentExpired,
|
||||
PaymentFailed,
|
||||
PaymentRefunded,
|
||||
WireCreated,
|
||||
WireWaitingCorrection,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(rename_all = "UPPERCASE")]
|
||||
pub enum FacilitapayWebhookErrorCode {
|
||||
/// Creditor account number invalid or missing (branch_number or account_number incorrect)
|
||||
Ac03,
|
||||
/// Creditor account type missing or invalid (account_type incorrect)
|
||||
Ac14,
|
||||
/// Value in Creditor Identifier is incorrect (owner_document_number incorrect)
|
||||
Ch11,
|
||||
/// Transaction type not supported/authorized on this account (account rejected the payment)
|
||||
Ag03,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum FacilitapayWebhookData {
|
||||
CardPayment {
|
||||
transaction_id: String,
|
||||
checkout_id: Option<String>,
|
||||
},
|
||||
Exchange {
|
||||
exchange_id: String,
|
||||
transaction_ids: Vec<String>,
|
||||
},
|
||||
Transaction {
|
||||
transaction_id: String,
|
||||
},
|
||||
Wire {
|
||||
wire_id: String,
|
||||
transaction_ids: Vec<String>,
|
||||
},
|
||||
WireError {
|
||||
error_code: FacilitapayWebhookErrorCode,
|
||||
error_description: String,
|
||||
bank_account_owner_id: String,
|
||||
bank_account_id: String,
|
||||
transaction_ids: Vec<String>,
|
||||
wire_id: String,
|
||||
},
|
||||
}
|
||||
|
||||
@ -11,8 +11,11 @@ use error_stack::ResultExt;
|
||||
use hyperswitch_domain_models::{
|
||||
payment_method_data::{BankTransferData, PaymentMethodData},
|
||||
router_data::{AccessToken, ConnectorAuthType, ErrorResponse, RouterData},
|
||||
router_flow_types::refunds::{Execute, RSync},
|
||||
router_request_types::ResponseId,
|
||||
router_flow_types::{
|
||||
payments::Void,
|
||||
refunds::{Execute, RSync},
|
||||
},
|
||||
router_request_types::{PaymentsCancelData, ResponseId},
|
||||
router_response_types::{PaymentsResponseData, RefundsResponseData},
|
||||
types,
|
||||
};
|
||||
@ -27,12 +30,12 @@ use url::Url;
|
||||
use super::{
|
||||
requests::{
|
||||
DocumentType, FacilitapayAuthRequest, FacilitapayCredentials, FacilitapayCustomerRequest,
|
||||
FacilitapayPaymentsRequest, FacilitapayPerson, FacilitapayRefundRequest,
|
||||
FacilitapayRouterData, FacilitapayTransactionRequest, PixTransactionRequest,
|
||||
FacilitapayPaymentsRequest, FacilitapayPerson, FacilitapayRouterData,
|
||||
FacilitapayTransactionRequest, PixTransactionRequest,
|
||||
},
|
||||
responses::{
|
||||
FacilitapayAuthResponse, FacilitapayCustomerResponse, FacilitapayPaymentStatus,
|
||||
FacilitapayPaymentsResponse, FacilitapayRefundResponse,
|
||||
FacilitapayPaymentsResponse, FacilitapayRefundResponse, FacilitapayVoidResponse,
|
||||
},
|
||||
};
|
||||
use crate::{
|
||||
@ -509,17 +512,6 @@ fn get_qr_code_data(
|
||||
.change_context(errors::ConnectorError::ResponseHandlingFailed)
|
||||
}
|
||||
|
||||
impl<F> TryFrom<&FacilitapayRouterData<&types::RefundsRouterData<F>>> for FacilitapayRefundRequest {
|
||||
type Error = Error;
|
||||
fn try_from(
|
||||
item: &FacilitapayRouterData<&types::RefundsRouterData<F>>,
|
||||
) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
amount: item.amount.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FacilitapayPaymentStatus> for enums::RefundStatus {
|
||||
fn from(item: FacilitapayPaymentStatus) -> Self {
|
||||
match item {
|
||||
@ -532,6 +524,56 @@ impl From<FacilitapayPaymentStatus> for enums::RefundStatus {
|
||||
}
|
||||
}
|
||||
|
||||
// Void (cancel unprocessed payment) transformer
|
||||
impl
|
||||
TryFrom<
|
||||
ResponseRouterData<Void, FacilitapayVoidResponse, PaymentsCancelData, PaymentsResponseData>,
|
||||
> for RouterData<Void, PaymentsCancelData, PaymentsResponseData>
|
||||
{
|
||||
type Error = Error;
|
||||
fn try_from(
|
||||
item: ResponseRouterData<
|
||||
Void,
|
||||
FacilitapayVoidResponse,
|
||||
PaymentsCancelData,
|
||||
PaymentsResponseData,
|
||||
>,
|
||||
) -> Result<Self, Self::Error> {
|
||||
let status = common_enums::AttemptStatus::from(item.response.data.status.clone());
|
||||
|
||||
Ok(Self {
|
||||
status,
|
||||
response: if is_payment_failure(status) {
|
||||
Err(ErrorResponse {
|
||||
code: item.response.data.status.clone().to_string(),
|
||||
message: item.response.data.status.clone().to_string(),
|
||||
reason: item.response.data.reason,
|
||||
status_code: item.http_code,
|
||||
attempt_status: None,
|
||||
connector_transaction_id: Some(item.response.data.void_id.clone()),
|
||||
network_decline_code: None,
|
||||
network_advice_code: None,
|
||||
network_error_message: None,
|
||||
})
|
||||
} else {
|
||||
Ok(PaymentsResponseData::TransactionResponse {
|
||||
resource_id: ResponseId::ConnectorTransactionId(
|
||||
item.response.data.void_id.clone(),
|
||||
),
|
||||
redirection_data: Box::new(None),
|
||||
mandate_reference: Box::new(None),
|
||||
connector_metadata: None,
|
||||
network_txn_id: None,
|
||||
connector_response_reference_id: Some(item.response.data.void_id),
|
||||
incremental_authorization_allowed: None,
|
||||
charges: None,
|
||||
})
|
||||
},
|
||||
..item.data
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<RefundsResponseRouterData<Execute, FacilitapayRefundResponse>>
|
||||
for types::RefundsRouterData<Execute>
|
||||
{
|
||||
@ -541,7 +583,7 @@ impl TryFrom<RefundsResponseRouterData<Execute, FacilitapayRefundResponse>>
|
||||
) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
response: Ok(RefundsResponseData {
|
||||
connector_refund_id: item.response.data.refund_id.to_string(),
|
||||
connector_refund_id: item.response.data.transaction_id.clone(),
|
||||
refund_status: enums::RefundStatus::from(item.response.data.status),
|
||||
}),
|
||||
..item.data
|
||||
@ -558,7 +600,7 @@ impl TryFrom<RefundsResponseRouterData<RSync, FacilitapayRefundResponse>>
|
||||
) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
response: Ok(RefundsResponseData {
|
||||
connector_refund_id: item.response.data.refund_id.to_string(),
|
||||
connector_refund_id: item.response.data.transaction_id.clone(),
|
||||
refund_status: enums::RefundStatus::from(item.response.data.status),
|
||||
}),
|
||||
..item.data
|
||||
|
||||
Reference in New Issue
Block a user