feat(connector): [Stripe] Add support for refund webhooks (#1488)

This commit is contained in:
Sangamesh Kulkarni
2023-06-28 14:35:04 +05:30
committed by GitHub
parent 82545555d7
commit e6529b6a63
4 changed files with 64 additions and 40 deletions

View File

@ -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,

View File

@ -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

View File

@ -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,
}

View File

@ -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")?,