0
# Advertising & Monetization
1
2
Advertising integration including native ads, banner ads, conversion tracking, and monetization features for VK Mini Apps.
3
4
## Capabilities
5
6
### Banner Advertising
7
8
Display and manage banner advertisements within the Mini App interface.
9
10
```typescript { .api }
11
/**
12
* Show banner advertisement
13
* @param props - Banner ad configuration
14
*/
15
function send(method: 'VKWebAppShowBannerAd', props: ShowBannerAdRequest): Promise<VKWebAppShowBannerAdResponse>;
16
17
/**
18
* Check banner ad availability
19
*/
20
function send(method: 'VKWebAppCheckBannerAd'): Promise<VKWebAppCheckBannerAdResponse>;
21
22
/**
23
* Hide currently displayed banner ad
24
*/
25
function send(method: 'VKWebAppHideBannerAd'): Promise<VKWebAppHideBannerAdResponse>;
26
27
interface ShowBannerAdRequest {
28
/** Banner placement location */
29
banner_location: BannerAdLocation;
30
}
31
32
enum BannerAdLocation {
33
TOP = 'top',
34
BOTTOM = 'bottom'
35
}
36
37
interface VKWebAppShowBannerAdResponse {
38
result: boolean;
39
}
40
41
interface VKWebAppCheckBannerAdResponse {
42
result: boolean;
43
}
44
45
interface VKWebAppHideBannerAdResponse {
46
result: boolean;
47
}
48
```
49
50
### Native Advertising
51
52
Display native ads that blend with app content for better user experience.
53
54
```typescript { .api }
55
/**
56
* Show native advertisements
57
* @param props.ad_format - Type of native ad format
58
* @param props.use_waterfall - Use waterfall ad loading (optional)
59
*/
60
function send(method: 'VKWebAppShowNativeAds', props: {
61
ad_format: EAdsFormats;
62
use_waterfall?: boolean;
63
}): Promise<{ result: true }>;
64
65
/**
66
* Check native ad availability
67
* @param props.ad_format - Type of native ad format to check
68
* @param props.use_waterfall - Use waterfall ad loading (optional)
69
*/
70
function send(method: 'VKWebAppCheckNativeAds', props: {
71
ad_format: EAdsFormats;
72
use_waterfall?: boolean;
73
}): Promise<{ result: boolean }>;
74
75
enum EAdsFormats {
76
REWARD = 'reward',
77
INTERSTITIAL = 'interstitial'
78
}
79
```
80
81
### Analytics & Tracking
82
83
Track user interactions and conversions for advertising optimization.
84
85
```typescript { .api }
86
/**
87
* Fire retargeting pixel for user tracking
88
* @param props - Retargeting pixel configuration
89
*/
90
function send(method: 'VKWebAppRetargetingPixel', props: RetargetingPixelOptions): Promise<{
91
result: true;
92
}>;
93
94
/**
95
* Track conversion events
96
* @param props.pixel_code - Pixel tracking code
97
* @param props.conversion_event - Event identifier
98
* @param props.conversion_value - Event value
99
*/
100
function send(method: 'VKWebAppConversionHit', props: {
101
pixel_code: string;
102
conversion_event: string;
103
conversion_value: number;
104
}): Promise<{ result: true }>;
105
106
interface RetargetingPixelOptions {
107
/** Pixel tracking code */
108
pixel_code: string;
109
/** Custom parameters */
110
custom_params?: Record<string, string | number>;
111
}
112
```
113
114
**Usage Examples:**
115
116
```typescript
117
// Check and show banner ads
118
const bannerAvailable = await bridge.send('VKWebAppCheckBannerAd');
119
120
if (bannerAvailable.result) {
121
const bannerResult = await bridge.send('VKWebAppShowBannerAd', {
122
banner_location: BannerAdLocation.BOTTOM
123
});
124
125
console.log('Banner ad shown:', bannerResult.result);
126
} else {
127
console.log('Banner ads not available');
128
}
129
130
// Show rewarded video ads
131
const rewardedAdsAvailable = await bridge.send('VKWebAppCheckNativeAds', {
132
ad_format: EAdsFormats.REWARD
133
});
134
135
if (rewardedAdsAvailable.result) {
136
await bridge.send('VKWebAppShowNativeAds', {
137
ad_format: EAdsFormats.REWARD,
138
use_waterfall: true
139
});
140
141
// Listen for ad completion event
142
bridge.subscribe((event) => {
143
if (event.detail.type === 'VKWebAppShowNativeAdsResult') {
144
console.log('Rewarded ad completed - give user reward');
145
giveUserReward();
146
}
147
});
148
}
149
150
// Track conversion events
151
await bridge.send('VKWebAppConversionHit', {
152
pixel_code: 'your-pixel-code',
153
conversion_event: 'purchase',
154
conversion_value: 100
155
});
156
157
// Track retargeting pixel
158
await bridge.send('VKWebAppRetargetingPixel', {
159
pixel_code: 'your-retargeting-pixel',
160
custom_params: {
161
user_id: '12345',
162
category: 'gaming',
163
value: 50
164
}
165
});
166
```
167
168
## Monetization Strategies
169
170
### Ad-Based Revenue
171
172
```typescript
173
class AdManager {
174
private adShownCount = 0;
175
private rewardedAdCooldown = 0;
176
177
async showInterstitialAd(): Promise<boolean> {
178
const available = await bridge.send('VKWebAppCheckNativeAds', {
179
ad_format: EAdsFormats.INTERSTITIAL
180
});
181
182
if (available.result) {
183
await bridge.send('VKWebAppShowNativeAds', {
184
ad_format: EAdsFormats.INTERSTITIAL
185
});
186
this.adShownCount++;
187
return true;
188
}
189
190
return false;
191
}
192
193
async showRewardedAd(): Promise<boolean> {
194
if (Date.now() < this.rewardedAdCooldown) {
195
console.log('Rewarded ad on cooldown');
196
return false;
197
}
198
199
const available = await bridge.send('VKWebAppCheckNativeAds', {
200
ad_format: EAdsFormats.REWARD
201
});
202
203
if (available.result) {
204
await bridge.send('VKWebAppShowNativeAds', {
205
ad_format: EAdsFormats.REWARD
206
});
207
208
// Set cooldown (e.g., 5 minutes)
209
this.rewardedAdCooldown = Date.now() + 5 * 60 * 1000;
210
return true;
211
}
212
213
return false;
214
}
215
216
async manageBannerAds(): Promise<void> {
217
const available = await bridge.send('VKWebAppCheckBannerAd');
218
219
if (available.result) {
220
// Show banner at bottom
221
await bridge.send('VKWebAppShowBannerAd', {
222
banner_location: BannerAdLocation.BOTTOM
223
});
224
225
// Hide after certain actions
226
setTimeout(async () => {
227
await bridge.send('VKWebAppHideBannerAd');
228
}, 30000); // Hide after 30 seconds
229
}
230
}
231
}
232
233
const adManager = new AdManager();
234
235
// Show ads at appropriate moments
236
document.getElementById('show-interstitial')?.addEventListener('click', async () => {
237
await adManager.showInterstitialAd();
238
});
239
240
document.getElementById('get-reward')?.addEventListener('click', async () => {
241
const success = await adManager.showRewardedAd();
242
if (success) {
243
console.log('User will receive reward after ad completion');
244
}
245
});
246
```
247
248
### Conversion Tracking Framework
249
250
```typescript
251
class ConversionTracker {
252
private pixelCode: string;
253
254
constructor(pixelCode: string) {
255
this.pixelCode = pixelCode;
256
}
257
258
async trackEvent(event: string, value: number = 0, customParams?: Record<string, any>): Promise<void> {
259
try {
260
// Track conversion
261
await bridge.send('VKWebAppConversionHit', {
262
pixel_code: this.pixelCode,
263
conversion_event: event,
264
conversion_value: value
265
});
266
267
// Track retargeting with custom parameters
268
if (customParams) {
269
await bridge.send('VKWebAppRetargetingPixel', {
270
pixel_code: this.pixelCode,
271
custom_params: customParams
272
});
273
}
274
275
console.log(`Tracked ${event} with value ${value}`);
276
} catch (error) {
277
console.error('Failed to track conversion:', error);
278
}
279
}
280
281
async trackPurchase(amount: number, productId: string): Promise<void> {
282
await this.trackEvent('purchase', amount, {
283
product_id: productId,
284
timestamp: Date.now()
285
});
286
}
287
288
async trackRegistration(userId: string): Promise<void> {
289
await this.trackEvent('registration', 0, {
290
user_id: userId,
291
timestamp: Date.now()
292
});
293
}
294
295
async trackLevelComplete(level: number): Promise<void> {
296
await this.trackEvent('level_complete', level, {
297
level: level,
298
timestamp: Date.now()
299
});
300
}
301
}
302
303
// Usage
304
const tracker = new ConversionTracker('your-pixel-code');
305
306
// Track different events
307
await tracker.trackPurchase(100, 'premium_month');
308
await tracker.trackRegistration('user123');
309
await tracker.trackLevelComplete(5);
310
```
311
312
### Hybrid Monetization
313
314
```typescript
315
// Combine ads and payments for optimal revenue
316
class MonetizationManager {
317
private paymentManager: PaymentManager;
318
private adManager: AdManager;
319
private tracker: ConversionTracker;
320
321
constructor() {
322
this.paymentManager = new PaymentManager(51665960, 12345);
323
this.adManager = new AdManager();
324
this.tracker = new ConversionTracker('pixel-code');
325
}
326
327
async unlockPremiumContent(contentId: string): Promise<boolean> {
328
// Offer choice: pay or watch ads
329
const choice = await this.showMonetizationChoice();
330
331
if (choice === 'payment') {
332
const success = await this.paymentManager.purchaseProduct({
333
id: contentId,
334
name: 'Premium Content',
335
description: 'Unlock premium content',
336
price: 5000, // 50 rubles
337
category: 'consumable'
338
}, getCurrentUserId());
339
340
if (success) {
341
await this.tracker.trackPurchase(5000, contentId);
342
return true;
343
}
344
} else if (choice === 'ads') {
345
const adSuccess = await this.adManager.showRewardedAd();
346
347
if (adSuccess) {
348
// Wait for ad completion
349
return new Promise((resolve) => {
350
bridge.subscribe((event) => {
351
if (event.detail.type === 'VKWebAppShowNativeAdsResult') {
352
this.tracker.trackEvent('ad_reward', 0, { content_id: contentId });
353
resolve(true);
354
}
355
});
356
});
357
}
358
}
359
360
return false;
361
}
362
363
private async showMonetizationChoice(): Promise<'payment' | 'ads' | 'cancel'> {
364
// Show UI choice to user
365
return new Promise((resolve) => {
366
const modal = document.createElement('div');
367
modal.innerHTML = `
368
<div class="monetization-modal">
369
<h3>Unlock Premium Content</h3>
370
<button id="pay-button">Pay 50₽</button>
371
<button id="ads-button">Watch Ad</button>
372
<button id="cancel-button">Cancel</button>
373
</div>
374
`;
375
376
document.body.appendChild(modal);
377
378
modal.querySelector('#pay-button')?.addEventListener('click', () => {
379
document.body.removeChild(modal);
380
resolve('payment');
381
});
382
383
modal.querySelector('#ads-button')?.addEventListener('click', () => {
384
document.body.removeChild(modal);
385
resolve('ads');
386
});
387
388
modal.querySelector('#cancel-button')?.addEventListener('click', () => {
389
document.body.removeChild(modal);
390
resolve('cancel');
391
});
392
});
393
}
394
}
395
```