# How GPT-Image2’s Credit-Based Generation System Works

> Discover how GPT-Image2's credit-based generation system safeguards its service. Learn about atomic transactions, billing integration, and admin overrides using Supabase PostgreSQL.

- Repository: [苍何/awesome-gpt-image-2](https://github.com/freestylefly/awesome-gpt-image-2)
- Tags: deep-dive
- Published: 2026-08-29

---

**GPT-Image2 protects its image-generation service with a credit-based quota enforced on every request, utilizing Supabase PostgreSQL for atomic transactions and providing both automated billing integration and manual admin overrides.**

The **credit-based generation system** in the `freestylefly/awesome-gpt-image-2` repository manages user access to AI image generation through a robust accounting layer built on Supabase. This architecture ensures that every creation request deducts the appropriate credits while maintaining audit trails for billing, memberships, and administrative adjustments.

## Core Database Components

The foundation of the credit system rests on two PostgreSQL tables and a set of atomic stored procedures.

### User Credit Tables

The schema defined in [`supabase/migrations/202605090001_user_credits.sql`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/supabase/migrations/202605090001_user_credits.sql) establishes the ledger structure:

- **`user_credits`** – Stores the current balance, purchased credits, and membership credits for each user.
- **`credit_transactions`** – Logs every debit and credit operation for complete auditability.

These tables link to Supabase Auth via `user_id`, ensuring that credit balances are intrinsically tied to authenticated sessions.

### Credit-Adjustment RPCs

Located in [`api/_lib/billing.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/billing.js), the system exposes Supabase remote procedure calls (RPCs) that atomically modify balances:

- **`grant_user_credits`** – Adds credits (used for purchases or admin grants).
- **`revoke_user_credits`** – Removes credits (used for refunds or corrections).

Because these execute as database transactions, they prevent race conditions when multiple simultaneous requests attempt to modify the same balance.

## The Generation Workflow

Every image creation follows a strict reservation-and-debit pattern to ensure users cannot generate content without sufficient credits.

### Credit Reservation Before Generation

When a user submits a generation request to [`api/generate-image.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/generate-image.js), the system performs a硬性 check before contacting external AI providers:

1. The endpoint queries the current `credit_balance` from the `user_credits` table.
2. It calculates the required `creditAmount` (typically **1 credit per generation**, configurable per model).
3. It calls `grant_user_credits` with a *negative* amount to **reserve** the credits.
4. Only upon successful reservation does the request proceed to the external image service (OpenAI, Stability, etc.).

If the reservation fails due to insufficient funds, the API aborts immediately, returning a 402 or similar error without consuming external API resources.

### Force Credit Bypass for Privileged Users

The system includes a `p_force_credit` flag within [`api/generate-image.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/generate-image.js) that allows specific accounts to bypass the debit step. This mechanism supports:

- Internal testing without consuming production credits.
- Generous free-tier promotions for super-admins.
- Debugging workflows without financial impact.

When `p_force_credit` is set to `true`, the reservation logic is skipped while the generation proceeds normally.

## Billing and Payment Integration

The credit system integrates with Stripe and Alipay to convert monetary payments into generation quotas.

### Credit Packs and Membership Plans

The checkout flow in [`api/billing/checkout.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/billing/checkout.js) creates orders for credit packs or membership subscriptions. Once payment succeeds, the webhook handler in [`api/billing/webhook.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/billing/webhook.js) executes:

```javascript
// Executed after Stripe/Alipay confirms payment
await client.rpc('grant_user_credits', {
  user_id: paidOrder.userId,
  amount: paidOrder.credits,   // e.g., 200 credits
  reason: 'credit_pack_purchase',
});

```

This atomic operation ensures that users receive their purchased credits only after confirmed payment, with the `credit_transactions` table recording the `reason` for audit purposes.

### Manual Admin Adjustments

Operators can manually adjust balances via the admin endpoint [`api/admin/credits/adjust.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/admin/credits/adjust.js). This endpoint calls the same `grant_user_credits` and `revoke_user_credits` RPCs used by the automated billing system, ensuring that manual interventions remain fully auditable in the transaction log.

## Retrieving Credit Status

The front-end queries [`api/me.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/me.js) to display real-time quota information. The endpoint returns a JSON payload containing:

- **`creditBalance`** – Current available credits.
- **`totalGenerationCredits`** – Lifetime generation count.
- **`purchasedCredits`** – Credits bought via packs.
- **`membershipCredits`** – Credits included in active subscriptions.

## End-to-End Code Examples

### Checking Credit Balance (Client-Side)

```javascript
fetch('https://gpt-image2.canghe.ai/api/me', {
  credentials: 'include'   // Sends Supabase auth cookie
})
  .then(r => r.json())
  .then(data => {
    console.log('Credits remaining:', data.creditBalance);
    console.log('Purchased credits:', data.purchasedCredits);
  });

```

### Requesting Image Generation

```javascript
fetch('https://gpt-image2.canghe.ai/api/generate-image', {
  method: 'POST',
  credentials: 'include',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    prompt: 'A futuristic cityscape at sunset, photorealistic',
    // Optional: bypass credit check for admin/testing
    p_force_credit: false
  })
})
  .then(r => r.json())
  .then(res => {
    console.log('Generated image:', res.imageUrl);
    console.log('New balance:', res.creditBalance);
  });

