arlyon / async-stripe

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

bug: PaymentLink::create cannot be deserialized #496

Open skeptrunedev opened 8 months ago

skeptrunedev commented 8 months ago

Describe the bug

For the following code:

let payment_link = PaymentLink::create(&stripe_client, create_payment_link)
        .await
        .map_err(|e| {
            log::error!("Failed to create stripe payment link: {}", e);
            DefaultError {
                message: "Failed to create stripe payment link",
            }
        })?
        .url;

I get an error of:

 [2024-02-06T08:56:51Z ERROR trieve_server::operators::stripe_operator] Failed to create stripe payment link: error serializing or deserializing a request

To Reproduce

Attempt to create a PaymentLink for a subscription and observe the issue.

Expected behavior

A successfully deserialized response.

Code snippets

No response

OS

linux

Rust version

stable-x86_64-unknown-linux-gnu (default)

Library version

0.31.0

API version

2023-10-16.

Additional context

No response

skeptrunedev commented 8 months ago

I rewrote this section of our codebase with Reqwest so we could get it fixed immediately. Leaving this here in case it's helpful for a fix or anyone else who encounters this issue before a fix is merged.

pub async fn create_stripe_payment_link(
    plan: StripePlan,
    organization_id: uuid::Uuid,
) -> Result<String, DefaultError> {
    let admin_dashboard_url = get_env!("ADMIN_DASHBOARD_URL", "ADMIN_DASHBOARD_URL must be set");

    let stripe_secret = get_env!("STRIPE_SECRET", "STRIPE_SECRET must be set");
    let payment_link_create_request = reqwest::Client::new()
        .post("https://api.stripe.com/v1/payment_links")
        .header("Authorization", format!("Bearer {}", stripe_secret));

    let payment_link_form_url_encoded = json!({
        "line_items[0][price]": plan.stripe_id,
        "line_items[0][quantity]": 1,
        "allow_promotion_codes": true,
        "after_completion[redirect][url]": format!("{}/dashboard/billing", admin_dashboard_url),
        "after_completion[type]": "redirect",
        "metadata[organization_id]": organization_id.to_string(),
        "metadata[plan_id]": plan.id.to_string()
    });

    let payment_link_response = payment_link_create_request
        .header("Content-Type", "application/x-www-form-urlencoded")
        .form(&payment_link_form_url_encoded)
        .send()
        .await
        .map_err(|e| {
            log::error!("Failed to create stripe payment link: {}", e);
            DefaultError {
                message: "Failed to create stripe payment link",
            }
        })?;

    let payment_link_response_json: serde_json::Value =
        payment_link_response.json().await.map_err(|e| {
            log::error!("Failed to get stripe payment link json: {}", e);
            DefaultError {
                message: "Failed to get stripe payment link json",
            }
        })?;

    log::info!("Payment link response: {:?}", payment_link_response_json);

    let payment_link = payment_link_response_json["url"]
        .as_str()
        .ok_or(DefaultError {
            message: "Failed to get stripe payment link url",
        })?;

    Ok(payment_link.to_string())
}
arlyon commented 7 months ago

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