Skip to content

Previous: ่„šๆœฌAPI.mdใ€€ยทใ€€Next: ../05-ๅ‚่€ƒ/ๆœฏ่ฏญ่กจ.md Related: APIๆฆ‚่งˆ.md ยท ่„šๆœฌAPI.md ยท ../02-ๆœไธปๆŒ‡ๅ—/็ปๆตŽๅŠจไฝœ.md ยท ../03-ๅค–้ƒจๆ’ไปถๅฏนๆŽฅ/็ปๆตŽๆ’ไปถ.md

๐Ÿ’ฐ Economy API โ€‹

QCL uses EconomyBridge to flatten economy backends like Vault / ExcellentEconomy / PlayerPoints into a single unified set of calls. This page covers the com.qinhuai.corelib.economy package: all EconomyBridge methods, the EconomyProvider interface, EconomyTransactionResult and error codes, the differences between the three backends, selectProvider, parseMoneyRequirement, EconomyActionParser / EconomyGuiActions, plus call examples and best practices.

For the server-admin-facing GUI economy action syntax see ../02-ๆœไธปๆŒ‡ๅ—/็ปๆตŽๅŠจไฝœ.md; for a detailed breakdown of backend integration differences see ../03-ๅค–้ƒจๆ’ไปถๅฏนๆŽฅ/็ปๆตŽๆ’ไปถ.md.


๐ŸŒ‰ EconomyBridge โ€‹

The economy facade (a Kotlin object; from Java use INSTANCE). All amount methods accept an optional providerId / currencyId: if omitted, the default provider and default currency are used.

Lifecycle โ€‹

MethodPurpose
init(plugin)Initialize (called by QCL)
reloadFromConfig()Reload from config
clear()Clean up
isAvailable(): BooleanWhether an economy backend is available

Query / Operations โ€‹

MethodSignatureReturns
getBalancegetBalance(player: OfflinePlayer, providerId?, currencyId?)Double
hashas(player, amount, providerId?, currencyId?)Boolean
depositdeposit(player, amount, providerId?, currencyId?)EconomyTransactionResult
withdrawwithdraw(player, amount, providerId?, currencyId?)EconomyTransactionResult
setBalancesetBalance(player, amount, providerId?, currencyId?)EconomyTransactionResult

Provider Selection / Info โ€‹

MethodReturnsPurpose
selectProvider(providerId?, currencyId?)EconomyProvider?Select a specific provider (both omitted = default)
getActiveProvider()EconomyProvider?The currently active provider
availableProviderIds()List<String>All available provider ids
getDefaultProviderId()StringDefault provider id
getDefaultCurrencyId()StringDefault currency id

Parsing / Diagnostics โ€‹

MethodReturnsPurpose
parseMoneyRequirement(str)MoneyRequirementParse a requirement string into a structure
diagnose()DiagnosticResult<List<BridgeStatus>>Diagnose the status of each backend
bridgeStatuses()Status listDetailed status of each backend

๐Ÿ”Œ EconomyProvider Interface โ€‹

Each economy backend implements an EconomyProvider:

kotlin
interface EconomyProvider {
    val id: String
    fun isAvailable(): Boolean
    fun getBalance(player, currencyId?): Double
    fun has(player, amount, currencyId?): Boolean
    fun deposit(player, amount, currencyId?): EconomyTransactionResult
    fun withdraw(player, amount, currencyId?): EconomyTransactionResult
    fun setBalance(player, amount, currencyId?): EconomyTransactionResult
}

In general you do not need to implement a provider yourself (unless you are wiring up a new economy backend). Day-to-day integration goes through EconomyBridge.


๐Ÿงพ EconomyTransactionResult and Error Codes โ€‹

EconomyTransactionResult(success, message?, code, suggestion, provider)

Construction helpers:

  • EconomyTransactionResult.ok(provider) โ€”โ€” success.
  • EconomyTransactionResult.fail(message, code, suggestion, provider) โ€”โ€” failure.
  • result.toDiagnostic(source) โ€”โ€” convert to a diagnostic object.

Common codes โ€‹

codeMeaning
OKSuccess
CURRENCY_REQUIREDThe backend requires an explicit currency (e.g. ExcellentEconomy multi-currency), but no currencyId was passed
INSUFFICIENT_FUNDSInsufficient balance
NO_PROVIDERNo economy backend available

๐Ÿฆ Differences Between the Three Backends โ€‹

