Appearance
Buy-Features
A buy-feature lets a player pay a fixed price for direct entry into a bonus feature (for example, free spins). The player does not need to trigger the feature in the base game.
How It Works
The published game defines each available option. loadConfig.config.buyFeatures supplies its runtime price, return to player (RTP), and initial spin count. The current engine exposes the configured target price and effective feature RTP.
Use these returned values. Do not reconstruct the price from base-game RTP or a remembered generator formula. Rebuild the purchase display when the session configuration changes.
Some verticals use featureToBuy to select a normal bet table with price 1. See that vertical's guide before treating every table as a bonus purchase.
Getting Available Buy-Features
The loadConfig response includes the buy-features:
typescript
const response = await loadConfig({ backendURL, token: sessionToken });
if (response.success) {
const buyFeatures = response.result.config.buyFeatures;
if (buyFeatures && buyFeatures.length > 0) {
for (const feature of buyFeatures) {
console.log(`Feature: ${feature.id}`);
console.log(` Price: ${feature.price}x stake`);
console.log(` Initial spins: ${feature.initialSpins}`);
}
}
}Buy-Feature Option Type
Each entry in config.buyFeatures is IBuyFeatureOption & { id: string }:
typescript
// Base type
interface IBuyFeatureOption {
feature: string; // Name of the table whose entries the engine uses
price: number; // Buy price as multiplier of stake
featureRTP: number; // Feature RTP percentage
initialSpins: number; // Spins awarded on initial trigger
}
// In config.buyFeatures, each entry also has an `id` field:
// (IBuyFeatureOption & { id: string })[]| Field | Type | Description |
|---|---|---|
id | string | Feature identifier |
feature | string | Name of the table whose entries the engine uses in the engine configuration |
price | number | Buy price as a multiplier of stake. A price of 100 means the feature costs 100x the stake amount |
featureRTP | number | The expected return percentage when buying this feature |
initialSpins | number | Number of spins the engine awards on the initial trigger (before retriggers) |
Purchasing a Feature
Resolve legal stakes and the full purchase cost first. Require packageBuyEnabled under the approved policy for paid slot bonus purchases. Check maxPackageStake against the total debit. Confirm the cost with the player before sending the request.
The current engine applies some purchase limits to the base stake only. Its acceptance does not replace your check of the complete debit.
To buy a feature, call placeBet with featureToBuy. The engine computes the price from the stake and the configured price multiplier. The client only needs to pass the feature ID:
typescript
const feature = buyFeatures[0]; // e.g. { id: 'freespin', price: 100 }
const currentStake = legalStakes[selectedStakeIndex]; // validated policy ladder
const response = await placeBet({
backendURL,
token: sessionToken,
stake: currentStake,
featureToBuy: feature.id,
config,
});
if (response.success) {
const gameResult = response.result.result;
// Render, finish timing, then inspect choices and collection before continuation.
}TIP
feature.price is a multiplier of stake. Use it for UI display (feature.price * currentStake) to show the total cost. You do not need to send it back to the engine.
TIP
response.result.result.engineData.buyFeatureId echoes back feature.id on this reply. It also echoes on every later reply for the round, including continuations and collect. See Endpoints for the full field reference.
Next Steps
- Response Handling - Handle the multi-step round after purchasing.
- Gamble Features - Other post-win features.
- Freeplays - Spending an operator-granted ticket instead of buying a feature.
- Endpoints -
placeBetparameter reference.
Resume and finish a purchase
Read the bought ID from response.result.result.engineData.buyFeatureId. Read the original selected stake from engineData.baseStake.
The RGS can store the full purchase debit in both gameRoundInfo.stake and gameRoundInfo.baseStake. Do not multiply payouts by that purchase debit. If a legacy bought round lacks the engine base stake, resolve its history before further play.
Continue the existing round without repeating featureToBuy or stake. Render all awarded spins and retriggers. Respect choices, collect availability, exposure caps, and final round status.
Apply the recovery procedure after an uncertain purchase response. Never resend the purchase automatically.