```

### Server-Side Credit Top-Up (Webhook Handler)

```javascript
// Located in api/billing/webhook.js
async function handleSuccessfulPayment(paidOrder) {
  const { error } = await client.rpc('grant_user_credits', {
    user_id: paidOrder.userId,
    amount: paidOrder.credits,
    reason: paidOrder.planType  // 'credit_pack' or 'membership'
  });
  
  if (error) throw new Error(`Credit grant failed: ${error.message}`);
  return { success: true, granted: paidOrder.credits };
}

```

## Summary

- **Atomic transactions** via Supabase RPCs prevent race conditions and double-spending of credits.
- **Reservation pattern** in [`api/generate-image.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/generate-image.js) ensures external AI costs are never incurred for users with insufficient balances.
- **Flexible billing** supports both one-time credit packs and recurring membership plans through Stripe/Alipay integration.
- **Audit trail** in `credit_transactions` provides complete visibility into every credit movement, including manual admin adjustments.
- **Privileged bypass** via `p_force_credit` enables testing and promotional use cases without disrupting the accounting system.

## Frequently Asked Questions

### How does GPT-Image2 prevent users from overdrawing credits?

The system uses **atomic RPC transactions** inside [`api/_lib/billing.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/billing.js). When `grant_user_credits` is called with a negative amount for reservation, the database checks the current balance within the same transaction. If two simultaneous requests attempt to debit the last remaining credit, PostgreSQL’s row locking ensures only one succeeds, while the other receives an insufficient-funds error.

### What happens if an image generation fails after credits are reserved?

The reservation logic in [`api/generate-image.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/generate-image.js) treats the RPC call as a temporary hold. If the subsequent call to the external AI service (OpenAI or Stability) fails or times out, the application logic rolls back the transaction or issues a compensating `grant_user_credits` call to return the reserved amount to the user's balance.

### Can administrators bypass the credit system for testing?

Yes. The `p_force_credit` parameter in [`api/generate-image.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/generate-image.js) allows privileged accounts to skip the debit step entirely. When this flag is set to `true`, the generation proceeds without checking `user_credits` or writing to `credit_transactions`, making it ideal for internal QA and super-admin demonstrations.

### What database powers the credit system?

The system runs on **Supabase**, which provides PostgreSQL as the underlying datastore along with built-in authentication. The migration files [`supabase/migrations/202605090001_user_credits.sql`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/supabase/migrations/202605090001_user_credits.sql) and [`supabase/migrations/20260509090000_membership_billing.sql`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/supabase/migrations/20260509090000_membership_billing.sql) define the tables, indexes, and stored procedures that enforce data integrity for all credit operations.