# How the Alipay Web Payment Sandbox Works Locally Without HTTPS

> Learn how the Alipay web payment sandbox works locally via plain HTTP. Discover how it routes SDK calls through the sandbox gateway to accept local development server callbacks.

- Repository: [苍何/awesome-gpt-image-2](https://github.com/freestylefly/awesome-gpt-image-2)
- Tags: internals
- Published: 2026-09-02

---

**The Alipay web payment sandbox in `freestylefly/awesome-gpt-image-2` runs entirely over plain HTTP by routing all Alipay SDK calls through Alipay's sandbox gateway, which accepts HTTP callback URLs from local development servers.**

Testing payment integrations typically requires HTTPS endpoints, but this repository provides a **local sandbox server** that eliminates that barrier. The sandbox isolates the full Alipay Web Payment flow on your machine, making it ideal for development and CI pipelines without TLS certificates or public deployment.

## How the Sandbox Bypasses HTTPS Requirements

The core insight is architectural: **your local server communicates with Alipay, not your browser directly**. Alipay's sandbox gateway intentionally relaxes HTTPS enforcement for callback URLs, allowing plain HTTP addresses pointing to `localhost` or private networks.

### The Three-Layer Flow

1. **Local HTTP server** – Listens on `127.0.0.1:4174` (configurable via `ALIPAY_SANDBOX_PORT`)
2. **SDK-mediated gateway calls** – Outbound HTTPS from your server to Alipay's sandbox endpoint
3. **HTTP callbacks accepted** – Alipay redirects back to your local server over plain HTTP

## Local Sandbox Server Implementation

The entry point is `scripts/alipay-webpay-sandbox-server.mjs`, a standalone Node.js HTTP server using only built-in modules:

```javascript
// scripts/alipay-webpay-sandbox-server.mjs
import { createServer } from 'node:http';
import { randomUUID } from 'node:crypto';
import { getAlipayClient } from '../api/_lib/alipay.js';

const host = '127.0.0.1';
const port = Number(process.env.ALIPAY_SANDBOX_PORT || 4174);
const origin = `http://${host}:${port}`;  // Plain HTTP, no TLS

```

The server deliberately uses `node:http` rather than `node:https`, keeping dependencies minimal and startup instant.

## Alipay SDK Sandbox Configuration

The gateway selection logic lives in [`api/_lib/alipay.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/alipay.js). The **sandbox gateway URL** is what enables local HTTP testing:

```javascript
// api/_lib/alipay.js
import { AlipaySdk } from 'alipay-sdk';

const SANDBOX_GATEWAY = 'https://openapi-sandbox.dl.alipaydev.com/gateway.do';
const PRODUCTION_GATEWAY = 'https://openapi.alipay.com/gateway.do';

export function getAlipayClient({ sandbox = false } = {}) {
  const gateway = sandbox ? SANDBOX_GATEWAY : PRODUCTION_GATEWAY;
  return new AlipaySdk({
    appId: process.env.ALIPAY_APP_ID,
    privateKey: process.env.ALIPAY_PRIVATE_KEY,
    alipayPublicKey: process.env.ALIPAY_PUBLIC_KEY,
    gateway,
    // ... additional config
  });
}

```

When `sandbox: true`, the SDK targets `openapi-sandbox.dl.alipaydev.com`. This environment **accepts HTTP return URLs** in payment requests, unlike production which requires HTTPS.

## Complete Payment Flow Step-by-Step

### Step 1: Initiate Checkout

The user submits a form to `/checkout`, triggering server-side SDK invocation:

```javascript
async function handleCheckout(req, res) {
  const client = getAlipayClient({ sandbox: true });
  
  const request = {
    out_trade_no: generateOrderId(),
    total_amount: '0.01',
    subject: 'Sandbox Test Order',
    return_url: `${origin}/return`,      // HTTP URL accepted
    notify_url: `${origin}/notify`,      // HTTP URL accepted
  };
  
  // pageExec returns an HTML form that auto-submits to Alipay
  const paymentHtml = client.pageExec('alipay.trade.page.pay', 'POST', request);
  send(res, 200, paymentHtml, 'text/html');
}

```

