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
- Local HTTP server – Listens on
127.0.0.1:4174(configurable viaALIPAY_SANDBOX_PORT) - SDK-mediated gateway calls – Outbound HTTPS from your server to Alipay's sandbox endpoint
- 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.queryto confirm payment status, never trust redirect parameters - Environment variable configuration –
ALIPAY_APP_ID,ALIPAY_PRIVATE_KEY,ALIPAY_PUBLIC_KEY, and optionalALIPAY_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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →