Staking Module
Fixed-period staking with admin-configured APYs, three penalty modes and a custom WordPress post type
What the Staking Module Is
The Staking Module lets your users lock a portion of their balance for a fixed period and earn a configurable APY. Each "staking page" is a custom WordPress post (post type wpcrypto_stake_page) with its own coin, periods, rates and penalty rules. Stakes are entirely internal accounting — no smart contract is deployed, no on-chain transaction is made, and your platform's balance ledger is the source of truth.
📋 Quick facts
- Post type:
wpcrypto_stake_page - Shortcode:
[wpcrypto_stake page_id="X"] - Six fixed periods: 10 days, 20 days, 30 days, 3 months, 6 months, 1 year
- Per-period APY set by the admin (no dynamic / market-driven adjustments)
- Three penalty modes for early unstake (see below)
- Default penalty rate:
10%with typereward_only
Where to Find It
Open WP Crypto → Staking Pools in the WordPress admin sidebar. The list mirrors the standard WordPress post list, scoped to the wpcrypto_stake_page post type. From there you can Add New to create a new staking page or open an existing one to edit its periods and rates.
Creating a Staking Page
- Add New. WP Crypto → Staking Pools → Add New opens the staking editor.
- Set the title and description. These render on the public stake page.
- Pick the staked coin. Choose from any coin you have configured in Coins Manager.
- Set APY per period. The form gives you one APY input per lock period (10d / 20d / 30d / 3m / 6m / 1y). Empty periods are hidden on the public page.
- Configure the early-unstake penalty. Pick a penalty rate (default
10%) and one of the three penalty modes described below. - Publish. The plugin can also auto-create a public WordPress page that embeds the shortcode, or you can paste
[wpcrypto_stake page_id="X"]on any page you already have.
Lock Periods and APY
The plugin offers six fixed lock periods. For each period you set the APY independently — there is no global rate, no dynamic adjustment, no market-driven recalculation. The APY you save is the APY users see and earn.
| Period key | Length | Use case |
|---|---|---|
10_days | 10 days | Short-term liquidity-friendly stake |
20_days | 20 days | Slightly higher APY than 10-day |
30_days | 30 days | Monthly cadence — often the marketing default |
3_months | 3 months | Quarter-long lock |
6_months | 6 months | Mid-term retention |
1_year | 1 year | Long-term commitment with the highest APY |
Rewards are computed pro-rata between the stake start and the unlock time using the saved APY. The runtime helper wpcrypto_stake_pages_calculate_precise_reward() does the math so partial-period figures are accurate to the second.
Penalty Modes
If a user unstakes before the lock period ends, the plugin applies a penalty using one of three modes. The rate (default 10%) is applied to whichever base the mode targets.
| Mode | Penalty target | Best for |
|---|---|---|
reward_only (default) | Penalty deducts only from the accrued reward; the principal is returned in full | User-friendly — penalises only the rewards earned so far |
principal_only | Penalty is applied to the principal; rewards are forfeited entirely | Stronger lock — discourages early exit even when no reward has accrued yet |
total_amount | Penalty is applied to (principal + accrued reward) | Maximum deterrent — useful on premium-APY long-term pools |
The user-facing stake page renders the chosen mode and the penalty rate so users see exactly what happens before they confirm.
The Shortcode
Embed the public stake page anywhere with:
[wpcrypto_stake page_id="123"]
The page_id attribute references the post id of the staking page you created. The renderer loads the periods, APYs and penalty configuration for that page and displays:
- The available lock periods with their APYs
- A live reward calculator
- The penalty warning
- A stake-now button (which prompts unauthenticated visitors to log in)
- The user's own active stakes on this page, if they have any
When the admin publishes a staking page, the plugin can also auto-create a sibling WordPress page that already embeds the shortcode — useful if you do not want to copy-paste the shortcode yourself.
How the Balance Math Works
Stakes are pure ledger operations:
- Stake start. The plugin moves the staked amount from the user's available balance to a locked-stake state.
- While locked. The reward accrues on read (it is not periodically materialised); the UI shows the precise reward at any point in time.
- Unlock at maturity. Principal + accrued reward are credited back to the user's available balance.
- Early unstake. The penalty is computed based on the configured mode, the remaining principal/reward is credited back, and the penalty stays with the platform.
No on-chain transaction is made; everything happens in the WordPress database against the user's internal balance.
Operator Notes
⚠️ Things to know before launch
- Pick APYs you can sustain. The platform pays rewards out of the same balance pool; there is no external yield source.
- Decide your penalty stance up front. Switching from
reward_onlytototal_amountafter users have already staked changes their terms mid-flight — communicate before changing. - One stake page per token is usually enough. Create more pages only when you want different penalty rules or different coin pools on the same page.
- The 10-day period is the shortest. The plugin does not support arbitrary "flexible" periods (e.g. 7 days, 14 days) — the periods are fixed.
Troubleshooting
The stake page renders an empty period grid
None of the six periods has an APY saved. Re-open the staking page in the admin and enter at least one APY before publishing.
Reward calculator shows zero
The APY for the selected period is 0. Pick a period with a non-zero APY, or set one in the admin.
Users can't stake — "balance too low"
The user does not have enough of the staked coin in their available balance. Top them up via the user-management screens or instruct them to deposit / buy the coin first.
Penalty is applied at unlock when it should not be
The unstake button is firing the early-exit branch because the lock period has not technically elapsed yet. Confirm the user opened the stake at the time they think they did — there is no grace period in the calculator.