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 { impl From<IncomingWebhookEvent> for WebhookFlow {
fn from(evt: IncomingWebhookEvent) -> Self { fn from(evt: IncomingWebhookEvent) -> Self {
match evt { match evt {
IncomingWebhookEvent::PaymentIntentFailure => Self::Payment, IncomingWebhookEvent::PaymentIntentFailure
IncomingWebhookEvent::PaymentIntentSuccess => Self::Payment, | IncomingWebhookEvent::PaymentIntentSuccess
IncomingWebhookEvent::PaymentIntentProcessing => Self::Payment, | IncomingWebhookEvent::PaymentIntentProcessing
IncomingWebhookEvent::PaymentActionRequired => Self::Payment, | IncomingWebhookEvent::PaymentActionRequired
IncomingWebhookEvent::PaymentIntentPartiallyFunded => Self::Payment, | IncomingWebhookEvent::PaymentIntentPartiallyFunded => Self::Payment,
IncomingWebhookEvent::EventNotSupported => Self::ReturnResponse, IncomingWebhookEvent::EventNotSupported => Self::ReturnResponse,
IncomingWebhookEvent::RefundSuccess => Self::Refund, IncomingWebhookEvent::RefundSuccess | IncomingWebhookEvent::RefundFailure => {
IncomingWebhookEvent::RefundFailure => Self::Refund, Self::Refund
IncomingWebhookEvent::DisputeOpened => Self::Dispute, }
IncomingWebhookEvent::DisputeAccepted => Self::Dispute, IncomingWebhookEvent::DisputeOpened
IncomingWebhookEvent::DisputeExpired => Self::Dispute, | IncomingWebhookEvent::DisputeAccepted
IncomingWebhookEvent::DisputeCancelled => Self::Dispute, | IncomingWebhookEvent::DisputeExpired
IncomingWebhookEvent::DisputeChallenged => Self::Dispute, | IncomingWebhookEvent::DisputeCancelled
IncomingWebhookEvent::DisputeWon => Self::Dispute, | IncomingWebhookEvent::DisputeChallenged
IncomingWebhookEvent::DisputeLost => Self::Dispute, | IncomingWebhookEvent::DisputeWon
| IncomingWebhookEvent::DisputeLost => Self::Dispute,
IncomingWebhookEvent::EndpointVerification => Self::ReturnResponse, IncomingWebhookEvent::EndpointVerification => Self::ReturnResponse,
IncomingWebhookEvent::SourceChargeable IncomingWebhookEvent::SourceChargeable
| IncomingWebhookEvent::SourceTransactionCreated => Self::BankTransfer, | 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> { ) -> CustomResult<api::IncomingWebhookEvent, errors::ConnectorError> {
let details: stripe::WebhookEventTypeBody = request let details: stripe::WebhookEventTypeBody = request
.body .body
.parse_struct("WebhookEvent") .parse_struct("WebhookEventTypeBody")
.change_context(errors::ConnectorError::WebhookReferenceIdNotFound)?; .change_context(errors::ConnectorError::WebhookReferenceIdNotFound)?;
Ok(match details.event_type { Ok(match details.event_type {
@ -1773,6 +1780,18 @@ impl api::IncomingWebhook for Stripe {
api::IncomingWebhookEvent::EventNotSupported 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 => { stripe::WebhookEventType::SourceChargeable => {
api::IncomingWebhookEvent::SourceChargeable api::IncomingWebhookEvent::SourceChargeable
} }
@ -1799,7 +1818,7 @@ impl api::IncomingWebhook for Stripe {
| stripe::WebhookEventType::ChargeFailed | stripe::WebhookEventType::ChargeFailed
| stripe::WebhookEventType::ChargePending | stripe::WebhookEventType::ChargePending
| stripe::WebhookEventType::ChargeUpdated | stripe::WebhookEventType::ChargeUpdated
| stripe::WebhookEventType::ChanrgeRefunded | stripe::WebhookEventType::ChargeRefunded
| stripe::WebhookEventType::PaymentIntentCanceled | stripe::WebhookEventType::PaymentIntentCanceled
| stripe::WebhookEventType::PaymentIntentCreated | stripe::WebhookEventType::PaymentIntentCreated
| stripe::WebhookEventType::PaymentIntentProcessing | stripe::WebhookEventType::PaymentIntentProcessing

View File

@ -571,6 +571,7 @@ pub enum StripeBankNames {
Boz, Boz,
} }
// This is used only for Disputes
impl From<WebhookEventStatus> for api_models::webhooks::IncomingWebhookEvent { impl From<WebhookEventStatus> for api_models::webhooks::IncomingWebhookEvent {
fn from(value: WebhookEventStatus) -> Self { fn from(value: WebhookEventStatus) -> Self {
match value { match value {
@ -590,6 +591,7 @@ impl From<WebhookEventStatus> for api_models::webhooks::IncomingWebhookEvent {
| WebhookEventStatus::RequiresCapture | WebhookEventStatus::RequiresCapture
| WebhookEventStatus::Canceled | WebhookEventStatus::Canceled
| WebhookEventStatus::Chargeable | WebhookEventStatus::Chargeable
| WebhookEventStatus::Failed
| WebhookEventStatus::Unknown => Self::EventNotSupported, | WebhookEventStatus::Unknown => Self::EventNotSupported,
} }
} }
@ -2371,6 +2373,7 @@ pub enum WebhookEventObjectType {
Dispute, Dispute,
Charge, Charge,
Source, Source,
Refund,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
@ -2399,12 +2402,14 @@ pub enum WebhookEventType {
ChargePending, ChargePending,
#[serde(rename = "charge.captured")] #[serde(rename = "charge.captured")]
ChargeCaptured, ChargeCaptured,
#[serde(rename = "charge.refund.updated")]
ChargeRefundUpdated,
#[serde(rename = "charge.succeeded")] #[serde(rename = "charge.succeeded")]
ChargeSucceeded, ChargeSucceeded,
#[serde(rename = "charge.updated")] #[serde(rename = "charge.updated")]
ChargeUpdated, ChargeUpdated,
#[serde(rename = "charge.refunded")] #[serde(rename = "charge.refunded")]
ChanrgeRefunded, ChargeRefunded,
#[serde(rename = "payment_intent.canceled")] #[serde(rename = "payment_intent.canceled")]
PaymentIntentCanceled, PaymentIntentCanceled,
#[serde(rename = "payment_intent.created")] #[serde(rename = "payment_intent.created")]
@ -2444,6 +2449,7 @@ pub enum WebhookEventStatus {
RequiresCapture, RequiresCapture,
Canceled, Canceled,
Chargeable, Chargeable,
Failed,
#[serde(other)] #[serde(other)]
Unknown, Unknown,
} }

View File

@ -117,29 +117,27 @@ pub async fn refunds_incoming_webhook_flow<W: api::OutgoingWebhookType>(
let db = &*state.store; let db = &*state.store;
//find refund by connector refund id //find refund by connector refund id
let refund = match webhook_details.object_reference_id { let refund = match webhook_details.object_reference_id {
api_models::webhooks::ObjectReferenceId::RefundId( api_models::webhooks::ObjectReferenceId::RefundId(refund_id_type) => match refund_id_type {
api_models::webhooks::RefundIdType::ConnectorRefundId(id), api_models::webhooks::RefundIdType::RefundId(id) => db
) => db .find_refund_by_merchant_id_refund_id(
.find_refund_by_merchant_id_connector_refund_id_connector( &merchant_account.merchant_id,
&merchant_account.merchant_id, &id,
&id, merchant_account.storage_scheme,
connector_name, )
merchant_account.storage_scheme, .await
) .change_context(errors::ApiErrorResponse::WebhookResourceNotFound)
.await .attach_printable_lazy(|| "Failed fetching the refund")?,
.change_context(errors::ApiErrorResponse::WebhookResourceNotFound) api_models::webhooks::RefundIdType::ConnectorRefundId(id) => db
.attach_printable_lazy(|| "Failed fetching the refund")?, .find_refund_by_merchant_id_connector_refund_id_connector(
api_models::webhooks::ObjectReferenceId::RefundId( &merchant_account.merchant_id,
api_models::webhooks::RefundIdType::RefundId(id), &id,
) => db connector_name,
.find_refund_by_merchant_id_refund_id( merchant_account.storage_scheme,
&merchant_account.merchant_id, )
&id, .await
merchant_account.storage_scheme, .change_context(errors::ApiErrorResponse::WebhookResourceNotFound)
) .attach_printable_lazy(|| "Failed fetching the refund")?,
.await },
.change_context(errors::ApiErrorResponse::WebhookResourceNotFound)
.attach_printable_lazy(|| "Failed fetching the refund")?,
_ => Err(errors::ApiErrorResponse::WebhookProcessingFailure) _ => Err(errors::ApiErrorResponse::WebhookProcessingFailure)
.into_report() .into_report()
.attach_printable("received a non-refund id when processing refund webhooks")?, .attach_printable("received a non-refund id when processing refund webhooks")?,