mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 17:19:15 +08:00
feat(connector): [Stripe] Add support for refund webhooks (#1488)
This commit is contained in:
committed by
GitHub
parent
82545555d7
commit
e6529b6a63
@ -41,21 +41,22 @@ pub enum WebhookFlow {
|
||||
impl From<IncomingWebhookEvent> for WebhookFlow {
|
||||
fn from(evt: IncomingWebhookEvent) -> Self {
|
||||
match evt {
|
||||
IncomingWebhookEvent::PaymentIntentFailure => Self::Payment,
|
||||
IncomingWebhookEvent::PaymentIntentSuccess => Self::Payment,
|
||||
IncomingWebhookEvent::PaymentIntentProcessing => Self::Payment,
|
||||
IncomingWebhookEvent::PaymentActionRequired => Self::Payment,
|
||||
IncomingWebhookEvent::PaymentIntentPartiallyFunded => Self::Payment,
|
||||
IncomingWebhookEvent::PaymentIntentFailure
|
||||
| IncomingWebhookEvent::PaymentIntentSuccess
|
||||
| IncomingWebhookEvent::PaymentIntentProcessing
|
||||
| IncomingWebhookEvent::PaymentActionRequired
|
||||
| IncomingWebhookEvent::PaymentIntentPartiallyFunded => Self::Payment,
|
||||
IncomingWebhookEvent::EventNotSupported => Self::ReturnResponse,
|
||||
IncomingWebhookEvent::RefundSuccess => Self::Refund,
|
||||
IncomingWebhookEvent::RefundFailure => Self::Refund,
|
||||
IncomingWebhookEvent::DisputeOpened => Self::Dispute,
|
||||
IncomingWebhookEvent::DisputeAccepted => Self::Dispute,
|
||||
IncomingWebhookEvent::DisputeExpired => Self::Dispute,
|
||||
IncomingWebhookEvent::DisputeCancelled => Self::Dispute,
|
||||
IncomingWebhookEvent::DisputeChallenged => Self::Dispute,
|
||||
IncomingWebhookEvent::DisputeWon => Self::Dispute,
|
||||
IncomingWebhookEvent::DisputeLost => Self::Dispute,
|
||||
IncomingWebhookEvent::RefundSuccess | IncomingWebhookEvent::RefundFailure => {
|
||||
Self::Refund
|
||||
}
|
||||
IncomingWebhookEvent::DisputeOpened
|
||||
| IncomingWebhookEvent::DisputeAccepted
|
||||
| IncomingWebhookEvent::DisputeExpired
|
||||
| IncomingWebhookEvent::DisputeCancelled
|
||||
| IncomingWebhookEvent::DisputeChallenged
|
||||
| IncomingWebhookEvent::DisputeWon
|
||||
| IncomingWebhookEvent::DisputeLost => Self::Dispute,
|
||||
IncomingWebhookEvent::EndpointVerification => Self::ReturnResponse,
|
||||
IncomingWebhookEvent::SourceChargeable
|
||||
| IncomingWebhookEvent::SourceTransactionCreated => Self::BankTransfer,
|
||||
|
||||
@ -1744,6 +1744,13 @@ impl api::IncomingWebhook for Stripe {
|
||||
),
|
||||
)
|
||||
}
|
||||
stripe::WebhookEventObjectType::Refund => {
|
||||
api_models::webhooks::ObjectReferenceId::RefundId(
|
||||
api_models::webhooks::RefundIdType::ConnectorRefundId(
|
||||
details.event_data.event_object.id,
|
||||
),
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -1753,7 +1760,7 @@ impl api::IncomingWebhook for Stripe {
|
||||
) -> CustomResult<api::IncomingWebhookEvent, errors::ConnectorError> {
|
||||
let details: stripe::WebhookEventTypeBody = request
|
||||
.body
|
||||
.parse_struct("WebhookEvent")
|
||||
.parse_struct("WebhookEventTypeBody")
|
||||
.change_context(errors::ConnectorError::WebhookReferenceIdNotFound)?;
|
||||
|
||||
Ok(match details.event_type {
|
||||
@ -1773,6 +1780,18 @@ impl api::IncomingWebhook for Stripe {
|
||||
api::IncomingWebhookEvent::EventNotSupported
|
||||
}
|
||||
}
|
||||
stripe::WebhookEventType::ChargeRefundUpdated => details
|
||||
.event_data
|
||||
.event_object
|
||||
.status
|
||||
.map(|status| match status {
|
||||
stripe::WebhookEventStatus::Succeeded => {
|
||||
api::IncomingWebhookEvent::RefundSuccess
|
||||
}
|
||||
stripe::WebhookEventStatus::Failed => api::IncomingWebhookEvent::RefundFailure,
|
||||
_ => api::IncomingWebhookEvent::EventNotSupported,
|
||||
})
|
||||
.unwrap_or(api::IncomingWebhookEvent::EventNotSupported),
|
||||
stripe::WebhookEventType::SourceChargeable => {
|
||||
api::IncomingWebhookEvent::SourceChargeable
|
||||
}
|
||||
@ -1799,7 +1818,7 @@ impl api::IncomingWebhook for Stripe {
|
||||
| stripe::WebhookEventType::ChargeFailed
|
||||
| stripe::WebhookEventType::ChargePending
|
||||
| stripe::WebhookEventType::ChargeUpdated
|
||||
| stripe::WebhookEventType::ChanrgeRefunded
|
||||
| stripe::WebhookEventType::ChargeRefunded
|
||||
| stripe::WebhookEventType::PaymentIntentCanceled
|
||||
| stripe::WebhookEventType::PaymentIntentCreated
|
||||
| stripe::WebhookEventType::PaymentIntentProcessing
|
||||
|
||||
@ -571,6 +571,7 @@ pub enum StripeBankNames {
|
||||
Boz,
|
||||
}
|
||||
|
||||
// This is used only for Disputes
|
||||
impl From<WebhookEventStatus> for api_models::webhooks::IncomingWebhookEvent {
|
||||
fn from(value: WebhookEventStatus) -> Self {
|
||||
match value {
|
||||
@ -590,6 +591,7 @@ impl From<WebhookEventStatus> for api_models::webhooks::IncomingWebhookEvent {
|
||||
| WebhookEventStatus::RequiresCapture
|
||||
| WebhookEventStatus::Canceled
|
||||
| WebhookEventStatus::Chargeable
|
||||
| WebhookEventStatus::Failed
|
||||
| WebhookEventStatus::Unknown => Self::EventNotSupported,
|
||||
}
|
||||
}
|
||||
@ -2371,6 +2373,7 @@ pub enum WebhookEventObjectType {
|
||||
Dispute,
|
||||
Charge,
|
||||
Source,
|
||||
Refund,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
@ -2399,12 +2402,14 @@ pub enum WebhookEventType {
|
||||
ChargePending,
|
||||
#[serde(rename = "charge.captured")]
|
||||
ChargeCaptured,
|
||||
#[serde(rename = "charge.refund.updated")]
|
||||
ChargeRefundUpdated,
|
||||
#[serde(rename = "charge.succeeded")]
|
||||
ChargeSucceeded,
|
||||
#[serde(rename = "charge.updated")]
|
||||
ChargeUpdated,
|
||||
#[serde(rename = "charge.refunded")]
|
||||
ChanrgeRefunded,
|
||||
ChargeRefunded,
|
||||
#[serde(rename = "payment_intent.canceled")]
|
||||
PaymentIntentCanceled,
|
||||
#[serde(rename = "payment_intent.created")]
|
||||
@ -2444,6 +2449,7 @@ pub enum WebhookEventStatus {
|
||||
RequiresCapture,
|
||||
Canceled,
|
||||
Chargeable,
|
||||
Failed,
|
||||
#[serde(other)]
|
||||
Unknown,
|
||||
}
|
||||
|
||||
@ -117,9 +117,17 @@ pub async fn refunds_incoming_webhook_flow<W: api::OutgoingWebhookType>(
|
||||
let db = &*state.store;
|
||||
//find refund by connector refund id
|
||||
let refund = match webhook_details.object_reference_id {
|
||||
api_models::webhooks::ObjectReferenceId::RefundId(
|
||||
api_models::webhooks::RefundIdType::ConnectorRefundId(id),
|
||||
) => db
|
||||
api_models::webhooks::ObjectReferenceId::RefundId(refund_id_type) => match refund_id_type {
|
||||
api_models::webhooks::RefundIdType::RefundId(id) => db
|
||||
.find_refund_by_merchant_id_refund_id(
|
||||
&merchant_account.merchant_id,
|
||||
&id,
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::WebhookResourceNotFound)
|
||||
.attach_printable_lazy(|| "Failed fetching the refund")?,
|
||||
api_models::webhooks::RefundIdType::ConnectorRefundId(id) => db
|
||||
.find_refund_by_merchant_id_connector_refund_id_connector(
|
||||
&merchant_account.merchant_id,
|
||||
&id,
|
||||
@ -129,17 +137,7 @@ pub async fn refunds_incoming_webhook_flow<W: api::OutgoingWebhookType>(
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::WebhookResourceNotFound)
|
||||
.attach_printable_lazy(|| "Failed fetching the refund")?,
|
||||
api_models::webhooks::ObjectReferenceId::RefundId(
|
||||
api_models::webhooks::RefundIdType::RefundId(id),
|
||||
) => db
|
||||
.find_refund_by_merchant_id_refund_id(
|
||||
&merchant_account.merchant_id,
|
||||
&id,
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::WebhookResourceNotFound)
|
||||
.attach_printable_lazy(|| "Failed fetching the refund")?,
|
||||
},
|
||||
_ => Err(errors::ApiErrorResponse::WebhookProcessingFailure)
|
||||
.into_report()
|
||||
.attach_printable("received a non-refund id when processing refund webhooks")?,
|
||||
|
||||
Reference in New Issue
Block a user