BackendCurrencyOffline supportKey points
VaultSingle currencyโœ… Supports offlineNo currencyId needed
ExcellentEconomy (EE)Multi-currencyโŒ Online onlyMust specify currencyId, otherwise reports CURRENCY_REQUIRED; offline players cannot be operated on
PlayerPointsPointsโœ… Supports offlineInteger points; amounts are processed as integers

See ../03-ๅค–้ƒจๆ’ไปถๅฏนๆŽฅ/็ปๆตŽๆ’ไปถ.md for details.


๐Ÿงฎ parseMoneyRequirement โ€‹

Parses a requirement string into a MoneyRequirement(providerId, currencyId, operator, amount):

kotlin
val req = EconomyBridge.parseMoneyRequirement(">=100")
// operator=">=", amount=100.0, provider/currency use defaults

val req2 = EconomyBridge.parseMoneyRequirement("excellenteconomy:gold:>=50")
// providerId="excellenteconomy", currencyId="gold", operator=">=", amount=50.0

Syntax: [provider:][currency:]<operator><amount>. Used for "condition requires the player to have a certain amount of money" type checks.


๐Ÿ›’ EconomyActionParser / EconomyGuiActions โ€‹

EconomyActionParser โ€‹

EconomyActionParser.parse(value) โ†’ EconomyActionSpec(amount, providerId?, currencyId?, failMessage?), parses the value string in a GUI action into a structure (for the value syntax see ../02-ๆœไธปๆŒ‡ๅ—/็ปๆตŽๅŠจไฝœ.md).

kotlin
val spec = EconomyActionParser.parse("excellenteconomy:gold:500")
// amount=500, providerId="excellenteconomy", currencyId="gold"

EconomyGuiActions โ€‹

The economy executor for GUI click actions:

MethodCorresponding action
giveMoneygive_money
takeMoneytake_money (checks balance first; does not deduct if insufficient)
setMoneyset_money

๐Ÿงช Call Examples โ€‹

Query balance / check โ€‹

kotlin
val bal = EconomyBridge.getBalance(player)
if (EconomyBridge.has(player, 100.0)) {
    // has at least 100
}
java
double bal = EconomyBridge.INSTANCE.getBalance(player, null, null);
boolean ok = EconomyBridge.INSTANCE.has(player, 100.0, null, null);

Withdraw (handling insufficient balance) โ€‹

kotlin
val r = EconomyBridge.withdraw(player, 100.0)
when {
    r.success -> player.sendMessage("ๆ‰ฃๆฌพๆˆๅŠŸ")
    r.code == "INSUFFICIENT_FUNDS" -> player.sendMessage("ไฝ™้ขไธ่ถณ๏ผš${r.message}")
    r.code == "NO_PROVIDER" -> logger.warning("ๆฒกๆœ‰ๅฏ็”จ็ปๆตŽๅŽ็ซฏ")
    else -> player.sendMessage("ไบคๆ˜“ๅคฑ่ดฅ๏ผš${r.message}๏ผˆ${r.suggestion}๏ผ‰")
}

Deposit / set balance โ€‹

kotlin
EconomyBridge.deposit(player, 50.0)
EconomyBridge.setBalance(player, 0.0)

Handling CURRENCY_REQUIRED (multi-currency backend) โ€‹

kotlin
var r = EconomyBridge.withdraw(player, 50.0)   // no currency specified
if (r.code == "CURRENCY_REQUIRED") {
    // multi-currency backends like EE must specify currencyId and retry
    r = EconomyBridge.withdraw(player, 50.0, "excellenteconomy", "gold")
}

Specifying provider / currency โ€‹

kotlin
val provider = EconomyBridge.selectProvider("excellenteconomy", "gold")
if (provider != null && provider.isAvailable()) {
    provider.withdraw(player, 50.0, "gold")
}

โœ… Best Practices โ€‹

  • Always check the returned code, don't just look at successโ€”CURRENCY_REQUIRED / NO_PROVIDER need to be handled differently.
  • Use withdraw to deduct; it already checks the balance internally; don't getBalance yourself and then deduct (there's a race condition).
  • For multi-currency backends (EE) always pass currencyId, otherwise CURRENCY_REQUIRED; and you can only operate on online players.
  • PlayerPoints uses integer points; passing a decimal will be processed as an integer, so keep this in mind when designing reward amounts.
  • At startup, use isAvailable() / diagnose() to confirm the backend is ready and give the server admin a clear error.
  • Use result.message for prompts shown to players, and result.code + result.suggestion for pinpointing issues in logs.

๐Ÿ“š Further Reading โ€‹