How the Alipay Web Payment Sandbox Works Locally Without HTTPS

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:

// 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. The sandbox gateway URL is what enables local HTTP testing:

// 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:

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:

// 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 SDK wrapper with gateway selection logic
docs/alipay-web-payment.md Human-readable setup and usage guide
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, 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →