uarp-sdk 0.5.7

Async Rust client for the UARP (Snaga) Universal Agent Runtime Platform API
Documentation
// Code generated by @uarp/codegen from spec/openapi.json. DO NOT EDIT.
//!
//! Usage tracking, quota management, and Stripe webhooks

#![allow(unused_imports, clippy::too_many_arguments)]

use reqwest::Method;
use serde::{Deserialize, Serialize};

use crate::client::{Client, Request, NO_BODY, NO_QUERY};
use crate::error::Result;
use crate::generated::models;
use crate::multipart::{field_text, FilePart};
use crate::util::encode_path;

/// Query and header parameters for `getUsage`.
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct GetUsageParams {
    /// Billing period in YYYY-MM format. Defaults to current month.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub period: Option<String>,
}

/// Query and header parameters for `getUsageTimeseries`.
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct GetUsageTimeseriesParams {
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub metric: Option<models::GetUsageTimeseriesMetric>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub days: Option<i64>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub agent_id: Option<String>,
}

/// Query and header parameters for `handleStripeWebhook`.
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct HandleStripeWebhookParams {
    /// Stripe webhook signature in `t=\<timestamp\>,v1=\<sig\>` format. Required; missing or
    /// invalid signatures are rejected with 400.
    #[serde(skip)]
    pub stripe_signature: String,
}

/// Usage tracking, quota management, and Stripe webhooks
#[derive(Debug, Clone)]
pub struct BillingApi {
    pub(crate) client: Client,
}

impl Client {
    /// Usage tracking, quota management, and Stripe webhooks
    pub fn billing(&self) -> BillingApi {
        BillingApi { client: self.clone() }
    }
}

impl BillingApi {
    /// Check tenant quota status
    ///
    /// `GET /api/v1/usage/quota`
    ///
    /// Required scopes: `billing:read`.
    pub async fn check_quota(&self) -> Result<serde_json::Value> {
        self.client
            .request_json(Request {
                method: Method::GET,
                path: "/api/v1/usage/quota".to_string(),
                query: NO_QUERY,
                body: NO_BODY,
                headers: Vec::new(),
                idempotent: false,
            })
            .await
    }

    /// Create a Stripe Customer Portal session URL
    ///
    /// Returns a Stripe-hosted URL where the customer can manage subscriptions and payment methods.
    /// `return_url` must be same-origin as the request; defaults to `\<origin\>/admin/billing`.
    ///
    /// `POST /api/v1/billing/portal-session`
    ///
    /// Required scopes: `billing:write`.
    pub async fn create_billing_portal_session(&self, body: &models::CreateBillingPortalSessionRequest) -> Result<models::CreateBillingPortalSessionResponse> {
        self.client
            .request_json(Request {
                method: Method::POST,
                path: "/api/v1/billing/portal-session".to_string(),
                query: NO_QUERY,
                body: Some(body),
                headers: Vec::new(),
                idempotent: true,
            })
            .await
    }

    /// Create Stripe checkout session
    ///
    /// `POST /api/v1/billing/checkout-session`
    ///
    /// Required scopes: `billing:read`.
    pub async fn create_checkout_session(&self, body: &models::CreateCheckoutSessionRequest) -> Result<models::CreateCheckoutSessionResponse> {
        self.client
            .request_json(Request {
                method: Method::POST,
                path: "/api/v1/billing/checkout-session".to_string(),
                query: NO_QUERY,
                body: Some(body),
                headers: Vec::new(),
                idempotent: true,
            })
            .await
    }

    /// Get current tenant usage
    ///
    /// `GET /api/v1/usage`
    ///
    /// Required scopes: `billing:read`.
    pub async fn get_usage(&self, params: &GetUsageParams) -> Result<serde_json::Value> {
        self.client
            .request_json(Request {
                method: Method::GET,
                path: "/api/v1/usage".to_string(),
                query: Some(params),
                body: NO_BODY,
                headers: Vec::new(),
                idempotent: false,
            })
            .await
    }

    /// Get usage analytics over time
    ///
    /// `GET /api/v1/usage/timeseries`
    ///
    /// Required scopes: `billing:read`.
    pub async fn get_usage_timeseries(&self, params: &GetUsageTimeseriesParams) -> Result<models::GetUsageTimeseriesResponse> {
        self.client
            .request_json(Request {
                method: Method::GET,
                path: "/api/v1/usage/timeseries".to_string(),
                query: Some(params),
                body: NO_BODY,
                headers: Vec::new(),
                idempotent: false,
            })
            .await
    }

    /// Handle Stripe webhook events
    ///
    /// Processes incoming Stripe events (invoice.paid, invoice.payment_failed,
    /// customer.subscription.deleted). Bypasses normal auth — `Stripe-Signature` header is
    /// HMAC-verified against the webhook signing secret.
    ///
    /// `POST /api/v1/webhooks/stripe`
    pub async fn handle_stripe_webhook(&self, body: &models::HandleStripeWebhookRequest, params: &HandleStripeWebhookParams) -> Result<serde_json::Value> {
        let mut headers: Vec<(&'static str, String)> = Vec::new();
        headers.push(("Stripe-Signature", params.stripe_signature.clone()));
        self.client
            .request_json(Request {
                method: Method::POST,
                path: "/api/v1/webhooks/stripe".to_string(),
                query: NO_QUERY,
                body: Some(body),
                headers,
                idempotent: true,
            })
            .await
    }

    /// List available billing plans
    ///
    /// `GET /api/v1/billing/plans`
    ///
    /// Required scopes: `billing:read`.
    pub async fn list_billing_plans(&self) -> Result<models::ListBillingPlansResponse> {
        self.client
            .request_json(Request {
                method: Method::GET,
                path: "/api/v1/billing/plans".to_string(),
                query: NO_QUERY,
                body: NO_BODY,
                headers: Vec::new(),
                idempotent: false,
            })
            .await
    }
}