arlyon / async-stripe

Async (and blocking!) Rust bindings for the Stripe API
https://payments.rs
Apache License 2.0
414 stars 121 forks source link

construct_event, no signatures found matching the expected signature #551

Closed cpasneedles closed 2 months ago

cpasneedles commented 2 months ago

Describe the bug

Hello, The problem is that the function stripe::Webhook::construct_event always returns BadSignature: "error comparing signatures" even when the signatures are equal.

To Reproduce

  1. Call stripe::Webhook::construct_event
  2. Set your header signature and your webhook secret key as parameters of the construct_event function
  3. Handle the error

Expected behavior

I want to implement webhook on my stripe service.

Code snippets

pub struct StripeEvent(Event);

#[async_trait]
impl<S> FromRequest<S> for StripeEvent
where
    String: FromRequest<S>,
    S: Send + Sync,
{
    type Rejection = Response;

    async fn from_request(req: Request<Body>, state: &S) -> Result<Self, Self::Rejection> {
        let signature = if let Some(sig) = req.headers().get("stripe-signature") {
            sig.to_owned()
        } else {
            return Err(StatusCode::BAD_REQUEST.into_response());
        };

        let payload =
            String::from_request(req, state).await.map_err(IntoResponse::into_response)?;

        let secret = match std::env::var("WEBHOOK_SECRET_KEY") {
            Ok(sig) => sig,
            Err(e) => {
                println!("Error getting stripe webhook secret key: {:?}", e);
                return Err((
                    StatusCode::INTERNAL_SERVER_ERROR,
                    Json(Message {
                        message: "Couldn't get the stripe webhook signature".to_string(),
                    }),
                )
                    .into_response());
            }
        };

        Ok(Self(
            stripe::Webhook::construct_event(&payload, signature.to_str().unwrap(), &secret)
                .map_err(|_| StatusCode::BAD_REQUEST.into_response())?,
        ))
    }
}

#[axum::debug_handler]
pub async fn handle_webhook(StripeEvent(event): StripeEvent) {
    match event.type_ {
        EventType::CheckoutSessionCompleted => {
            if let EventObject::CheckoutSession(session) = event.data.object {
                println!("Received checkout session completed webhook with id: {:?}", session.id);
            }
        }
        EventType::AccountUpdated => {
            if let EventObject::Account(account) = event.data.object {
                println!("Received account updated webhook for account: {:?}", account.id);
            }
        }
        _ => println!("Unknown event encountered in webhook: {:?}", event.type_),
    }
}

OS

windows

Rust version

1.76.0

Library version

async-stripe 0.37.0

API version

2024-04-10

Additional context

No response

cpasneedles commented 2 months ago

ok I fixed the problem , the problem came from my request