YuPay
# 🎮 YuPay —— Make Sponsorship Management a Pleasure
> **Minecraft server sponsorship has never been been this elegant.**
>
> Direct integration with WeChat Pay & Alipay, redeem code system, refund review, multi-language, full lifecycle event listening — everything you need, YuPay delivers it all at once. Free, no middlemen, no tricks. 100% of the revenue goes straight to your account. The only fees are those charged by Alipay and WeChat.
—
## 📦 What Is It
**YuPay** is a free, modern payment plugin tailored for Minecraft servers. It breaks down the hassle of “sponsorship management” into four steps: **Initiate → Pay → Receive → Record**. Every step is automated, every step traceable.
Server operators use it to collect sponsorships, players use it to scan and pay. Both sides enjoy a worry-free experience. Supports direct API integration with WeChat Pay and Alipay — no third-party relay, your funds stay secure in your own hands.
> ⚠️ This plugin is designed for scenarios where “players voluntarily sponsor server operations”. Please ensure usage complies with local laws and payment platform regulations.
—
## ✨ Highlights at a Glance
| Category | What You Get |
|———-|—————|
| 💳 **Payment** | WeChat + Alipay dual channels, Native QR scan payment, automatic fallback |
| 💰 **Economy** | Vault + PlayerPoints dual support, one-click switch |
| 🎁 **Rewards** | Base rewards, single milestone, total achievements, limited-time sprints — four trigger layers |
| 🔑 **Redeem Code** | Create/redeem/query/modify, supports paid codes, complete logs |
| 💵 **Refund** | Players can request refunds, admin approve/deny, forced refund, partial refund |
| 📊 **Data** | Leaderboards, order history, page browsing, one-click copy order ID |
| 🌐 **Multi-language** | Default Chinese + English, server owners can customize any language, different players see different languages |
| 🔌 **PAPI** | 40+ placeholders, use in scoreboards/titles/item lore |
| 🛡️ **Security** | Signature verification, IP whitelist, 24h event monitoring, anti-duplicate delivery |
| ⚡ **Performance** | Fully async, HikariCP connection pool, 600% startup speed boost |
| 🧩 **Extensibility** | Full lifecycle event API for deep integration by developers |
—
## 🔄 What a Complete Sponsorship Looks Like
1. Player executes a command, e.g. `/donate 50 wechat`
2. System creates order asynchronously, writes to database
3. Calls WeChat/Alipay API to generate payment QR code
4. Depending on your config, sends **clickable link**, **text-art QR** in chat, or **map QR** in inventory
5. Player scans and completes payment
6. Payment platform calls back to your server
7. Plugin verifies signature, confirms receipt, grants rewards (economy + commands)
8. Leaderboard and placeholders update in real time
9. All logs written, traceable anytime
Fully automated. You just configure the rewards, YuPay handles the rest.
—
## 🎁 Four Reward Layers, Mix and Match
YuPay’s reward system is like a Lego box — four trigger modes you can combine freely.
| Layer | Trigger | Example |
|——-|———|———|
| **Base Reward** | Every successful payment | `give {player} diamond 1` |
| **Single Milestone** | Single payment reaches threshold | 50 yuan → 5 gold blocks |
| **Total Achievement** | Lifetime total reaches new height | 500 yuan → SVIP permission group |
| **Limited Sprint** | Cumulative within specified time period | 200 yuan in 24h → enchanted golden apple |
Each layer’s commands are fully customizable, support variables like `{player}`, `{amount}`, `{points}`, and can integrate with permission/economy plugins like LuckPerms, CMI, etc.
> 💡 Adding `-n` (e.g. `/donate 10 -n`) makes it a **no-reward sponsorship** — pure server support, no rewards triggered.
—
## 🔑 Redeem Code System: More Than Just a Voucher
YuPay’s redeem code module goes far beyond typical “gift codes”:
– **Free codes**: Players enter to claim — great for event giveaways
– **Paid activation codes**: Players must scan and pay a specified amount before redeeming — suitable for selling item entitlements, redeeming codes from other platforms, etc.
– **Economy rewards**: Automatically grant Vault currency or PlayerPoints upon redemption
– **Custom commands**: Each code can bind a set of commands executed on redemption
– **Usage limits & expiry**: Independent control per code
– **Code PAPI**: Placeholders directly read any code’s status, amount, remaining uses
Create a paid activation code with a single command:
“`
/yp code create –code VIP2026 –amount 50 –economy vault –eco-amount 5000 –commands “lp user {player} parent set vip” –max-uses 100 –expire 30d
“`
—
## 💵 Refund System: Bad Debt Terminator
Refunds are no longer a nightmare. YuPay’s refund process is complete and reassuring:
– **Players request refund**: Submit application with reason
– **Admin reviews**: Approve/deny in an orderly manner
– **Forced refund**: Direct operation for urgent cases, no waiting for review
– **Partial refund**: Flexible handling, precise to the cent
– **Code refund**: Refund money and rollback usage count, status automatically restored
– **Refund callback**: Interfaces with WeChat/Alipay official refund API, money returns to original payment method
– **Complete logs**: Who refunded, how much, when, why — all clear
—
## 🌐 Thousand Players, Thousand Languages — No Language Fights
A lifesaver for international server operators.
– Comes with **Simplified Chinese** and **English** complete translations
– Server owners can add any language file in `language.mappings`
– Players switch preference with `/yp lang
– New players automatically **detect client language** and match the best translation
– Different players on the same server see different language prompts — truly per-player localization
—
## 🔌 Complete PAPI Placeholder List
YuPay provides **40+ built-in PlaceholderAPI placeholders**, covering personal, server, leaderboard, and redeem code dimensions. All monetary values keep two decimal places. Full list below:
—
### 1. Personal Dimension (requires player context)
| Placeholder | Description | Example Return |
|————-|————-|—————-|
| `%yupay_is_banned%` | Whether the player is banned from sponsoring | `true` / `false` |
| `%yupay_total%` | Player’s lifetime total sponsorship (yuan) | `158.00` |
| `%yupay_total_orders%` | Player’s total orders (including failed) | `7` |
| `%yupay_success_orders%` | Player’s successful orders | `5` |
| `%yupay_rank%` | Player’s sponsorship rank (off-rank shows text from language file) | `3` or `Not ranked` |
| `%yupay_has_paid_in_
> 💡 **Dynamic parameters**: `
—
### 2. Server Dimension (no player needed)
| Placeholder | Description | Example Return |
|————-|————-|—————-|
| `%yupay_server_total%` | Server’s lifetime total sponsorship (yuan) | `12850.75` |
| `%yupay_server_total_orders%` | Server’s total orders (including failed) | `312` |
| `%yupay_server_success_orders%` | Server’s successful orders | `289` |
| `%yupay_server_orders_in_
| `%yupay_server_success_orders_in_
| `%yupay_server_amount_in_
—
### 3. Leaderboard Dimension (no player needed)
Two formats supported (first recommended):
| Placeholder | Description | Example Return |
|————-|————-|—————-|
| `%yupay_top_
| `%yupay_top_
| `%yupay_top
| `%yupay_top
> `
—
### 4. Redeem Code Dimension
Includes global statistics (no player needed) and specific code attributes (where `redeemed` and `can_redeem` require player context).
#### Global Statistics
| Placeholder | Description | Example Return |
|————-|————-|—————-|
| `%yupay_code_total%` | Total number of codes | `25` |
| `%yupay_code_active%` | Number of active codes (status ACTIVE) | `18` |
#### Specific Code Attributes — replace `` with actual code string (auto-uppercase)
| Placeholder | Description | Example (code = `VIP2026`) |
|-------------|-------------|----------------------------|
| `%yupay_code__status%` | Current status of the code | `ACTIVE` |
| `%yupay_code__amount%` | Required payment amount (yuan) | `50.00` |
| `%yupay_code__economy_type%` | Economy reward type | `vault` |
| `%yupay_code__economy_amount%` | Economy reward amount | `5000.00` |
| `%yupay_code__used%` | Number of times redeemed | `23` |
| `%yupay_code__max_uses%` | Max redeem count (-1 = unlimited) | `100` |
| `%yupay_code__expire%` | Expiry timestamp (ms), -1 = never | `1798675199999` |
| `%yupay_code__expire_formatted%` | Formatted expiry time | `2026-12-31 23:59` |
| `%yupay_code__remark%` | Code remark | `"VIP activation code"` |
| `%yupay_code__locked%` | Whether locked by a payment (someone is paying) | `true` / `false` |
| `%yupay_code__redeemed%` | Whether **current player** has redeemed this code | `true` / `false` |
| `%yupay_code__can_redeem%` | Whether **current player** can redeem now (comprehensive check) | `true` / `false` |
> 💡 `_can_redeem` checks: code status normal, not expired, uses left, not locked by others, and current player hasn't redeemed it.
---
### Usage Notes
- **All monetary placeholders** are in `yuan`, with two decimal places, e.g. `99.50`. Integer amounts also show `.00`.
- Dynamic time parameter `
- Code strings in placeholders are auto-uppercased; lowercase input works too.
- Server and leaderboard placeholders **do not require a player context**; personal and some code placeholders **require a player** or return empty/default.
- Placeholders work in any plugin that supports PlaceholderAPI (scoreboard, BossBar, DeluxeTags, chat prefix, item lore, etc.).
---
## 🧩 Gift for Developers
If you can write plugins, these events will make your secondary development experience fly:
| Event | Trigger | Modifiable Parameters |
|-------|---------|----------------------|
| `PrePaymentEvent` | Before payment | amount, payment method, order ID, cancel flag |
| `PaymentOrderCreatedEvent` | Order created successfully | read-only (has QR URL) |
| `PaymentCompletedEvent` | Payment success + rewards granted | read-only (full data) |
| `PaymentFailedEvent` | Payment failed / canceled | read-only |
| `RefundCompletedEvent` | Refund completed | read-only |
| `RedeemCodeRedeemedEvent` | Code redeemed | read-only |
| `RedeemCodeLifetimeEvent` | Code status changed | read-only (old → new state) |
| `PlayerPointsChangedEvent` | Economy changed | read-only |
All events support sync. You can intercept before order creation, trigger联动 other systems after payment, sync data on refund — every detail of the sponsorship lifecycle is observable.
---
## 🛡️ Security Is Not Just Talk
- **Signature verification**: WeChat/Alipay callbacks are fully signature-verified against forgery
- **Anti-duplicate delivery**: Order status check + idempotent handling
- **IP whitelist**: Callback interface can restrict access to official payment platform IPs only
- **TLS/HTTPS**: Supports certificate-encrypted communication
- **Event monitoring**: `/yp audit` one-click audit, 24h monitoring of which plugins are listening to YuPay's fund events
- **Map virtual lock**: When a payment QR is placed in the inventory, the player is locked in place, cannot drop/switch items, payment unlocks
---
## ⚡ Blazing Fast Startup
The rewritten dependency loading system means YuPay no longer requires cumbersome JVM startup parameters. All dependencies are automatically managed, verification speed increased by 600%, out-of-the-box. Drop it into the `plugins` folder, start the server, it's ready.
---
## 📊 Data at Your Fingertips
`/yp history` is one of your most-used commands. Order history supports **page browsing**, click an order ID to **copy it with one click** — reconciliation efficiency doubled.
`/yp top` lets you know at any time who is contributing to the server — leaderboard data syncs with placeholders in real time.
`/yp total` for personal stats, `/yp total all` for server-wide stats — all available at your fingertips.
---
## 🚀 Two-Minute Quick Start Guide
1. Drop `YuPay.jar` into the `plugins/` folder
2. Start the server, wait for `config.yml` and `messages.yml` to generate
3. Open `config.yml`, fill in your WeChat/Alipay parameters
4. Ensure the callback port (default `8080`) is open in your server firewall and security group
5. In-game, type `/donate 0.01` to test a small payment
6. Confirm callback works and rewards arrive — start business 🎉
---
## 🏆 Why Server Owners Are Using YuPay
- ✅ **Stable**: Production-tested, compatible with Spigot/Paper 1.8 to latest versions
- ✅ **Reliable**: Direct official API connection, no middlemen, money goes to your account directly
- ✅ **Worry-free**: From payment to rewards fully automated, you just configure
- ✅ **Flexible**: Reward logic fully programmable, command aliases freely definable
- ✅ **Secure**: Signature verification + anti-duplicate + IP whitelist + event monitoring
- ✅ **Transparent**: Every order, every refund, every code redemption has logs
- ✅ **Evolving**: Actively maintained, continuously iterated, community-driven
---
> 💬 **Plugin Discussion Group: 1080918424**
>
> For issues, feature requests, or just to chat — welcome. Every improvement of YuPay comes from feedback from server owners.
> 💛 **Support the Author on AiFaDian**: https://ifdian.net/item/012b6c1c4a0911f18d1b52540025c377
>
> If YuPay has helped your server, consider buying the author a milk tea ~ Your support is the biggest motivation for the plugin's continued evolution.
**Stop struggling with sponsorship management. Leave the professional stuff to YuPay, and focus on running your server well.**
***
# 📖 YuPay Operation Manual
## 1. Environment Requirements
| Item | Requirement |
|------|-------------|
| Server | Spigot / Paper / compatible forks / compatible hybrid servers, 1.8 – 1.26+ |
| Java | JDK 8 or higher |
| Optional dependencies | Vault (economy), PlayerPoints (points), PlaceholderAPI (placeholders), ProtocolLib (map lock) |
> 🎉 **Good news**: You no longer need to manually add JVM startup parameters for Java 9+. YuPay's latest version has built-in smart dependency management — out-of-the-box.
## 2. Installation & Startup
1. Download `YuPay.jar`, place it in the server's `plugins/` directory
2. Start the server, the plugin will automatically generate `config.yml`, `messages.yml`, and SQLite database files
3. Edit `plugins/YuPay/config.yml`, fill in payment channel configuration parameters
4. Depending on your payment method, configure callback URLs in the payment platform backend:
- WeChat: `http(s)://your-domain-or-ip:port/pay/wechat/notify`
- Alipay: `http(s)://your-domain-or-ip:port/pay/alipay/notify`
5. Ensure the callback port (default `8080`) is open in firewall and security group
6. Execute `/yupay reload` or type `reload` in console to apply configuration
7. In-game, type `/donate 0.01` to test a small payment
## 3. Configuration Quick Reference
### 3.1 Core Payment Parameters
| Path | Description | Example |
|------|-------------|---------|
| `pay.default-method` | Default payment method | `wechat` / `alipay` |
| `pay.min-amount` | Minimum amount per order (yuan) | `0.01` |
| `pay.max-amount` | Maximum amount per order (-1 = unlimited) | `500` |
| `pay.max-daily-amount` | Daily cumulative limit (-1 = unlimited) | `1000` |
| `pay.order-subject` | Order subject template | `Sponsorship-{player}-{amount}yuan` |
### 3.2 WeChat Pay Parameters
| Path | Description |
|------|-------------|
| `wechat.enabled` | Enable (true/false) |
| `wechat.mchid` | Merchant ID |
| `wechat.appid` | Official account / Mini Program AppID |
| `wechat.serial-no` | API certificate serial number |
| `wechat.private-key-path` | Merchant private key (relative to `pems/` directory) |
| `wechat.public-key-path` | Platform public key (relative to `pems/` directory) |
| `wechat.public-key-id` | Platform public key ID |
| `wechat.api-v3-key` | API v3 key (32 characters) |
| `wechat.notify-url` | Complete callback notification URL |
### 3.3 Alipay Parameters
| Path | Description |
|------|-------------|
| `alipay.enabled` | Enable |
| `alipay.mode` | `public_key` or `cert` |
| `alipay.app-id` | App ID |
| `alipay.merchant-private-key` | Merchant private key (PKCS8, without headers/footers) |
| `alipay.alipay-public-key` | Alipay public key (required for public_key mode) |
| `alipay.app-cert-path` | App public key certificate (cert mode) |
| `alipay.alipay-cert-path` | Alipay public key certificate (cert mode) |
| `alipay.alipay-root-cert-path` | Alipay root certificate (cert mode) |
| `alipay.notify-url` | Async notification URL |
| `alipay.return-url` | Sync return URL |
### 3.4 Economy System
| Path | Description |
|------|-------------|
| `economy.enabled` | Enable economy rewards |
| `economy.type` | `vault` or `playerpoints` |
| `economy.rate` | 1 yuan = how many in-game currency/points |
### 3.5 QR Code Display
| Path | Description |
|------|-------------|
| `qrcode.default-output-mode` | `link` / `text` / `map` |
| `qrcode.text-qr-size` | Text mode QR side length (characters, default 12) |
| `qrcode.text-black-char` | Black pixel character (default `██`) |
| `qrcode.api-url` | Image generation API for link mode |
### 3.6 Callback Server
| Path | Description |
|------|-------------|
| `callback.port` | Listening port |
| `callback.host` | Bind address (`0.0.0.0` = all interfaces) |
| `callback.io-threads` | IO thread count |
| `callback.worker-threads` | Worker thread count |
| `callback.allowed-ips` | IP whitelist (CIDR format, empty = allow all) |
| `callback.access-log` | Enable access logging |
### 3.7 Database
| Path | Description |
|------|-------------|
| `database.type` | `sqlite` (standalone) or `mysql` (multi-server sync) |
| `database.mysql.*` | MySQL connection parameters |
| `database.connection-pool.*` | HikariCP connection pool parameters |
| `database.table-names.prefix` | Table prefix to avoid conflicts |
| `database.table-names.*` | Individual business table names (can be customized) |
## 4. Complete Reward Configuration Guide
### 4.1 Base Reward (on-success)
Executed on every successful payment — suitable for "base reward every sponsorship".
```yaml
commands:
on-success:
- "give {player} diamond 1"
- "effect give {player} minecraft:speed 30 1"
```
Available variables: `{player}` (player name), `{amount}` (amount), `{points}` (economy points earned)
### 4.2 Single Milestone (on-single-achieved)
Triggered when a single payment reaches a set amount. **Sort amounts from low to high**, multiple tiers allowed.
```yaml
commands:
on-single-achieved:
- amount: 50
commands:
- "say {player} reached 50 yuan in a single sponsorship!"
- "give {player} minecraft:gold_block 5"
- amount: 100
commands:
- "give {player} minecraft:diamond_block 3"
- "lp user {player} parent set vip"
```
### 4.3 Total Achievement (on-total-achieved)
Triggered when lifetime total reaches a new height. **Each tier triggers only once** — anti-duplicate mechanism built-in.
```yaml
commands:
on-total-achieved:
- total: 100
commands:
- "lp user {player} parent set vip"
- total: 1000
commands:
- "lp user {player} parent set ultimate"
- "give {player} minecraft:beacon 1"
```
### 4.4 Limited Sprint Reward (on-recent-achieved)
Triggered when cumulative amount within a specified time period (milliseconds) reaches the target. Great for holiday events, weekend leaderboard pushes, etc.
```yaml
commands:
on-recent-achieved:
- time: 86400000 # 24 hours
total: 200
commands:
- "give {player} minecraft:enchanted_golden_apple 5"
- time: 604800000 # 7 days
total: 500
commands:
- "give {player} minecraft:elytra 1"
```
### 4.5 Refund Trigger Commands (on-refund)
Executed after a successful refund — can be used to notify admins, log events.
```yaml
commands:
on-refund:
- "say {player}'s order {order} has been refunded {amount} yuan"
```
## 5. Command System
### 5.1 Player Commands
| Command | Function | Default Aliases |
|---------|----------|----------------|
| `/donate
| `/ytop` | Sponsorship leaderboard Top10 | `/paytop`, `/yt` |
| `/ytotal [player|all]` | Query total sponsorship | `/paytotal`, `/ytt` |
| `/yp history [page]` | My sponsorship history | `/yupay history` |
| `/yp lang [language]` | Switch personal language preference | |
| `/yp code redeem ` | Redeem a code | |
| `/yp cancel` | Cancel current map payment | |
> 💡 The `-n` flag means "no-reward sponsorship" — pure server support, no reward commands or economy items triggered.
### 5.2 Admin Commands
| Command | Function |
|---------|----------|
| `/yp reload` | Hot reload configuration |
| `/yp set
### 5.3 Key Permission Nodes
| Permission Node | Operations |
|----------------|------------|
| `yupay.command.pay` | Initiate sponsorship |
| `yupay.command.top` | View leaderboard |
| `yupay.command.total` | Query total sponsorship |
| `yupay.command.history` | View order history |
| `yupay.reload` | Reload config |
| `yupay.ban` | Manage blacklist |
| `yupay.convert` | Currency conversion |
| `yupay.audit` | Event listener audit |
| `yupay.admin` | Includes all above admin permissions |
## 6. Redeem Code System In-Depth
### 6.1 Code Creation Command Details
Code creation uses named parameters in `--param value` format, freely combinable:
```bash
# Free welfare code (unlimited uses, never expires)
/yp code create --code FREEGIFT --max-uses -1 --economy vault --eco-amount 100 --remark "New player gift"
# Paid activation code (pay 50 yuan to redeem, 100 uses, expires after 30 days)
/yp code create --code PREMIUM --amount 50 --economy vault --eco-amount 5000 --max-uses 100 --expire 30d --commands "lp user {player} parent set vip"
# Command-only code (no economy, no payment)
/yp code create --code WELCOME --commands "give {player} diamond 5; say {player} Welcome back!"
```
**Parameter quick reference:**
| Parameter | Description | Example |
|-----------|-------------|---------|
| `--code` | Code string (auto-uppercase) | `VIP2026` |
| `--amount` | Required payment amount (0 = free) | `50` |
| `--economy` | Economy type (vault / playerpoints / none) | `vault` |
| `--eco-amount` | Economy reward amount | `5000` |
| `--max-uses` | Max redeem count (-1 = unlimited) | `100` |
| `--expire` | Expiry time (`30d` / `24h` / `2026-12-31` / `never`) | `30d` |
| `--commands` | Commands to execute on redemption (semicolon-separated) | `"cmd1; cmd2"` |
| `--remark` | Remark description | `"VIP activation code"` |
### 6.2 Code Status Explanation
| Status | Meaning |
|--------|---------|
| `ACTIVE` | Usable |
| `DEPLETED` | Uses exhausted (automatic) |
| `EXPIRED` | Expired (automatic) |
| `DISABLED` | Manually disabled by admin |
### 6.3 Code PAPI Placeholders
Using code `VIP2026` as example:
| Placeholder | Example Return |
|-------------|----------------|
| `%yupay_code_total%` | Total number of codes |
| `%yupay_code_active%` | Number of active codes |
| `%yupay_code_VIP2026_status%` | `ACTIVE` |
| `%yupay_code_VIP2026_amount%` | `50.00` |
| `%yupay_code_VIP2026_used%` | `23` |
| `%yupay_code_VIP2026_max_uses%` | `100` |
| `%yupay_code_VIP2026_expire_formatted%` | `2026-12-31 23:59` |
| `%yupay_code_VIP2026_can_redeem%` | `true` / `false` |
| `%yupay_code_VIP2026_locked%` | `true` / `false` |
| `%yupay_code_VIP2026_redeemed%` | Whether current player has redeemed |
## 7. Refund System In-Depth
### 7.1 Refund Method Comparison
| Method | Command Example | Use Case |
|--------|-----------------|----------|
| Direct refund | `/yp refund ORDER001 50` | Confirmed refund needed, quick processing |
| Forced refund | `/yp refund ORDER001 50 -f` | Skip amount check, refund directly |
| Partial refund | `/yp refund ORDER001 30` | Refund part of the amount |
| Approval workflow | `/yp refund request ORDER001` → wait for approve | Scenarios requiring approval |
| Code refund | `/yp refund -r
### 7.2 Refund Approval Workflow
1. Player or admin submits refund request: `/yp refund request
2. Admin views pending list: `/yp refund pending`
3. Approve or reject: `/yp refund approve
4. Upon approval, actual refund automatically executes; upon rejection, requester is notified
### 7.3 What Happens After Refund
- Payment platform (WeChat/Alipay) receives refund request, money returns to original payment method
- Plugin updates order refund status (`FULL_REFUND` / `PARTIAL_REFUND`)
- If code refund: code usage count -1, status restored to `ACTIVE`
- Executes commands configured in `commands.on-refund`
- Triggers `RefundCompletedEvent` for other plugins to react
- Complete refund logs written to database
## 8. Multi-Language System
### 8.1 Adding a Language
Add under `language.mappings` node in `config.yml`:
```yaml
language:
mappings:
zh_cn:
file: "messages.yml"
aliases: [zh, cn, chinese]
client-locales: ["zh_cn", "zh_*"]
en:
file: "messages_en.yml"
aliases: [english, eng]
client-locales: ["en_*"]
ja:
file: "messages_ja.yml"
aliases: [japanese, jp]
client-locales: ["ja_*"]
```
Then create `plugins/YuPay/messages_ja.yml`, translating based on `messages.yml`. Plugin will automatically fill in missing keys.
### 8.2 Switching Language
- Players switch manually: `/yp lang en` (supports aliases, e.g. `english`)
- First join auto-detects client language and matches best translation
- Language preference stored in database, remembered across sessions
## 9. Database Selection Guide
| Server Scale | Recommended Type | Reason |
|--------------|------------------|--------|
| Single small server | SQLite | Zero configuration, out-of-the-box |
| Multi-server network | MySQL | Unified data, cross-server sync |
| Large network | MySQL + connection pool | High concurrency support, connection reuse |
## 10. Troubleshooting Common Issues
### Callback server fails to start
- Check if port is occupied
- Confirm firewall/security group has opened the port
- Check console error logs
### Payment successful but rewards not received
- Check order `status` in database — should be `SUCCESS`
- Confirm `economy.enabled` and `commands.enabled` are both `true`
- Check console for economy plugin load errors
### Map QR code not showing
- Confirm ProtocolLib matching server version is installed
- Check if `qrcode.default-output-mode` is set to `map`
- If ProtocolLib missing, mode auto-falls back to `link`
### WeChat Pay says public key file not found
- Check existence of `plugins/YuPay/pems/` directory
- Confirm `wechat.public-key-path` is correct
- Go to WeChat Merchant Platform → API Security → API Certificates → download platform certificate
### Configuration lost after plugin upgrade
- YuPay has built-in smart config upgrader — automatically backs up old file (`.bak` suffix) and merges new keys
- Manual backup before upgrade for extra peace of mind
## 11. Database Tables
| Table Name | Stored Content |
|------------|----------------|
| `yu_payments` | All payment orders, including refund status |
| `yu_total_levels` | Cumulative reward tier records |
| `yu_banned_players` | Sponsorship blacklist |
| `yu_player_lang` | Player language preferences |
| `yu_redeem_codes` | Redeem code master table |
| `yu_redeem_logs` | Redemption records |
| `yu_refund_logs` | Refund operation logs |
| `yu_refund_requests` | Refund review requests |
## 12. Uninstallation Steps
1. Execute `/yp reload` (ensure in-memory config is flushed)
2. Stop the server
3. Delete `plugins/YuPay.jar`
4. For complete removal, delete `plugins/YuPay` folder (including database)
---
> 💬 Plugin Discussion Group: **1080918424**
> Don't struggle alone — bring your logs and config screenshots to the group, the author and helpful server owners are there.
> 💛 **Support the Author on AiFaDian**: https://ifdian.net/item/012b6c1c4a0911f18d1b52540025c377
>
> If YuPay has helped your server, consider buying the author a milk tea ~ Your support is the biggest motivation for the plugin's continued evolution.
```