feat(compatibility): add webhook support for stripe compatibility (#710)

This commit is contained in:
Abhishek
2023-03-05 18:58:04 +05:30
committed by GitHub
parent 3bdc9b0a2f
commit 7916050450
9 changed files with 112 additions and 25 deletions

View File

@ -3,6 +3,7 @@ pub mod customers;
pub mod payment_intents;
pub mod refunds;
pub mod setup_intents;
pub mod webhooks;
use actix_web::{web, Scope};
pub mod errors;
@ -18,6 +19,7 @@ impl StripeApis {
.service(app::SetupIntents::server(state.clone()))
.service(app::PaymentIntents::server(state.clone()))
.service(app::Refunds::server(state.clone()))
.service(app::Customers::server(state))
.service(app::Customers::server(state.clone()))
.service(app::Webhooks::server(state))
}
}

View File

@ -1,7 +1,7 @@
use actix_web::{web, Scope};
use super::{customers::*, payment_intents::*, refunds::*, setup_intents::*};
use crate::routes;
use super::{customers::*, payment_intents::*, refunds::*, setup_intents::*, webhooks::*};
use crate::routes::{self, webhooks};
pub struct PaymentIntents;
@ -55,3 +55,21 @@ impl Customers {
.service(list_customer_payment_method_api)
}
}
pub struct Webhooks;
impl Webhooks {
pub fn server(config: routes::AppState) -> Scope {
web::scope("/webhooks")
.app_data(web::Data::new(config))
.service(
web::resource("/{merchant_id}/{connector}")
.route(
web::post().to(webhooks::receive_incoming_webhook::<StripeOutgoingWebhook>),
)
.route(
web::get().to(webhooks::receive_incoming_webhook::<StripeOutgoingWebhook>),
),
)
}
}

View File

@ -2,7 +2,7 @@ use std::{convert::From, default::Default};
use serde::{Deserialize, Serialize};
use crate::{core::errors, types::api::refunds};
use crate::types::api::refunds;
#[derive(Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
pub struct StripeCreateRefundRequest {
@ -68,10 +68,9 @@ impl From<refunds::RefundStatus> for StripeRefundStatus {
}
}
impl TryFrom<refunds::RefundResponse> for StripeCreateRefundResponse {
type Error = error_stack::Report<errors::ApiErrorResponse>;
fn try_from(res: refunds::RefundResponse) -> Result<Self, Self::Error> {
Ok(Self {
impl From<refunds::RefundResponse> for StripeCreateRefundResponse {
fn from(res: refunds::RefundResponse) -> Self {
Self {
id: res.refund_id,
amount: res.amount,
currency: res.currency.to_ascii_lowercase(),
@ -79,6 +78,6 @@ impl TryFrom<refunds::RefundResponse> for StripeCreateRefundResponse {
status: res.status.into(),
created: res.created_at.map(|t| t.assume_utc().unix_timestamp()),
metadata: res.metadata.unwrap_or_else(|| serde_json::json!({})),
})
}
}
}

View File

@ -0,0 +1,54 @@
use api_models::webhooks::{self as api};
use serde::Serialize;
use super::{
payment_intents::types::StripePaymentIntentResponse, refunds::types::StripeCreateRefundResponse,
};
#[derive(Serialize)]
pub struct StripeOutgoingWebhook {
id: Option<String>,
#[serde(rename = "type")]
stype: &'static str,
data: StripeWebhookObject,
}
impl api::OutgoingWebhookType for StripeOutgoingWebhook {}
#[derive(Serialize)]
#[serde(tag = "type", content = "object", rename_all = "snake_case")]
pub enum StripeWebhookObject {
PaymentIntent(StripePaymentIntentResponse),
Refund(StripeCreateRefundResponse),
}
impl From<api::OutgoingWebhook> for StripeOutgoingWebhook {
fn from(value: api::OutgoingWebhook) -> Self {
let data: StripeWebhookObject = value.content.into();
Self {
id: data.get_id(),
stype: "webhook_endpoint",
data,
}
}
}
impl From<api::OutgoingWebhookContent> for StripeWebhookObject {
fn from(value: api::OutgoingWebhookContent) -> Self {
match value {
api::OutgoingWebhookContent::PaymentDetails(payment) => {
Self::PaymentIntent(payment.into())
}
api::OutgoingWebhookContent::RefundDetails(refund) => Self::Refund(refund.into()),
}
}
}
impl StripeWebhookObject {
fn get_id(&self) -> Option<String> {
match self {
Self::PaymentIntent(p) => p.id.to_owned(),
Self::Refund(r) => Some(r.id.to_owned()),
}
}
}