> For the complete documentation index, see [llms.txt](https://docs.zus.network/zus-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.zus.network/zus-docs/http-apis/obox-api/stripe-apis.md).

# Stripe APIs

### Stripe APIs

These endpoints manage all payment and subscription-related interactions for decentralized storage services, including one-time purchases, subscription-based allocations, AI agents, operational fees, and blobber rental.

#### **Get Stripe Configuration**

**Path:** `/v2/stripe/config`\
**Method:** `GET`\
**Access:** Private API\
**Description:**\
Fetches the available Stripe pricing plans configured for different app types (e.g., `blimp`, `vult`, `chalk`, `chimney`). Each plan includes pricing and metadata like storage size and currency.

**Query Parameters:** *(None)*

**Response:**

```json
[
  {
    "id": "price_1P0abc123xyz",
    "currency": "usd",
    "lookup_key": "blimp:: 100gb",
    "metadata": {
      "AppType": "blimp",
      "Size": "107374182400"
    },
    "unit_amount": 1500,
    "unit_amount_decimal": 1500.0,
    "active": true
  },
  {
    "id": "price_1P0def456uvw",
    "currency": "usd",
    "lookup_key": "blimp:: 200gb",
    "metadata": {
      "AppType": "blimp",
      "Size": "214748364800"
    },
    "unit_amount": 2500,
    "unit_amount_decimal": 2500.0,
    "active": true
  }
]
```

**Logic:**

* Plans are retrieved using Stripe’s pricing list API.
* Filters by `AppType` and ensures only active plans are returned.
* Extracts and returns relevant metadata for each plan:
  * `AppType`
  * `Size` (in bytes)
  * `lookup_key`
  * `unit_amount`
  * `currency`
* Used to populate pricing dropdowns or plan selectors in UI.

#### **Get Stripe Customer**

**Path:** `/v2/stripe/customer`\
**Method:** `GET`\
**Access:** Private API\
**Description:**\
Retrieves the Stripe customer profile associated with the currently authenticated user.

**Query Parameters:** *(None)*

**Response:**

```json
{
  "customer_id": "cus_abc123xyz",
  "email": "user@example.com",
  "phone": "+1234567890",
  "name": "Alice"
}
```

**Logic:**

* The backend maps the authenticated user’s ID to a stored Stripe customer ID.
* If the customer does not exist:
  * Returns a `404` or triggers creation (implementation dependent).
* Returns core details for UI prefill, account linking, and analytics.

#### **Cancel Subscription**

**Path:** `/v2/stripe/cancel-subscription`\
**Method:** `POST`\
**Access:** Private API\
**Description:**\
Cancels a user’s active Stripe subscription by `subscription_id` and updates both Stripe and local DB records.

**Request Body:**

```json
{
  "subscription_id": "sub_1P0abc123xyz"
}
```

**Response:**

```json
{
  "id": 123,
  "subscription_id": "sub_1P0abc123xyz",
  "customer_id": 456,
  "app_type": "blimp",
  "cancel_at": "2025-07-01T12:00:00Z",
  "subscription_start": "2025-06-01T12:00:00Z",
  "subscription_end": "2025-07-01T12:00:00Z",
  "discount": 0,
  "plan_id": "price_1P0abc123xyz",
  "plan_name": "blimp:: 100gb",
  "duration": "month",
  "status": "canceled",
  "stripe_allocation_details": {
    "allocation_id": "alloc_abc123",
    "allocation_size": 107374182400,
    "allocation_expiry": 1750000000
  },
  "stripe_ai_subscription": false
}
```

**Logic:**

* Validates ownership of the subscription.
* Calls Stripe’s subscription cancel API.
* Marks subscription as `canceled` in the local DB.
* Updates any associated allocations or resources to reflect termination.

#### **Get Specific PaymentIntent**

**Path:** `/v2/stripe/payment-intent`\
**Method:** `GET`\
**Access:** Private API\
**Description:**\
Returns full details about a specific PaymentIntent from Stripe, including allocation linkage and payment metadata.

**Query Parameters:**

* `payment_intent` (string, required)

**Example:**\
`GET /v2/stripe/payment-intent?payment_intent=pi_1P0abc123xyz`

**Response:**

```json
{
  "payment_intent": "pi_1P0abc123xyz",
  "amount": 1500,
  "date": "2025-07-01T12:00:00Z",
  "currency": "usd",
  "method": "card",
  "description": "Purchase 100GB storage",
  "status": "succeeded",
  "subscription_id": 12345,
  "checkout_session": "cs_test_12345",
  "app_type": "blimp",
  "stripe_allocation_details": {
    "allocation_id": "alloc_abc123",
    "allocation_size": 107374182400,
    "allocation_expiry": 1750000000
  }
}
```

**Logic:**

* Validates the user owns the `payment_intent`.
* Joins local database records with Stripe payment data.
* Links back to the allocation or subscription triggered by this payment.

#### **Create One-Time Allocation Checkout Session**

**Path:** `/v2/stripe/create-allocation`

**Method:** `POST`

**Access:** Private API

**Description:** Creates a Stripe Checkout session for a **one-time purchase** of a storage allocation (currently supports `blimp` app type only). Returns a session URL for redirecting the user.

**Request Body:**\
(Required fields, full example)

```json
{
  "price_id": "price_1P0abc123xyz",
  "amount": 1500,
  "success_url": "https://yourapp.com/payment-success",
  "cancel_url": "https://yourapp.com/payment-cancel",
  "description": "Purchase 100GB storage",
  "allocation_name": "My Storage",
  "allocation_type": "HotPlus",
  "owner_public_key": "abcdef1234567890",
  "data_shards": 2,
  "parity_shards": 2,
  "size": 107374182400,
  "read_price_min": 0,
  "read_price_max": 0,
  "write_price_min": 0,
  "write_price_max": 0,
  "blobber_ids": "blobber1,blobber2,blobber3,blobber4",
  "is_enterprise": false,
  "alloc_blobbers_type": "HotPlus",
  "round_expiry": 0,
  "owner_signing_public_key": "abcdef1234567890"
}
```

**Response:**

* **Status:** `201 Created`
* **Content-Type:** `application/json`

```json
{
  "id": "cs_test_12345",
  "amount_total": 1500,
  "currency": "usd",
  "url": "https://checkout.stripe.com/pay/cs_test_12345"
}
```

**Logic:**

1. Validates all input fields.
2. Ensures `blobber_ids.length ≥ data_shards + parity_shards`.
3. Checks app type == `"blimp"`.
4. Filters blobbers by allocation type/enterprise.
5. Verifies price on mainnet (match with blobber write price).
6. Saves a `StripeAllocationOptions` task in DB.
7. Builds checkout session with success/cancel URLs and metadata.**Webhook:** `checkout.session.completed` → `case modelV2.CreateAllocation`

* Extracts `TaskID` from metadata.
* Stores payment details in DB.
* Marks the allocation as paid.
* Triggers a worker to finalize allocation on-chain.

#### **Update One-Time Allocation Checkout Session**

**Path:** `/v2/stripe/update-allocation`

**Method:** `POST`\
**Access:** Private API

**Description:** Creates a Stripe Checkout session to **upgrade** or **modify** an existing allocation (increase size, replace blobbers). Applicable for `blimp` and `vult`.

**Request Body:**

```json
{
  "price_id": "price_1P0abc123xyz",
  "amount": 1000,
  "success_url": "https://yourapp.com/payment-success",
  "cancel_url": "https://yourapp.com/payment-cancel",
  "allocation_id": "alloc_abc123",
  "size": 214748364800,
  "description": "Upgrade to 200GB",
  "add_blobber": "blobber5",
  "remove_blobber": "blobber2",
  "update_alloc_ticket": "",
  "round_expiry": 0
}
```

**Response:**

* **Status:** `201 Created`
* **Content-Type:** `application/json`

```json
{
  "id": "cs_test_67890",
  "amount_total": 1000,
  "currency": "usd",
  "url": "https://checkout.stripe.com/pay/cs_test_67890"
}
```

**Logic:**

1. Validates `allocation_id` and presence of `size` or blobber changes.
2. App type must be `blimp` or `vult`.
3. If only `remove_blobber` is provided and `amount == 0`:
   * Skips Stripe session and performs free replacement in DB.
4. Otherwise, creates `StripeAllocationOptions` task.
5. Verifies mainnet cost matches `amount`.

**Webhook:** `checkout.session.completed` → `case modelV2.UpdateAllocation`

* Processes payment.
* Updates allocation task with PaymentIntent ID.
* Triggers background update.

#### **Create Allocation Subscription**

**Path:** `/v2/stripe/create-allocation-subscription`

**Method:** `POST`

**Access:** Private API

**Description:** Creates a **recurring subscription-based** storage allocation (for `vult` or `chalk`). Validates the subscription plan and metadata.

**Request Body:**

```json
{
  "price_id": "price_1P0abc123xyz",
  "amount": 1500,
  "success_url": "https://yourapp.com/payment-success",
  "cancel_url": "https://yourapp.com/payment-cancel",
  "description": "Purchase 100GB storage",
  "allocation_name": "My Storage",
  "allocation_type": "HotPlus",
  "owner_public_key": "abcdef1234567890",
  "data_shards": 2,
  "parity_shards": 2,
  "size": 107374182400,
  "read_price_min": 0,
  "read_price_max": 0,
  "write_price_min": 0,
  "write_price_max": 0,
  "blobber_ids": "blobber1,blobber2,blobber3,blobber4",
  "is_enterprise": false,
  "alloc_blobbers_type": "HotPlus",
  "round_expiry": 0,
  "owner_signing_public_key": "abcdef1234567890"
}
```

**Response:**

* **Status:** `201 Created`
* **Content-Type:** `application/json`

```json
{
  "id": "cs_test_12345",
  "amount_total": 1500,
  "currency": "usd",
  "url": "https://checkout.stripe.com/pay/cs_test_12345"
}
```

**Logic:**

1. Ensures `AppType == vult || chalk`
2. Validates plan metadata using `checkSubscriptionPlanAllocation`
3. Stores allocation config as a `StripeAllocationOptions` task.
4. Builds Stripe Checkout session:
   * Mode: `subscription`
   * Metadata includes: `TaskID`, `ClientID`, `StripeOperation`
   * Billing anchor set \~335 days later for yearly plans
   * Links to existing customer if exists

**Webhook:** `checkout.session.completed` → `case modelV2.CreateAllocation`

* Extracts metadata
* Creates allocation and subscription record
* Processes referral discount (if any)
* Marks allocation task as ready

#### **Update Allocation Subscription**

**Path:** `/v2/stripe/update-allocation-subscription`

**Method:** `POST`

**Access:** Private API

**Description:** Used to upgrade an existing subscription-based allocation. Cancels the old subscription and creates a new one.

**Request Body:**

```json
{
  "price_id": "price_1P0abc123xyz",
  "success_url": "https://yourapp.com/payment-success",
  "cancel_url": "https://yourapp.com/payment-cancel",
  "allocation_id": "alloc_abc123",
  "size": 214748364800,
  "description": "Upgrade to 200GB"
}
```

**Response:**

* **Status:** `201 Created`
* **Content-Type:** `application/json`

```json
{
  "id": "cs_test_67890",
  "amount_total": 2500,
  "currency": "usd",
  "url": "https://checkout.stripe.com/pay/cs_test_67890"
}
```

**Logic:**

1. Validates `price_id`, `allocation_id`, and `size`
2. Matches app type and size with plan metadata
3. Finds existing active subscriptions:
   * Generates upgrade coupons
   * Adds to metadata for Stripe
4. Creates Stripe Checkout session:
   * Mode: `subscription`
   * Applies coupons/discounts
   * Adds `ExistingSubscriptions` metadata
   * Metadata: `TaskID`, `PlanName`, `Duration`, `StripeOperation`

**Webhook:** `checkout.session.completed` → `case modelV2.UpdateAllocationSubscription`

* Fetches metadata
* Cancels old subscriptions
* Saves new subscription
* Links task to updated allocation

#### **Create Chimney Subscription**

**Path:** `/v2/stripe/chimney-subscription`

**Method:** `POST`

**Access:** Private API

**Description:** Sets up a **recurring operational fee** between a blobber and validator using Stripe subscriptions.

**Request Body:**

```json
{
  "price_id": "price_1P0abc123xyz",
  "blobber_client_id": "blobber123",
  "validator_client_id": "validator456",
  "success_url": "https://yourapp.com/payment-success",
  "cancel_url": "https://yourapp.com/payment-cancel",
  "description": "Operational fee for Chimney"
}
```

**Response:**

* **Status:** `201 Created`
* **Content-Type:** `application/json`

```json
{
  "id": "cs_test_12345",
  "amount_total": 500,
  "currency": "usd",
  "url": "https://checkout.stripe.com/pay/cs_test_12345"
}
```

**Logic:**

1. Fetches customer by user ID.
2. Validates `price_id` metadata.
3. Builds metadata:
   * `BlobberClientID`, `ValidatorClientID`, `StripeOperation=ChimneySubscription`
4. Creates checkout session in subscription mode.

**Webhook:** `checkout.session.completed` → `case modelV2.ChimneySubscription`

* Parses metadata
* Creates/updates `StripeSubscriptionDetails` with Chimney info
* Triggers:
  * `fundOperationalWallets()`
  * Delegate wallet funding task
  * Link to subscription ID

#### **Create Rent Blobber Subscription**

**Path:** `/v2/stripe/rent-blobber-subscription`\
**Method:** `POST`\
**Access:** Private API\
**Description:**\
Creates a Stripe Checkout session for a **recurring subscription to rent a blobber** (dedicated storage provider). This allows a user to rent storage capacity directly from a specific blobber.

**Request Body:**

```json
{
  "price_id": "price_1P0abc123xyz",
  "blobber_id": "blobber123",
  "success_url": "https://yourapp.com/payment-success",
  "cancel_url": "https://yourapp.com/payment-cancel",
  "description": "Rent blobber for 1 year"
}
```

**Response:**

* **Status:** `201 Created`
* **Content-Type:** `application/json`

```json
{
  "id": "cs_test_rent_blobber_001",
  "amount_total": 8000,
  "currency": "usd",
  "url": "https://checkout.stripe.com/pay/cs_test_rent_blobber_001"
}
```

**Logic:**

1. Fetch Stripe customer for the authenticated user.
2. Retrieve Stripe plan using `price_id` and extract metadata.
3. Prepare metadata:
   * `StripeOperation`: `"RentBlobberSubscription"`
   * `ClientID`, `AppType`, `BlobberID`, `DelegateWallet`, `PlanName`, `Duration`, `Description`, `PriceID`, etc.
4. Create Stripe Checkout session in subscription mode using metadata.
5. Return Checkout session details to the client.

**Webhook Handler:** `case modelV2.RentBlobberSubscription`

* On `checkout.session.completed`:
  * Extracts metadata (plan, blobber ID, delegate wallet, shift price ID, etc.)
  * Generates split key using ZVault
  * Fetches Portainer API endpoint for blobber host
  * Stops and renames old container, then deploys new one with split key
  * Deletes old container after successful migration
  * Updates `rent_blobber` record and saves delegate wallet and subscription metadata
  * Marks blobber as rented by the user in the database

#### **Create AI Agent Subscription**

**Path:** `/v2/stripe/ai-agent-subscription`

**Method:** `POST`

**Access:** Private API

**Description:** Creates a Stripe Checkout session for subscribing to an **AI Agent** service. This enables a recurring subscription to use AI inference APIs on the platform.

**Request Body:**

```json
{
  "price_id": "price_1P0abc123xyz",
  "success_url": "https://yourapp.com/payment-success",
  "cancel_url": "https://yourapp.com/payment-cancel",
  "description": "AI Agent monthly subscription"
}
```

**Response:**

* **Status:** `201 Created`
* **Content-Type:** `application/json`

```json
{
  "id": "cs_test_ai_agent_001",
  "amount_total": 2500,
  "currency": "usd",
  "url": "https://checkout.stripe.com/pay/cs_test_ai_agent_001"
}
```

**Logic:**

1. Fetch Stripe customer for the authenticated user.
2. Validate `price_id` by fetching associated Stripe plan.
3. Add metadata:
   * `StripeOperation`: `"AiAgentSubscription"`
   * `ClientID`, `PlanName`, `Duration`, `PriceID`, `Description`
4. Create Stripe subscription checkout session with metadata
5. Return session details to client

**Webhook Handler:** `case modelV2.AiAgentSubscription`

* On `checkout.session.completed`:
  * Extract metadata (`PriceID`, `PlanName`, `Duration`, etc.)
  * Fetch subscription details from Stripe using `subscription_id`
  * Save new record in `StripeSubscriptionDetails`
  * Create new entry in `AiSubscriptionEntity` to link user ID and subscription

#### 18. **Get Stripe Subscription**

**Path:** `/v2/stripe/subscription`

**Method:** `GET`

**Access:** Private API

**Description:** Returns the **Stripe subscription details** for a specific allocation or operational wallet (blobber and validator pair).

**Query Parameters:**

* Use either of the following:
  * `allocation_id=alloc_abc123`
  * `blobber_client_id=blobber123&validator_client_id=validator456`

**Response:**

* **Status:** `200 OK`
* **Content-Type:** `application/json`

```json
{
  "subscription_id": "sub_1P0abc123xyz",
  "customer_id": "cus_abc123xyz",
  "stripe_allocation_details": {
    "allocation_id": "alloc_abc123",
    "allocation_size": 107374182400,
    "allocation_expiry": 1750000000
  },
  "stripe_chimney_details": {
    "blobber_client_id": "blobber123",
    "validator_client_id": "validator456"
  },
  "stripe_rent_blobber_details": {
    "blobber_id": "blobber123",
    "delegate_wallet": "wallet_xyz",
    "shift_price_id": "price_1P0def456uvw"
  },
  "app_type": "blimp",
  "cancel_at": "2025-07-01T12:00:00Z",
  "subscription_start": "2025-06-01T12:00:00Z",
  "subscription_end": "2025-07-01T12:00:00Z",
  "discount": 0,
  "plan_id": "price_1P0abc123xyz",
  "plan_meta_data": "blimp:: 100gb",
  "duration": "month",
  "status": "active"
}
```

**Logic:**

* Uses provided `allocation_id` or `(blobber_client_id, validator_client_id)` to query internal DB
* Fetches subscription metadata and links it to the Stripe customer and plan

#### **Get All Stripe Subscriptions**

**Path:** `/v2/stripe/subscriptions`

**Method:** `GET`

**Access:** Private API

**Description:** Returns **all active Stripe subscriptions** for the authenticated user.

**Query Parameters (Optional):**

* `ai_subscription=true` → filters only AI agent subscriptions

**Sample Requests:**

```
GET /v2/stripe/subscriptions
GET /v2/stripe/subscriptions?ai_subscription=true
```

**Response:**

* **Status:** `200 OK`
* **Content-Type:** `application/json`

```json
[
  {
    "subscription_id": "sub_1P0abc123xyz",
    "customer_id": "cus_abc123xyz",
    "plan_id": "price_1P0abc123xyz",
    "app_type": "blimp",
    "plan_meta_data": "blimp:: 100gb",
    "duration": "month",
    "status": "active",
    "subscription_start": "2025-06-01T12:00:00Z",
    "subscription_end": "2025-07-01T12:00:00Z"
  },
  {
    "subscription_id": "sub_1P0ai789xyz",
    "customer_id": "cus_abc123xyz",
    "plan_id": "price_1P0ai789xyz",
    "app_type": "ai",
    "plan_meta_data": "ai:: pro",
    "duration": "month",
    "status": "active",
    "subscription_start": "2025-06-15T12:00:00Z",
    "subscription_end": "2025-07-15T12:00:00Z"
  }
]
```

**Logic:**

* Fetches subscriptions tied to the user’s Stripe customer ID
* Filters based on `app_type` if `ai_subscription=true`

#### 20. **Get Active Rent Blobber Subscriptions**

**Path:** `/v2/stripe/rent-blobber-subscriptions`

**Method:** `GET`

**Access:** Private API

**Description:** Returns all **active rent blobber subscriptions** linked to the authenticated user.

**Response:**

* **Status:** `200 OK`
* **Content-Type:** `application/json`

```json
[
  {
    "subscription_id": "sub_1P0rent001xyz",
    "customer_id": "cus_abc123xyz",
    "blobber_id": "blobber123",
    "delegate_wallet": "wallet_xyz",
    "shift_price_id": "price_1P0rentxyz",
    "plan_id": "price_1P0rentxyz",
    "app_type": "blimp",
    "duration": "year",
    "status": "active",
    "subscription_start": "2025-01-01T00:00:00Z",
    "subscription_end": "2026-01-01T00:00:00Z"
  }
]
```

**Logic:**

* Queries all subscriptions where `stripe_blobber_id IS NOT NULL`
* Filters only active records tied to the authenticated user

#### **Get Stripe Payment Intents**

**Path:** `/v2/stripe/payment-intents`\
**Method:** `GET`\
**Access:** Private API

**Description:**\
Returns all Stripe payment intents (i.e., payment transaction records) for the currently authenticated user. This includes both one-time payments and subscription-related charges. The data is fetched using the user’s Stripe customer ID and includes relevant metadata for each payment.

***

**Response:**\
**Status:** `200 OK`\
**Content-Type:** `application/json`

```json
jsonCopyEdit[
  {
    "payment_intent": "pi_1P0abc123xyz",
    "amount": 1500,
    "currency": "usd",
    "status": "succeeded",
    "date": "2025-07-01T12:00:00Z",
    "description": "Purchase 100GB storage",
    "allocation_id": "alloc_abc123",
    "subscription_id": null
  },
  {
    "payment_intent": "pi_1P0def456uvw",
    "amount": 2500,
    "currency": "usd",
    "status": "pending",
    "date": "2025-07-10T10:00:00Z",
    "description": "Yearly subscription upgrade",
    "allocation_id": null,
    "subscription_id": "sub_1P0xyzsub456"
  }
]
```

```json
    "date": "2025-07-10T12:00:00Z",
    "description": "Upgrade to 200GB",
    "allocation_id": "alloc_def456",
    "subscription_id": "sub_1P0def456uvw"
  }
]
```
