@smartico/public-api 0.0.380 → 0.0.382

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/CLAUDE.md +103 -0
  2. package/README.md +32 -10
  3. package/dist/Base/ClassId.d.ts +2 -0
  4. package/dist/Jackpots/JackpotDetails.d.ts +14 -15
  5. package/dist/Jackpots/JackpotPot.d.ts +10 -6
  6. package/dist/MiniGames/SAWGameType.d.ts +3 -1
  7. package/dist/MiniGames/SAWTemplateUI.d.ts +7 -0
  8. package/dist/Raffle/GetRaffleWonPrizesRequest.d.ts +9 -0
  9. package/dist/Raffle/GetRaffleWonPrizesResponse.d.ts +52 -0
  10. package/dist/Raffle/index.d.ts +2 -0
  11. package/dist/SmarticoAPI.d.ts +6 -1
  12. package/dist/SmarticoLib/index.d.ts +5 -1
  13. package/dist/WSAPI/WSAPIAvatars.d.ts +267 -49
  14. package/dist/WSAPI/WSAPIBonuses.d.ts +224 -10
  15. package/dist/WSAPI/WSAPIGamePick.d.ts +538 -253
  16. package/dist/WSAPI/WSAPIGeneral.d.ts +156 -14
  17. package/dist/WSAPI/WSAPIInbox.d.ts +547 -58
  18. package/dist/WSAPI/WSAPIJackpots.d.ts +292 -57
  19. package/dist/WSAPI/WSAPILeaderBoard.d.ts +127 -13
  20. package/dist/WSAPI/WSAPIMiniGames.d.ts +465 -49
  21. package/dist/WSAPI/WSAPIRaffles.d.ts +576 -52
  22. package/dist/WSAPI/WSAPITournaments.d.ts +3 -3
  23. package/dist/WSAPI/WSAPITypes.d.ts +243 -132
  24. package/dist/WSAPI/WSAPIUser.d.ts +193 -43
  25. package/dist/index.js +3412 -616
  26. package/dist/index.js.map +1 -1
  27. package/dist/index.modern.mjs +3395 -609
  28. package/dist/index.modern.mjs.map +1 -1
  29. package/docs/Callbacks.md +162 -0
  30. package/docs/SmarticoObject.md +445 -0
  31. package/docs/Transforms.md +99 -0
  32. package/docs/api/README.md +26 -0
  33. package/docs/api/classes/WSAPIAvatars.md +282 -54
  34. package/docs/api/classes/WSAPIBonuses.md +233 -12
  35. package/docs/api/classes/WSAPIClans.md +380 -10
  36. package/docs/api/classes/WSAPIGamePick.md +555 -26
  37. package/docs/api/classes/WSAPIGeneral.md +165 -16
  38. package/docs/api/classes/WSAPIInbox.md +588 -64
  39. package/docs/api/classes/WSAPIJackpots.md +320 -66
  40. package/docs/api/classes/WSAPILeaderBoard.md +133 -15
  41. package/docs/api/classes/WSAPIMiniGames.md +501 -64
  42. package/docs/api/classes/WSAPIMissions.md +58 -79
  43. package/docs/api/classes/WSAPIRaffles.md +647 -69
  44. package/docs/api/classes/WSAPIStore.md +83 -108
  45. package/docs/api/classes/WSAPITournaments.md +495 -28
  46. package/docs/api/classes/WSAPIUser.md +520 -83
  47. package/docs/api/documents/Callbacks.md +162 -0
  48. package/docs/api/documents/SmarticoObject.md +445 -0
  49. package/docs/api/documents/Transforms.md +99 -0
  50. package/docs/api/enumerations/BonusStatus-1.md +11 -6
  51. package/docs/api/enumerations/JoinClanErrorCode.md +81 -0
  52. package/docs/api/enumerations/TournamentRegistrationError.md +12 -0
  53. package/docs/api/functions/clanTournamentPlayersTransform.md +13 -0
  54. package/docs/api/interfaces/AvatarCustomized.md +25 -0
  55. package/docs/api/interfaces/AvatarDefinition.md +94 -0
  56. package/docs/api/interfaces/AvatarPrompt.md +45 -0
  57. package/docs/api/interfaces/BonusMetaMap-1.md +4 -1
  58. package/docs/api/interfaces/BonusTemplateMetaMap-1.md +9 -4
  59. package/docs/api/interfaces/Clan.md +4 -0
  60. package/docs/api/interfaces/ClanInfo.md +109 -0
  61. package/docs/api/interfaces/ClanMember.md +53 -0
  62. package/docs/api/interfaces/ClanTournamentPlayerRaw.md +67 -0
  63. package/docs/api/interfaces/GemsDiamondsLog.md +43 -0
  64. package/docs/api/interfaces/GetClanInfoResponse.md +61 -0
  65. package/docs/api/interfaces/GetClanTournamentPlayersResponse.md +81 -0
  66. package/docs/api/interfaces/GetRaffleWonPrizesRequest.md +59 -0
  67. package/docs/api/interfaces/GetRaffleWonPrizesResponse.md +95 -0
  68. package/docs/api/interfaces/InboxMarkMessageAction.md +10 -2
  69. package/docs/api/interfaces/JackpotDetails.md +14 -15
  70. package/docs/api/interfaces/JackpotPot.md +9 -6
  71. package/docs/api/interfaces/LeaderBoardDetailsT.md +14 -8
  72. package/docs/api/interfaces/LeaderBoardUserT.md +8 -5
  73. package/docs/api/interfaces/LeaderBoardsRewardsT.md +7 -0
  74. package/docs/api/interfaces/PointsLog.md +43 -0
  75. package/docs/api/interfaces/RaffleWonPrize.md +59 -0
  76. package/docs/api/interfaces/RaffleWonPrizePublicMeta.md +27 -0
  77. package/docs/api/interfaces/RaffleWonPrizeUser.md +43 -0
  78. package/docs/api/interfaces/TAchCategory.md +2 -7
  79. package/docs/api/interfaces/TAvatarCustomized.md +4 -4
  80. package/docs/api/interfaces/TAvatarDefinition.md +13 -14
  81. package/docs/api/interfaces/TAvatarPrompt.md +6 -6
  82. package/docs/api/interfaces/TBonus.md +16 -8
  83. package/docs/api/interfaces/TBuyStoreItemResult.md +4 -29
  84. package/docs/api/interfaces/TClaimBonusResult.md +5 -5
  85. package/docs/api/interfaces/TClan.md +8 -4
  86. package/docs/api/interfaces/TClanInfo.md +47 -0
  87. package/docs/api/interfaces/TClanJoinResult.md +11 -1
  88. package/docs/api/interfaces/TClanTournamentPlayer.md +55 -0
  89. package/docs/api/interfaces/TClanTournamentPlayersResult.md +27 -0
  90. package/docs/api/interfaces/TClans.md +3 -1
  91. package/docs/api/interfaces/TGetTranslations.md +4 -0
  92. package/docs/api/interfaces/TInboxMessage.md +14 -6
  93. package/docs/api/interfaces/TInboxMessageBody.md +18 -12
  94. package/docs/api/interfaces/TLevel.md +17 -20
  95. package/docs/api/interfaces/TLevelCurrent.md +19 -18
  96. package/docs/api/interfaces/TMiniGamePlayBatchResult.md +14 -6
  97. package/docs/api/interfaces/TMiniGamePlayResult.md +9 -4
  98. package/docs/api/interfaces/TMissionClaimRewardResult.md +1 -9
  99. package/docs/api/interfaces/TMissionOptInResult.md +1 -5
  100. package/docs/api/interfaces/TMissionOrBadge.md +4 -7
  101. package/docs/api/interfaces/TRaffleOptinResponse.md +4 -2
  102. package/docs/api/interfaces/TSegmentCheckResult.md +10 -0
  103. package/docs/api/interfaces/TSetAvatarResult.md +3 -3
  104. package/docs/api/interfaces/TStoreItem.md +3 -13
  105. package/docs/api/interfaces/TTournament.md +1 -1
  106. package/docs/api/interfaces/TTournamentDetailed.md +1 -1
  107. package/docs/api/interfaces/TTournamentRegistrationResult.md +4 -2
  108. package/docs/api/interfaces/TUICustomSection.md +23 -19
  109. package/docs/api/interfaces/TUserProfile.md +18 -16
  110. package/docs/api/interfaces/TransformedRaffleClaimPrizeResponse.md +6 -2
  111. package/docs/api/interfaces/UserLevelExtraCountersT.md +9 -2
  112. package/docs/api/type-aliases/ActivityLogEntry.md +3 -0
  113. package/docs/native/ADDING_METHODS.md +7 -2
  114. package/docs/native/PROTOCOL.md +337 -0
  115. package/docs/ui/avatars/UIGuide_getAvatarPrompts.md +100 -0
  116. package/docs/ui/avatars/UIGuide_getAvatarsCustomized.md +90 -0
  117. package/docs/ui/avatars/UIGuide_getAvatarsList.md +105 -0
  118. package/docs/ui/avatars/UIGuide_setAvatar.md +118 -0
  119. package/docs/ui/bonuses/UIGuide_claimBonus.md +144 -0
  120. package/docs/ui/bonuses/UIGuide_getBonuses.md +176 -0
  121. package/docs/ui/gamepick/UIGuide_gamePickGetActiveRound.md +99 -0
  122. package/docs/ui/gamepick/UIGuide_gamePickGetActiveRounds.md +76 -0
  123. package/docs/ui/gamepick/UIGuide_gamePickGetBoard.md +81 -0
  124. package/docs/ui/gamepick/UIGuide_gamePickGetGameInfo.md +78 -0
  125. package/docs/ui/gamepick/UIGuide_gamePickGetHistory.md +55 -0
  126. package/docs/ui/gamepick/UIGuide_gamePickGetRoundInfoForUser.md +71 -0
  127. package/docs/ui/gamepick/UIGuide_gamePickGetUserInfo.md +64 -0
  128. package/docs/ui/gamepick/UIGuide_gamePickSubmitSelection.md +103 -0
  129. package/docs/ui/gamepick/UIGuide_gamePickSubmitSelectionQuiz.md +67 -0
  130. package/docs/ui/general/UIGuide_getCustomSections.md +137 -0
  131. package/docs/ui/general/UIGuide_getRelatedItemsForGame.md +140 -0
  132. package/docs/ui/inbox/UIGuide_deleteInboxMessage.md +135 -0
  133. package/docs/ui/inbox/UIGuide_getInboxMessageBody.md +133 -0
  134. package/docs/ui/inbox/UIGuide_getInboxMessages.md +186 -0
  135. package/docs/ui/inbox/UIGuide_markInboxMessageAsRead.md +122 -0
  136. package/docs/ui/inbox/UIGuide_markUnmarkInboxMessageAsFavorite.md +84 -0
  137. package/docs/ui/jackpots/UIGuide_getJackpotEligibleGames.md +73 -0
  138. package/docs/ui/jackpots/UIGuide_getJackpotWinners.md +83 -0
  139. package/docs/ui/jackpots/UIGuide_jackpotGet.md +138 -0
  140. package/docs/ui/jackpots/UIGuide_jackpotOptIn.md +85 -0
  141. package/docs/ui/jackpots/UIGuide_jackpotOptOut.md +65 -0
  142. package/docs/ui/leaderboard/UIGuide_getLeaderBoard.md +166 -0
  143. package/docs/ui/minigames/UIGuide_getMiniGames.md +153 -0
  144. package/docs/ui/minigames/UIGuide_getMiniGamesHistory.md +90 -0
  145. package/docs/ui/minigames/UIGuide_playMiniGame.md +150 -0
  146. package/docs/ui/minigames/UIGuide_playMiniGameBatch.md +128 -0
  147. package/docs/ui/raffles/UIGuide_claimRafflePrize.md +99 -0
  148. package/docs/ui/raffles/UIGuide_getRaffleDrawRun.md +117 -0
  149. package/docs/ui/raffles/UIGuide_getRaffleDrawRunsHistory.md +92 -0
  150. package/docs/ui/raffles/UIGuide_getRaffleWonPrizes.md +120 -0
  151. package/docs/ui/raffles/UIGuide_getRaffles.md +175 -0
  152. package/docs/ui/raffles/UIGuide_requestRaffleOptin.md +114 -0
  153. package/docs/ui/user/UIGuide_getActivityLog.md +130 -0
  154. package/docs/ui/user/UIGuide_getLevels.md +47 -42
  155. package/package.json +1 -1
  156. package/src/Base/ClassId.ts +2 -0
  157. package/src/Jackpots/JackpotDetails.ts +14 -15
  158. package/src/Jackpots/JackpotPot.ts +10 -6
  159. package/src/MiniGames/SAWGameType.ts +3 -0
  160. package/src/MiniGames/SAWTemplateUI.ts +10 -0
  161. package/src/Raffle/GetRaffleWonPrizesRequest.ts +12 -0
  162. package/src/Raffle/GetRaffleWonPrizesResponse.ts +56 -0
  163. package/src/Raffle/index.ts +3 -1
  164. package/src/SmarticoAPI.ts +14 -1
  165. package/src/SmarticoLib/index.ts +4 -0
  166. package/src/WSAPI/WSAPIAvatars.ts +267 -49
  167. package/src/WSAPI/WSAPIBonuses.ts +224 -10
  168. package/src/WSAPI/WSAPIGamePick.ts +538 -253
  169. package/src/WSAPI/WSAPIGeneral.ts +156 -14
  170. package/src/WSAPI/WSAPIInbox.ts +545 -56
  171. package/src/WSAPI/WSAPIJackpots.ts +297 -61
  172. package/src/WSAPI/WSAPILeaderBoard.ts +127 -13
  173. package/src/WSAPI/WSAPIMiniGames.ts +465 -49
  174. package/src/WSAPI/WSAPIRaffles.ts +592 -64
  175. package/src/WSAPI/WSAPITournaments.ts +3 -3
  176. package/src/WSAPI/WSAPITypes.ts +243 -132
  177. package/src/WSAPI/WSAPIUser.ts +193 -43
  178. package/tsconfig.json +9 -1
