# How Alipay Web Payment Works with Stripe Webhooks in Awesome-GPT-Image-2

> Learn how Alipay web payment integrates with Stripe webhooks in Awesome-GPT-Image-2. Discover how the backend handles subscriptions and one-off purchases for seamless order completion.

- Repository: [苍何/awesome-gpt-image-2](https://github.com/freestylefly/awesome-gpt-image-2)
- Tags: how-to-guide
- Published: 2026-08-31

---

**The Awesome-GPT-Image-2 backend processes Stripe subscriptions via webhooks while handling Alipay one-off purchases through a separate notify/query flow, both converging on shared credit-granting utilities to ensure idempotent order completion.**

This open-source project implements a dual-channel payment architecture that separates subscription management from single-purchase handling. While Stripe webhooks manage recurring membership billing, Alipay web payment facilitates one-time credit pack purchases for Chinese users, with both systems storing orders in a unified `payment_orders` table and delegating credit allocation to common backend helpers.

## Dual-Channel Payment Architecture

The repository maintains two parallel integration paths that never intersect during transaction processing but share post-payment business logic. According to the source code, **Stripe** handles subscription lifecycles through asynchronous events, while **Alipay** manages immediate payment confirmations for credit packs via server-to-server notifications.

The architectural separation is enforced at the database layer. The migration file [`supabase/migrations/20260721090000_alipay_webpay.sql`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/supabase/migrations/20260721090000_alipay_webpay.sql) adds provider-specific columns (`alipay_amount_cents`, `alipay_trade_no`) to the `payment_orders` table, allowing the same table to track both Stripe subscriptions and Alipay one-off purchases without confusion.

## Alipay Web Payment Flow

Alipay integration follows the classic "create-pay-notify" pattern, implemented across dedicated endpoints under `api/billing/alipay/`.

### Checkout Endpoint

The `POST /api/billing/alipay/checkout` handler in [`api/billing/alipay/checkout.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/billing/alipay/checkout.js) initiates the payment flow. It retrieves the Alipay SDK client from [`api/_lib/alipay.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/alipay.js) and constructs a signed request using the `alipay.trade.page.pay` method.

```javascript
// api/billing/alipay/checkout.js
import { getAlipayClient } from '../../_lib/alipay.js';
import { createPaymentOrder } from '../../_lib/billing.js';

export default async function handler(req, res) {
  const { packId, userId } = req.body;
  const product = await getCreditPack(packId);
  if (!product.alipayAvailable) return res.status(400).json({ error: 'ALIPAY_NOT_AVAILABLE' });

  const client = getAlipayClient();
  const request = {
    method: 'alipay.trade.page.pay',
    biz_content: {
      out_trade_no: generateOrderId(),
      total_amount: (product.alipayAmountCents / 100).toFixed(2),
      subject: product.name,
      product_code: 'FAST_INSTANT_TRADE_PAY',
      quit_url: `${appUrl}/billing/alipay/cancel`,
      return_url: `${appUrl}/?billing=alipay_return&order_id=${order.id}`
    }
  };
  const paymentHtml = client.pageExec(request.method, 'POST', request);
  res.setHeader('Content-Type', 'text/html');
  res.send(paymentHtml);
}

```

The `pageExec` method generates an auto-submitting HTML form that redirects the user to Alipay's gateway. The SDK automatically handles signature generation using the private key configured via environment variables (`ALIPAY_APP_ID`, `ALIPAY_PRIVATE_KEY`).

### Asynchronous Notification Handling

After the user completes payment, Alipay's servers call `POST /api/billing/alipay/notify` as documented in [`api/billing/alipay/notify.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/billing/alipay/notify.js). This handler validates the cryptographic signature using `client.checkNotifySign()` before processing the order.

```javascript
// api/billing/alipay/notify.js
import { getAlipayClient } from '../../_lib/alipay.js';
import { finalizeAlipayCreditPackOrder } from '../../_lib/billing.js';

export default async function handler(req, res) {
  const client = getAlipayClient();
  const { body } = req;
  if (!client.checkNotifySign(body)) {
    return res.status(400).json({ error: 'INVALID_SIGNATURE' });
  }
  const result = await client.exec('alipay.trade.notify', body);
  await finalizeAlipayCreditPackOrder(supabaseClient, result);
  res.json({ ok: true });
}

```

The `finalizeAlipayCreditPackOrder` function implements idempotency by checking the order status before granting credits, ensuring that duplicate notifications from Alipay do not result in multiple credit allocations.

### Polling Fallback for Restricted Environments

When the server cannot expose a public `notify_url`, the client can poll `GET /api/billing/alipay/query` implemented in [`api/billing/alipay/query.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/billing/alipay/query.js). This endpoint queries Alipay's trade status API and triggers the same completion logic as the notify handler, providing a fallback for local or firewalled deployments.

## Stripe Webhook Integration

Unlike Alipay's synchronous payment page flow, Stripe handles recurring subscriptions through asynchronous webhooks. The `POST /api/billing/webhook` endpoint in [`api/billing/webhook.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/billing/webhook.js) processes events including `checkout.session.completed` and `invoice.payment_succeeded`.

```javascript
// api/billing/webhook.js
import { completeCreditPackOrder, grantMembershipCredits } from '../_lib/billing.js';

export default async function handler(req, res) {
  const signature = req.headers['stripe-signature'];
  const rawBody = await readRawBody(req);
  const event = getStripeClient().webhooks.constructEvent(
    rawBody, signature, process.env.STRIPE_WEBHOOK_SECRET
  );

  if (event.type === 'checkout.session.completed') {
    const session = event.data.object;
    await completeCreditPackOrder(supabaseClient, session);
  }
  // Subscription renewals handled via grantMembershipCredits
}

```

The webhook handler constructs the event using `constructEvent` to verify the signature against `STRIPE_WEBHOOK_SECRET`, then routes to either `completeCreditPackOrder` for one-time purchases or `grantMembershipCredits` for subscription renewals.

## Unified Credit Granting Layer

Both payment channels converge on shared utilities defined in [`api/_lib/billing.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/billing.js). The `completeCreditPackOrder` function grants credits idempotently using the order's unique identifier, while `grantMembershipCredits` handles recurring subscription entitlements.

This unification ensures that whether a user pays via Stripe webhook or Alipay notification, the system executes the same validation logic:

1. Verify the order exists and is in `pending` status
2. Record the payment provider (`stripe` or `alipay`)
3. Atomically increment user credits
4. Mark order as `completed`

The [`api/billing/plans.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/billing/plans.js) file enforces the business rule that Alipay only appears for credit packs (not subscriptions) by checking `alipay_amount_cents > 0`, preventing users from attempting to start recurring subscriptions through the Alipay channel.

## Summary

- **Stripe webhooks** process recurring subscriptions through [`api/billing/webhook.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/billing/webhook.js), verifying signatures with `constructEvent` and calling `grantMembershipCredits` for renewals.
- **Alipay web payments** use [`api/billing/alipay/checkout.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/billing/alipay/checkout.js) to create orders, [`api/billing/alipay/notify.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/billing/alipay/notify.js) to validate signatures via `checkNotifySign`, and [`api/billing/alipay/query.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/billing/alipay/query.js) for polling fallbacks.
- **Shared completion logic** in [`api/_lib/billing.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/billing.js) ensures idempotent credit granting via `completeCreditPackOrder`, regardless of payment provider.
- **Database separation** via `alipay_*` columns in the `payment_orders` table prevents confusion between one-off Alipay purchases and Stripe subscriptions.

## Frequently Asked Questions

### How does the system prevent duplicate credit grants from Alipay notifications?

The `finalizeAlipayCreditPackOrder` function in [`api/_lib/billing.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/billing.js) checks the order status before granting credits. Since the order is marked `completed` atomically with the credit grant, subsequent Alipay notifications for the same `out_trade_no` find the order already fulfilled and exit without modifying the user's balance.

### Can users purchase subscriptions through Alipay instead of Stripe?

No. The [`api/billing/plans.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/billing/plans.js) logic only exposes Alipay checkout when `alipay_amount_cents` is defined for a credit pack. Subscriptions require Stripe's recurring billing infrastructure, so the system deliberately restricts Alipay to one-off purchases to avoid confusion between Alipay's immediate payment flow and Stripe's subscription lifecycle management.

### What happens if the Alipay notify URL is unreachable?

The system provides a polling mechanism via `GET /api/billing/alipay/query` in [`api/billing/alipay/query.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/billing/alipay/query.js). When the notify endpoint is inaccessible due to firewall restrictions or local development environments, the client can call this endpoint to query Alipay's trade status and trigger the same completion workflow that the notify handler would execute.

### How are payment signatures validated differently between Stripe and Alipay?

Stripe uses `stripe.webhooks.constructEvent()` with a webhook secret to verify payload integrity in [`api/billing/webhook.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/billing/webhook.js), while Alipay uses RSA signature verification through `client.checkNotifySign()` in [`api/billing/alipay/notify.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/billing/alipay/notify.js). The Alipay SDK ([`api/_lib/alipay.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/alipay.js)) handles the cryptographic validation against the Alipay public key, whereas Stripe handles verification internally within their Node.js library.