arlyon / async-stripe

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

Refunds on Charge object is nullable #456

Closed migueltol22 closed 6 months ago

migueltol22 commented 9 months ago

Describe the bug

According to the stripe docs refunds on the charge object is nullable.

In situations when trying to deserialize the object to a Charge struct we get an error of

missing field `refunds`

To Reproduce

In my specific scenario, I am listening to the charge.succeeded webhook that is equivalent to the example as part of the repo

Listen to stripe webhooks locally using stripe cli

stripe listen --forward-connect-to localhost:8000/stripe_webhooks

charge.succeeded event will fail with the example setup.

Added additional logging for debugging

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

    async fn from_request(req: Request<B>, state: &S) -> Result<Self, Self::Rejection> {
        let ctx: AppState = AppState::from_ref(state);
        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)?;

        Ok(Self(
            stripe::Webhook::construct_event(
                &payload,
                signature.to_str().unwrap(),
                &ctx.config.stripe_webhook_secret,
            )
            .map_err(|e| {
                log::error!(
                    "failed to construct event of payload: {:?} with err: {:?}",
                    payload,
                    e
                );
                StatusCode::BAD_REQUEST.into_response()
            })?,
        ))
    }
}

Expected Error:

failed to construct event of payload: "<redacted_payload>" with err: BadParse(Error("missing field `refunds`", line: 120, column: 3))

Expected behavior

I'd expect refunds to be of type Option<List<Refund>> and be able to parse correctly if refunds is not provided in the payload.

Code snippets

No response

OS

macOs

Rust version

1.74.0

Library version

async-stripe 0.22.2

API version

2022-11-15

Additional context

No response

extrawurst commented 7 months ago

I am hitting the same problem in the webhook charge.refunded it wont deserialize properly .. with err: BadParse(Error("missing fieldrefunds", line: 124, column: 5))

JBlashME commented 6 months ago

I am hitting the same problem in the webhook charge.refunded it wont deserialize properly .. with err: BadParse(Error("missing fieldrefunds", line: 124, column: 5))

Im currently working with 0.31.0 and having the same issue. I think its because refunds is not optional in the charge struct causing it to fail. async-stripe-0.31.0/src/resources/generated/charge.rs

    /// A list of refunds that have been applied to the charge.
    pub refunds: List<Refund>,

It looks like in the PR above they have a fix pub refunds: Option<stripe_types::List<stripe_shared::Refund>>,

The last comment on the PR was to release so hopefully it goes out soon.

arlyon commented 6 months ago

I have a PR for this here: https://github.com/arlyon/async-stripe/pull/503