@@ -3,39 +3,160 @@
3
3
 
4
4
  ### getBonuses()
5
5
 
6
- > **getBonuses**(`__namedParameters?`): `Promise`\<[`TBonus`](../interfaces/TBonus.md)[]\>
6
+ > **getBonuses**(`params?`): `Promise`\<[`TBonus`](../interfaces/TBonus.md)[]\>
7
7
 
8
- Returns all the bonuses for the current user
9
- The returned bonuses are cached for 30 seconds. But you can pass the onUpdate callback as a parameter.
10
- Note that each time you call getBonuses with a new onUpdate callback, the old one will be overwritten by the new one.
11
- The onUpdate callback will be called on bonus claimed and the updated bonuses will be passed to it.
8
+ Returns the bonuses awarded to the current user — both pending
9
+ (player-claim required) and already-redeemed. Each bonus carries
10
+ a `bonus_status_id` ([BonusStatus](../enumerations/BonusStatus.md)) describing its lifecycle
11
+ stage and an `is_redeemable` flag that signals whether the
12
+ consumer must trigger a manual [claimBonus](#claimbonus) call.
12
13
 
13
- **Visitor mode: not supported**
14
+ Bonuses originate from many sources (CRM rules, mission/tournament
15
+ rewards, store redemptions, mini-game prizes, manual operator
16
+ awards) and all surface through this single list. The consumer
17
+ cannot distinguish the source server-side without operator
18
+ coordination.
14
19
 
15
20
  #### Parameters
16
21
 
17
- ##### \_\_namedParameters?
22
+ ##### params?
23
+
24
+ Optional. Omit to fetch without subscribing.
18
25
 
19
26
  ###### onUpdate?
20
27
 
21
28
  (`data`) => `void`
22
29
 
30
+ Callback invoked with the full refreshed
31
+ bonuses list after every
32
+ [claimBonus](#claimbonus) resolves. Each call
33
+ to `getBonuses` overwrites the prior
34
+ callback.
35
+
23
36
  #### Returns
24
37
 
25
38
  `Promise`\<[`TBonus`](../interfaces/TBonus.md)[]\>
26
39
 
40
+ Promise resolving to the bonuses list.
41
+ Empty array if no bonuses are visible.
42
+
43
+ #### Remarks
44
+
45
+ **Subscription model (`onUpdate`)**
46
+ The callback receives the FULL refreshed bonuses list (never a
47
+ diff/patch). Each subsequent call to `getBonuses({ onUpdate })`
48
+ REPLACES the prior callback. Pass `onUpdate: undefined` (or omit
49
+ it) to keep the prior callback in place; the callback is never
50
+ auto-cleared.
51
+
52
+ **Update triggers** — the callback fires after every
53
+ [claimBonus](#claimbonus) call resolves on this connection (success OR
54
+ failure). This is the ONLY trigger.
55
+
56
+ Does NOT fire when: a new bonus is awarded server-side
57
+ (CRM rule, mission completion, store purchase, etc.), a bonus
58
+ expires, or an operator manually issues / cancels a bonus. Those
59
+ changes surface only on the next cache miss (after the 30 s TTL).
60
+ Re-call `getBonuses()` manually if your UI needs near-live state
61
+ for server-driven awards.
62
+
63
+ **Reading state from the returned bonus**
64
+ Drive UI bucketing from `bonus_status_id` (enum [BonusStatus](../enumerations/BonusStatus.md)):
65
+
66
+ - `COUPON_ISSUED` (2) — actionable; player must claim. Pair with
67
+ `is_redeemable === true` to gate the Claim button.
68
+ - `REDEEM_FAILED` (4) — also actionable; the previous claim
69
+ attempt failed but the bonus is still valid. Surface a retry CTA
70
+ — the default Smartico UI treats this identically to
71
+ `COUPON_ISSUED` from the player's perspective.
72
+ - `REDEEMED` (3) — historical; show in a "claimed" tab.
73
+ - `New` (1), `COUPON_ISSUE_FAILED` (5), `EXPIRED` (6) — these
74
+ should not normally reach the client and are typically filtered
75
+ out by operator-side widget configuration; if they do appear,
76
+ they have no player-actionable state.
77
+
78
+ `is_redeemable` is the authoritative gate for showing the Claim
79
+ button — it's `true` only when the bonus is in a claimable status
80
+ AND the operator's integration uses a coupon model (where the
81
+ player must explicitly trigger delivery). Auto-redeemed bonuses
82
+ arrive already in `REDEEMED` state with `is_redeemable: false`.
83
+
84
+ **Field hierarchy — display amount**
85
+ Bonuses carry both template-level (`label_bonus_template_meta_map.description`)
86
+ and instance-level (`bonus_meta_map.uiAmount`) display strings.
87
+ Prefer `bonus_meta_map.uiAmount` when present — it's the dynamic
88
+ amount computed at issuance time (e.g. from a dynamic-bonus
89
+ formula). Fall back to `label_bonus_template_meta_map.description`
90
+ (which can include HTML; sanitize before injecting).
91
+
92
+ **Date format**
93
+ `create_date` and `redeem_date` are ISO 8601 UTC strings WITHOUT
94
+ a timezone suffix (`"YYYY-MM-DDTHH:MM:SS"`). Parse as UTC and
95
+ display in the user's local timezone. `redeem_date` is absent
96
+ until the bonus reaches `REDEEMED` status.
97
+
98
+ **Cache TTL**: the SDK caches the response for 30 seconds. Cache
99
+ is fully cleared on login / logout.
100
+
101
+ **Idempotency / Side effects**: safe. Read-only.
102
+
103
+ **UI guidance**: see [UI Guide — `getBonuses`](../_media/UIGuide_getBonuses.md).
104
+
105
+ **Visitor mode**: not supported.
106
+
107
+ #### Example
108
+
109
+ ```ts
110
+ const bonuses = await window._smartico.api.getBonuses({
111
+ onUpdate: (refreshed) => {
112
+ console.log('[smartico] bonuses refreshed (after claimBonus) — re-render the bonuses UI from this array:', refreshed);
113
+ },
114
+ });
115
+
116
+ // Bucket into pending vs redeemed tabs. The default Smartico UI groups
117
+ // COUPON_ISSUED + REDEEM_FAILED into the same "Pending" tab.
118
+ const pending = bonuses.filter(b =>
119
+ b.bonus_status_id === 2 || b.bonus_status_id === 4 // COUPON_ISSUED or REDEEM_FAILED
120
+ );
121
+ const redeemed = bonuses.filter(b => b.bonus_status_id === 3); // REDEEMED
122
+
123
+ console.log('[smartico] render bonus tabs: pending=', pending.length, 'redeemed=', redeemed.length);
124
+
125
+ // Render each pending bonus card; show Claim button only when redeemable.
126
+ for (const b of pending) {
127
+ const amount = b.bonus_meta_map?.uiAmount || b.label_bonus_template_meta_map?.description;
128
+ if (b.is_redeemable) {
129
+ console.log('[smartico] render Claim button for bonus', b.bonus_id, '— amount:', amount);
130
+ } else {
131
+ console.log('[smartico] render bonus as informational (no Claim button) — amount:', amount);
132
+ }
133
+ }
134
+
135
+ // Server-awarded bonuses (e.g. from a CRM campaign) do NOT push;
136
+ // poll if you need near-live awareness.
137
+ setInterval(async () => {
138
+ const fresh = await window._smartico.api.getBonuses();
139
+ const newCount = fresh.filter(b => b.bonus_status_id === 2 || b.bonus_status_id === 4).length;
140
+ console.log('[smartico] poll tick — pending bonuses now:', newCount);
141
+ }, 30_000);
142
+ ```
143
+
27
144
  ***
28
145
 
29
146
  ### claimBonus()
30
147
 
31
148
  > **claimBonus**(`bonus_id`): `Promise`\<[`TClaimBonusResult`](../interfaces/TClaimBonusResult.md)\>
32
149
 
33
- Claim the bonus by bonus_id. Returns the err_code in case of success or error.
34
- Note that this method can be used only on integrations where originally failed bonus can be claimed again.
35
- For example, user won a bonus in the mini-game, but Operator rejected this bonus.
36
- This bonus will be available for the user to claim again.
150
+ Triggers manual redemption of a coupon-model bonus the user has
151
+ been awarded. For bonuses with `is_redeemable === true` returned
152
+ by [getBonuses](#getbonuses), this is the call that asks the operator's
153
+ integration to actually credit the bonus to the player's account.
154
+ Bonuses on integrations that auto-redeem arrive already in
155
+ `REDEEMED` state and do not require this call.
37
156
 
38
- **Visitor mode: not supported**
157
+ Use this for `bonus_status_id` of `COUPON_ISSUED` (2) as the
158
+ first-time claim, and for `REDEEM_FAILED` (4) as a retry after a
159
+ prior unsuccessful attempt.
39
160
 
40
161
  #### Parameters
41
162
 
@@ -43,8 +164,108 @@ This bonus will be available for the user to claim again.
43
164
 
44
165
  `number`
45
166
 
167
+ The `bonus_id` from a `TBonus` returned by
168
+ [getBonuses](#getbonuses).
169
+
46
170
  #### Returns
47
171
 
48
172
  `Promise`\<[`TClaimBonusResult`](../interfaces/TClaimBonusResult.md)\>
49
173
 
174
+ `{ err_code, err_message, success? }`; success when
175
+ `err_code === 0` (or `err_code === -1` when treated as
176
+ idempotent no-op). The `success` field is unreliable —
177
+ ignore it.
178
+
179
+ #### Remarks
180
+
181
+ **Preconditions**
182
+ Read the candidate bonus from [getBonuses](#getbonuses) and gate the
183
+ call on `is_redeemable === true`. The SDK forwards the request
184
+ unconditionally — calling on a non-claimable bonus returns
185
+ `err_code = -1`.
186
+
187
+ **Error codes** (in `err_code`)
188
+
189
+ The SDK currently types `err_code` as [SAWSpinErrorCode](../enumerations/SAWSpinErrorCode.md) for
190
+ historical reasons, but the values returned by this method come
191
+ from the server's general error space and are NOT mini-game codes.
192
+ Branch on the numeric values:
193
+
194
+ - `0` — success; the bonus has been redeemed and the operator's
195
+ integration has credited the player's account.
196
+ - `-1` — bonus not claimable: not found, already claimed by
197
+ another session, or its status is no longer `COUPON_ISSUED` /
198
+ `REDEEM_FAILED`. Treat as idempotent — refresh
199
+ [getBonuses](#getbonuses) and reconcile.
200
+ - `1` — generic server error. Transient; allow retry after a brief
201
+ delay.
202
+ - `9999` — uncaught server exception. Treat as a transient failure;
203
+ surface a generic error and allow retry.
204
+ - other non-zero — generic server error. Surface `err_message` if
205
+ any.
206
+
207
+ **`success` field is unreliable**: the wire response does not
208
+ carry a `success` boolean — the field on `TClaimBonusResult` will
209
+ be `undefined` in practice. Always branch on `err_code === 0`
210
+ for the success check.
211
+
212
+ **Refresh after success (and after failure)**
213
+ The SDK automatically refreshes the bonuses cache on every
214
+ response (success OR failure) and fires any `onUpdate` callback
215
+ registered via [getBonuses](#getbonuses)'s `onUpdate`. After
216
+ `err_code === 0`, the redeemed bonus shifts from
217
+ `COUPON_ISSUED` / `REDEEM_FAILED` to `REDEEMED` on the refreshed
218
+ array, with `redeem_date` populated. After a failure, the bonus
219
+ typically lands in `REDEEM_FAILED` and remains claimable for a
220
+ retry.
221
+
222
+ **Idempotency**: NOT idempotent at the SDK level. A second call
223
+ returns `err_code = -1` once the first has succeeded — treat that
224
+ as success in the UI rather than as a real error. Guard the call
225
+ site against double-clicks (set a local "claiming" flag on click,
226
+ clear it on response).
227
+
228
+ **Side effects** (on `err_code === 0`)
229
+ - Bonus status transitions to `REDEEMED`; `redeem_date` is set.
230
+ - The operator's integration credits the player's account
231
+ externally. The SDK does not observe that credit directly —
232
+ balance updates flow over the user-properties channel from the
233
+ operator's side, not from this response.
234
+ - Server-side analytics events fire downstream (not directly
235
+ observable from the SDK).
236
+
237
+ **UI guidance**: see [UI Guide — `claimBonus`](../_media/UIGuide_claimBonus.md).
238
+
239
+ **Visitor mode**: not supported.
240
+
241
+ #### Example
242
+
243
+ ```ts
244
+ const bonuses = await window._smartico.api.getBonuses({
245
+ onUpdate: (refreshed) => console.log('[smartico] bonuses refreshed — re-render from this array', refreshed),
246
+ });
247
+ const bonus = bonuses.find(b => b.bonus_id === bonusId);
248
+
249
+ if (!bonus) {
250
+ console.log('[smartico] bonus no longer visible — refresh list and hide CTA');
251
+ return;
252
+ }
253
+ if (!bonus.is_redeemable) {
254
+ console.log('[smartico] bonus is not claimable (auto-redeemed or already finalised) — keep CTA hidden');
255
+ return;
256
+ }
257
+
258
+ console.log('[smartico] claim starting — set in-flight flag, show loading dots on the Claim button, keep the modal open');
259
+ const r = await window._smartico.api.claimBonus(bonus.bonus_id);
260
+ console.log('[smartico] claim response received — clear in-flight flag');
261
+
262
+ if (r.err_code === 0 || r.err_code === -1) {
263
+ console.log('[smartico] claim succeeded (or was already done) — show a success toast; the getBonuses onUpdate above will fire with the refreshed list');
264
+ } else if (r.err_code === 9999) {
265
+ console.error('[smartico] uncaught server exception — show a generic error toast and allow retry');
266
+ } else {
267
+ console.error('[smartico] claim failed — surface this error message to the user; the bonus will move to REDEEM_FAILED state and remain claimable for a retry:', r.err_message);
268
+ }
269
+ ```
270
+
50
271
  ***