The `return_url` and `notify_url` parameters use `http://127.0.0.1:4174` — explicitly **not HTTPS**.

### Step 2: Redirect Through Alipay Sandbox

Alipay's response is a self-submitting HTML form that sends the user to the sandbox payment UI. After simulated payment completion, Alipay redirects to your local HTTP endpoint.

### Step 3: Server-Side Verification

The sandbox server **never trusts query parameters** from the return URL. Instead, it independently queries Alipay to confirm payment status:

```javascript
// After Alipay redirects to /return?out_trade_no=XXX&...
async function handleReturn(req, res) {
  const client = getAlipayClient({ sandbox: true });
  
  // Verifiable server-to-server call
  const result = await client.exec('alipay.trade.query', {
    out_trade_no: req.query.out_trade_no
  });
  
  if (result.msg === 'Success' && result.code === '10000') {
    // Payment confirmed via Alipay's API, not URL tampering
    renderSuccess(res, result);
  }
}

```

This **verification pattern** is critical: client-side redirects can be spoofed, but the `alipay.trade.query` call over HTTPS to Alipay's gateway cannot.

## Key Files and Their Roles

| File | Purpose |
|------|---------|
| `scripts/alipay-webpay-sandbox-server.mjs` | Standalone HTTP server driving the complete sandbox UI and flow |
| [`api/_lib/alipay.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/alipay.js) | SDK wrapper with gateway selection logic |
| [`docs/alipay-web-payment.md`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/docs/alipay-web-payment.md) | Human-readable setup and usage guide |
| [`supabase/migrations/20260721090000_alipay_webpay.sql`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/supabase/migrations/20260721090000_alipay_webpay.sql) | Database schema for persisting sandbox notifications locally |

## Why This Approach Is Secure for Development

The sandbox maintains security boundaries without HTTPS on your local machine:

- **Alipay signatures verify authenticity** – All SDK responses are cryptographically signed
- **Secrets stay server-side** – Private keys never reach the browser
- **No production data exposure** – Sandbox environment is completely isolated
- **Query verification prevents spoofing** – Status confirmation happens via authenticated API calls, not redirect parameters

## Summary

- **No HTTPS required locally** because Alipay's sandbox gateway accepts HTTP callback URLs
- **Outbound HTTPS only** – From your server to `openapi-sandbox.dl.alipaydev.com`
- **Sandbox mode toggle** – Single boolean in `getAlipayClient({ sandbox: true })`
- **Always verify server-side** – Use `alipay.trade.query` to confirm payment status, never trust redirect parameters
- **Environment variable configuration** – `ALIPAY_APP_ID`, `ALIPAY_PRIVATE_KEY`, `ALIPAY_PUBLIC_KEY`, and optional `ALIPAY_SANDBOX_PORT`

## Frequently Asked Questions

### Does the sandbox work in CI environments without HTTPS?

**Yes.** The sandbox server binds to `127.0.0.1` by default, which works in containerized CI runners. Since all Alipay communication originates from the server (outbound HTTPS), no ingress configuration or TLS termination is required. Set `ALIPAY_SANDBOX_PORT` to avoid port conflicts if needed.

### Can I test with the production Alipay gateway using this setup?

**No.** The production gateway at `openapi.alipay.com` enforces HTTPS for all `return_url` and `notify_url` values. The sandbox specifically exists to bypass this requirement for local development. Attempting to use production credentials with HTTP callbacks will fail validation.

### How does the sandbox handle payment notifications?

**Synchronously via redirect, or asynchronously via polling.** The `notify_url` receives POST requests from Alipay, but in local development these require tunneling tools (like ngrok) for Alipay's servers to reach your machine. The `alipay-webpay-sandbox-server.mjs` primarily demonstrates the synchronous `return_url` flow with server-side query verification as the reliability mechanism.

### Is the private key ever exposed to the browser?

**Never.** The `AlipaySdk` initialization with `privateKey` happens only in [`api/_lib/alipay.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/alipay.js), which runs server-side. The browser receives only pre-signed HTML forms generated by `pageExec()`, containing one-time tokens that Alipay validates against your configured public key.