Project Build
This page details how to compile, build, and start every DaxPay app. It is organized into four tracks — backend, Go, frontend, and mini-program — with one section per app covering environment requirements, build commands, artifact paths, and startup verification.
First tryout
If you just want to get DaxPay up and running to try it out, use the one-click installer instead — no local build required. This page is for scenarios that need secondary development or customized deployment.
The compilation chain from source to runnable artifacts is split into four independent tracks — backend / Go / frontend / mini-program — and each track has its own section below.
Startup order: middleware → main app → channel sub-apps (optional, pick one language edition) → frontend.
Getting the Source
Each app is an independent git repository; clone the ones you need into the same parent directory. All cd paths below assume the directory names used in this section:
# Main app: the public repository is named dax-pay; pass the target directory dax-pay-open explicitly
# (keeps it consistent with the ops panel and the paths used throughout this doc)
git clone -b 4.0 https://gitee.com/dromara/dax-pay.git dax-pay-open
# Channel sub-app (direct channels, Java edition)
git clone -b 4.0 https://gitee.com/opendaxpay/dax-pay-channel-one.git
# Web admin (admin panel + merchant panel from the same source) / mobile H5
git clone -b 4.0 https://gitee.com/opendaxpay/dax-pay-ui.git
git clone -b 4.0 https://gitee.com/opendaxpay/dax-pay-h5.gitNon-public repositories
The aggregate and international channel sub-apps (dax-pay-channel-two / dax-pay-channel-three) and the three uni-app repositories (dax-pay-app-admin / dax-pay-app-merchant / dax-pay-mini-cashier) are not on the public source list and are obtained through authorized channels; after cloning, the directory names already match the paths used in each section of this doc, so no adjustment is needed. The cashier app's remote repository was historically named dax-pay-cashier; locally the directory is always dax-pay-mini-cashier.
Environment Preparation
Shared and app-specific dependencies are summarized below; install as needed.
| Environment | Version | Applies to | Notes |
|---|---|---|---|
| JDK | 25+ | All Java backends | Java runtime (not required for containerized deployment — the image ships one) |
| mvnd | Latest | All Java backends | Maven Daemon, speeds up compilation |
| Node.js | ^22.13.0 || ^24.0.0 | All frontends | Frontend build environment |
| pnpm | >=10.0.0 | All frontends | Package manager (mandatory; preinstall blocks npm/yarn) |
| PostgreSQL | 14+ | Backend runtime dependency | Primary database (not needed to compile, needed to run) |
| Redis | 7+ | Backend runtime dependency | Distributed cache |
| Apache Artemis | Latest | Backend runtime dependency | JMS message queue for delayed payment notifications |
Spring Boot 4.1 build notes
-DskipTestsno longer skips AOT processing of tests; use-Dmaven.test.skip=trueinstead- In PowerShell,
-Darguments containing=must be quoted (e.g."-Dmaven.test.skip=true"), otherwise they are split on spaces
Database Preparation
The databases must be created in advance (UTF8 encoding, public schema). Databases used by each app:
| App | dev database | prod database |
|---|---|---|
| Main app dax-pay-open | daxpay-dev | daxpay-prod |
| Channel sub-apps (channel-one / channel-two) | same database as the main app, daxpay-dev | same database as the main app, daxpay-prod |
Import the Initialization SQL
After creating the database, import the initialization scripts from the _config/sql/ directory of the main app repository. Any method works — psql on the command line, or GUI tools such as Navicat / DBeaver; the key point is that the execution order must not be swapped: run table.sql first to create the table schema, then data.sql to load the initial data.
| Script | Purpose |
|---|---|
table.sql | Full table schema; step one of a fresh install |
data.sql | Full initial data (sanitized), including the built-in super admin account and menus; step two of a fresh install |
update-tables.sql | Table schema changes for version upgrades |
update-datas.sql | Data changes for version upgrades |
Upgrade scripts cannot cross versions
The update-* scripts only apply to upgrading from the previous version to the current one and must not be executed across multiple versions; to upgrade across versions, run each version's upgrade script in order, or rebuild directly with the full scripts.
Shared database
The channel sub-apps share the main app's database — no separate database creation or SQL import is needed. See Configuration for connection details.
First-Start Note
application-dev.yml in the repository uses the hostnames postgresql / redis / mq for connections (not localhost); before the first start, append 127.0.0.1 postgresql redis mq to your local hosts file, or change the connection settings in the yml directly. For quick commands to start middleware instances, see Run - Quick Middleware Setup.
Backend Apps
Main App dax-pay-open
The payment core backend, hosting payment business logic, channel routing orchestration, risk control, and system administration.
Stack: Java 25 · Spring Boot 4.1.1 · PostgreSQL · Redis · Apache Artemis · MyBatis-Plus · Sa-Token · MapStruct
Port: 9999
Build
cd dax-pay-open
# Full package (produces the runnable jar)
mvnd clean package "-Dmaven.test.skip=true" -T 4Never use install
mvnd install triggers a full package and writes to the local Maven repository — huge output, long runtime, and it easily deadlocks when piped through PowerShell. For day-to-day build verification use compile only; for production packaging use package.
Fast single-module compilation (compile only the modules affected by your change, much faster than a full build):
cd dax-pay-open
# -pl selects the module path; -am also builds its dependencies
mvnd compile -pl daxpay-payment/daxpay-payment-core -am "-Dmaven.test.skip=true"Artifact path: dax-pay-open/daxpay-start/target/daxpay-union.jar
Start
# Development mode (port 9999)
cd dax-pay-open/daxpay-start
mvnd spring-boot:run -Dspring-boot.run.profiles=dev
# Production mode (start from the jar)
java -jar dax-pay-start/target/daxpay-union.jar --spring.profiles.active=prodProduction credentials are injected via environment variables; see Configuration - production environment variables.
Verify
curl http://127.0.0.1:9999/actuator/health
# expect {"status":"UP"}On a successful start the console prints 应用 'dax-pay-open' 运行成功!; in dev the API docs are at http://127.0.0.1:9999/swagger-ui/index.html. After importing the initialization SQL you can sign in to the Web admin panel with the built-in super admin account — see Run - Default Login.
The main app consists of six Maven aggregate modules with top-down dependency direction (the actual dependencies of daxpay-start prevail):
There is also the daxpay-plugin plugin module (Yi-Pay compatibility / risk control); include it on demand — it does not take part in the default startup assembly.
Channel Sub-App dax-pay-channel-one
An independently deployed microservice integrating direct channels such as Alipay, WeChat, Douyin, UMS, and UnionPay (Cloud QuickPass); it hosts the direct invocation of third-party SDKs.
Stack: Java 25 · Spring Boot 4.1.1 · official channel SDKs (alipay-sdk / weixin-java-pay / douyinpay / self-developed UMS HTTP / UnionPay RSA2 certificate signing)
Port: 20100
Build
cd dax-pay-channel-one
mvnd clean package "-Dmaven.test.skip=true" -T 4Artifact path: dax-pay-channel-one/daxpay-channel-start/target/daxpay-channel-one.jar
Start
# Development mode (port 20100)
cd dax-pay-channel-one/daxpay-channel-start
mvnd spring-boot:run -Dspring-boot.run.profiles=dev
# Production mode
java -jar daxpay-channel-start/target/daxpay-channel-one.jar --spring.profiles.active=prodVerify
curl http://127.0.0.1:20100/actuator/health
# expect {"status":"UP"}Relationship with the main app
The main app calls this sub-app through a declarative @HttpExchange client, with AES-GCM encrypted transport. Start the main app first, or make sure it is reachable.
Channel Sub-App dax-pay-channel-two
An independently deployed microservice integrating aggregate channels (Lakala, Haike Rongtong, Dougong, Leshua, Fuiou, etc.); its architecture is identical to channel-one — only the set of hosted channels differs.
Stack: Java 25 · Spring Boot 4.1.1 · aggregate channel SDKs
Port: 20200
Build
cd dax-pay-channel-two
mvnd clean package "-Dmaven.test.skip=true" -T 4Artifact path: dax-pay-channel-two/daxpay-channel-start/target/daxpay-channel-two.jar
Start
# Development mode (port 20200)
cd dax-pay-channel-two/daxpay-channel-start
mvnd spring-boot:run -Dspring-boot.run.profiles=dev
# Production mode
java -jar daxpay-channel-start/target/daxpay-channel-two.jar --spring.profiles.active=prodVerify
curl http://127.0.0.1:20200/actuator/health
# expect {"status":"UP"}channel-two is enabled by default
All three sub-apps — channel-one / channel-two / channel-three — are already enabled in the main app's default routing configuration; no uncommenting needed. In production, sub-app addresses and channel transport keys are injected via environment variables such as CHANNEL_TWO_BASE_URL / CHANNEL_TWO_TRANSPORT_KEY; see Configuration - channel sub-app routing.
Frontend Apps
Prerequisites
All frontend apps require Node.js ^22.13.0 || ^24.0.0 and pnpm >=10.0.0. Run pnpm install in each app directory before the first build.
Web Admin dax-pay-ui
A monorepo based on Vue Vben Admin 5 that builds the admin panel and the merchant panel as two independent apps from the same source, sharing the packages/ framework packages and the i18n architecture.
Stack: Vue 3.5 · Vite 8 · TypeScript · antdv-next · vxe-table 4 · TailwindCSS 4 · vue-i18n · pnpm + Turbo
Sub-apps:
| Sub-app | Role | dev port | VITE_APP_CLIENT_CODE |
|---|---|---|---|
apps/daxpay-admin | Admin panel | 6999 | admin |
apps/daxpay-merchant | Merchant panel | 7999 | merchant |
Install and Develop
cd dax-pay-ui
pnpm install
# Admin panel development (port 6999)
pnpm run dev:admin
# Merchant panel development (port 7999)
pnpm run dev:merchantBuild
cd dax-pay-ui
# Build all apps (turbo runs them in parallel)
pnpm run build
# Build the admin panel only
pnpm -F daxpay-admin run build
# Build the merchant panel only
pnpm -F daxpay-merchant run buildArtifact paths:
| Sub-app | Artifacts |
|---|---|
| Admin panel | dax-pay-ui/apps/daxpay-admin/dist/ |
| Merchant panel | dax-pay-ui/apps/daxpay-merchant/dist/ |
Type Checking and Lint
pnpm run check:type # turbo run typecheck (vue-tsc)
pnpm run lint # ESLintMonorepo internals: the two sub-apps compile from the same source in different modes, sharing the framework layer:
The client identity is injected at build time from VITE_APP_CLIENT_CODE in .env, which together with the backend isolates menus and data per panel; see Configuration - Web admin.
Mobile H5 dax-pay-h5
A single app serving two fully independent page sets for PC and mobile, dispatched by device detection at the entry point; the mobile side uses postcss-mobile-forever for vw adaptation.
Stack: Vue 3.5 · Vite 8 · Vue Router · Vant 4 (mobile) · UnoCSS · Pinia · vue-i18n
Port (dev): 9500
Install and Develop
cd dax-pay-h5
pnpm install
# Development (port 9500; ?device=pc|mobile forces a device view)
pnpm run devBuild
cd dax-pay-h5
pnpm run buildArtifact path: dax-pay-h5/dist/vant-mobile/ (note the output directory is vant-mobile, not the default dist/)
PC and mobile
A single H5 build contains both the PC and mobile pages, dispatched at runtime by device detection — no separate builds needed. During development you can force a specific view with the ?device=pc|mobile query parameter.
Cross-Platform Apps
The three uni-app clients share the unibest 4, Vue 3.4, pnpm, and uni CLI workflow, but support different platforms. The admin and merchant clients support H5, WeChat / Alipay / Douyin mini-programs, and Android / iOS apps; the cashier supports the three mini-programs only.
For the full platform matrix, run commands, build commands, artifact paths, and development tool notes, see Cross-Platform Apps.
Static Deployment
uni-app artifacts
The static deployment in this section applies only to the Web admin panel, merchant panel, and standalone H5. uni-app mini-program artifacts must be imported into the corresponding platform's developer tools, and App artifacts into HBuilderX — they are not deployed to Nginx directly.
Frontend build artifacts are static files; deploy them to Nginx or any other static server. The example below covers the Web admin panel + H5 + API reverse proxy:
# Web admin (admin panel)
server {
listen 80;
server_name admin.daxpay.example.com;
root /var/www/daxpay-admin; # admin panel dist artifacts
location / {
try_files $uri $uri/ /index.html; # SPA history routing
}
# Reverse-proxy the API to the main app (the frontend production prefix is uniformly /api;
# the trailing slash on proxy_pass strips the /api prefix, so the backend never sees it)
location /api/ {
proxy_pass http://127.0.0.1:9999/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
# H5
server {
listen 80;
server_name h5.daxpay.example.com;
root /var/www/daxpay-h5/vant-mobile; # note: H5 artifacts live in the vant-mobile subdirectory
location / {
try_files $uri $uri/ /index.html;
}
# Reverse-proxy the API to the main app (the frontend production prefix is uniformly /api;
# the trailing slash on proxy_pass strips the /api prefix, so the backend never sees it)
location /api/ {
proxy_pass http://127.0.0.1:9999/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# Reverse-proxy domain verification files to the main app (see the note below;
# regex locations take priority over plain prefixes, so these are not swallowed by the try_files fallback)
# Root path: WeChat domain verification MP_verify_*.txt / random-name .txt for plain-link QR rules /
# Alipay linked plain QR .html
# File names are restricted to >= 8 characters, which naturally excludes root static files
# such as index.html (5 chars) and robots.txt (6 chars)
location ~ ^/[A-Za-z0-9_]{8,64}\.(txt|html)$ {
proxy_pass http://127.0.0.1:9999;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# Verification files under QR terminal / unified cashier / aggregate pay directories
# (platforms require them in the last path segment of the rule URL);
# business paths (/m/{code} etc., without extension) do not match and are still served by the SPA
location ~ ^/(m|cm|am)/[A-Za-z0-9_]{1,64}\.(txt|html)$ {
proxy_pass http://127.0.0.1:9999;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}Merchant panel
apps/daxpay-merchant/dist/ deploys exactly like the admin panel — just configure another server block for it.
Domain verification files must be reverse-proxied by Nginx to the main app
When you configure domain ownership and plain-link QR rules, WeChat/Alipay fetch the verification file as plain text and compare it for ownership — they do not execute page scripts. H5 is a pure static SPA: the index.html returned by the try_files fallback is useless for verification, so these paths must be reverse-proxied by Nginx to the main app before they fall into the SPA fallback, and the main app gateway responds uniformly by looking the file up in the database. File contents are uploaded and maintained in the admin panel under "Payment Config → Domain Verification Files" (merchant-level MP_verify_*.txt can also be uploaded from the merchant panel's "Domain Verification Files" page); uploads take effect immediately, with no Nginx changes. The domain must be publicly reachable before the platform-side check can pass; for DNS switching timing see Local Debugging.
Build Verification
How to verify each app after a successful start:
| App | Verification |
|---|---|
| Main app dax-pay-open | console prints 应用 'dax-pay-open' 运行成功! · http://127.0.0.1:9999/actuator/health |
| channel-one | http://127.0.0.1:20100/actuator/health |
| channel-two | http://127.0.0.1:20200/actuator/health |
| Web admin panel (dev) | http://127.0.0.1:6999 |
| Web merchant panel (dev) | http://127.0.0.1:7999 |
| Standalone H5 (dev) | http://127.0.0.1:9500 |
| uni-app admin (H5 dev) | http://127.0.0.1:9000 |
| uni-app merchant (H5 dev) | http://127.0.0.1:9100 |
Related Sections
- Run: the single entry point for choosing how to run by scenario
- Cross-Platform Apps: running, building, and publishing the three uni-app clients
- Configuration: profile switching, database, Redis, secrets, and production environment variables (per app)
- Local Debugging: tunneling, callback domains, and phone-side H5 debugging